diff --git a/apps/lspci.c b/apps/lspci.c index 8b3bfa6e..a3f20928 100644 --- a/apps/lspci.c +++ b/apps/lspci.c @@ -99,6 +99,7 @@ struct { {0x8086, 0x1237, "PCI & Memory"}, {0x8086, 0x2415, "82801AA AC'97 Audio Controller"}, {0x8086, 0x2448, "82801 Mobile PCI Bridge"}, + {0x8086, 0x2668, "ICH6 HD Audio Controller"}, {0x8086, 0x29c0, "DRAM Controller"}, {0x8086, 0x2918, "ICH9 LPC Interface Controller"}, {0x8086, 0x2922, "ICH9 6-port SATA Controller"}, diff --git a/modules/hda.c b/modules/hda.c new file mode 100644 index 00000000..0ff8e404 --- /dev/null +++ b/modules/hda.c @@ -0,0 +1,116 @@ +/** + * @file kernel/audio/hda.c + * @brief Driver for the Intel High Definition Audio. + * + * @copyright + * This file is part of ToaruOS and is released under the terms + * of the NCSA / University of Illinois License - see LICENSE.md + * Copyright (C) 2021 K. Lange + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if 0 +static snd_knob_t _knobs[] = { + { + "Master", + SND_KNOB_MASTER + } +}; + +static int hda_mixer_read(uint32_t knob_id, uint32_t *val); +static int hda_mixer_write(uint32_t knob_id, uint32_t val); + +/** + * TODO: We should generate this dynamically + * for each card based on the ports we find. + */ +static snd_device_t _snd = { + .name = "Intel HDA", + .device = NULL, + .playback_speed = 48000, + .playback_format = SND_FORMAT_L16SLE, + + .knobs = _knobs, + .num_knobs = 1, + + .mixer_read = hda_mixer_read, + .mixer_write = hda_mixer_write, +}; + +static int hda_mixer_read(uint32_t knob_id, uint32_t *val) { + return 0; +} + +static int hda_mixer_write(uint32_t knob_id, uint32_t val) { + return 0; +} +#endif + +static void hda_setup(uint32_t device) { + /* Map MMIO */ + uintptr_t mmio_addr = pci_read_field(device, PCI_BAR0, 4) & 0xFFFFFFFE; + void* mapped_mmio = mmu_map_mmio_region(mmio_addr, 0x1000 * 8); /* TODO size? */ + + /* Enable bus mastering, MMIO */ + pci_write_field(device, PCI_COMMAND, 2, 0x6); + + /* Enable controller */ + ((volatile uint32_t*)mapped_mmio)[2] |= 1; + while (!(((volatile uint32_t*)mapped_mmio)[2]) & 0x1); + + printf("hda: codec bitmap: %04x\n", + ((volatile uint16_t*)mapped_mmio)[7]); + + /* Stop DMA engine */ + + /* Configure DMA engine */ + + /* Map space for DMA */ + + /* Set up ring buffer pointers */ + + /* Then do the same for the DMA response ring buffer... ? */ +} + +static void find_hda(uint32_t device, uint16_t vendorid, uint16_t deviceid, void * extra) { + if (vendorid == 0x8086 && deviceid == 0x2668) { + hda_setup(device); + } +} + +static int hda_install(int argc, char * argv[]) { + pci_scan(&find_hda, -1, NULL); + return 0; +} + +static int fini(void) { + #if 0 + snd_unregister(&_snd); + + free(_device.bdl); + for (int i = 0; i < AC97_BDL_LEN; i++) { + free(_device.bufs[i]); + } + #endif + return 0; +} + +struct Module metadata = { + .name = "hda", + .init = hda_install, + .fini = fini, +}; +