static int ac97_read2 (void *devc_, int index) { fm801_devc *devc = devc_; int idx; oss_native_word flags; MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags); /* * Wait until the codec interface is not ready.. */ for (idx = 0; idx < 10000; idx++) { if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))) break; oss_udelay (10); } if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)) { DDB (cmn_err (CE_WARN, "Secondary AC97 (read) not ready (1)\n")); MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); return 0; } /* read command */ OUTW (devc->osdev, index | (0x1 << 10) | (1 << 7), devc->base + AC97_CMD); for (idx = 0; idx < 10000; idx++) { if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))) break; oss_udelay (10); } /* * Wait until the codec interface is not ready.. */ if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)) { DDB (cmn_err (CE_WARN, "Secondary AC97 (read) not ready(2)\n")); MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); return 0; } for (idx = 0; idx < 10000; idx++) { if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 8)) break; oss_udelay (10); } if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 8))) { cmn_err (CE_WARN, "Secondary AC97 (read) data not valid (2)\n"); MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); return 0; } MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); return INW (devc->osdev, devc->base + AC97_DATA); }
static int detect_mad16(void) { unsigned char tmp, tmp2, bit; int i, port; /* * Check that reading a register doesn't return bus float (0xff) * when the card is accessed using password. This may fail in case * the card is in low power mode. Normally at least the power saving * mode bit should be 0. */ if ((tmp = mad_read(MC1_PORT)) == 0xff) { DDB(printk("MC1_PORT returned 0xff\n")); return 0; } for (i = 0xf8d; i <= 0xf98; i++) if (!c924pnp) DDB(printk("Port %0x (init value) = %0x\n", i, mad_read(i))) else DDB(printk("Port %0x (init value) = %0x\n", i-0x80, mad_read(i))); if (board_type == C930) return detect_c930(); /* * Now check that the gate is closed on first I/O after writing * the password. (This is how a MAD16 compatible card works). */ if ((tmp2 = inb(MC1_PORT)) == tmp) /* It didn't close */ { DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2)); return 0; } bit = (c924pnp) ? 0x20 : 0x80; port = (c924pnp) ? MC2_PORT : MC1_PORT; tmp = mad_read(port); mad_write(port, tmp ^ bit); /* Toggle a bit */ if ((tmp2 = mad_read(port)) != (tmp ^ bit)) /* Compare the bit */ { mad_write(port, tmp); /* Restore */ DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2)); return 0; } mad_write(port, tmp); /* Restore */ return 1; /* Bingo */ }
int hdaudio_asus_m9_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group) { DDB(cmn_err(CE_CONT, "hdaudio_asus_m9_mixer_init got called.\n")); corb_write (mixer, cad, 0x1b, 0, SET_EAPD, 0); return hdaudio_generic_mixer_init(dev, mixer, cad, top_group); }
int probe_adlib(struct address_info *hw_config) { if (check_region(hw_config->io_base, 4)) { DDB(printk("opl3.c: I/O port %x already in use\n", hw_config->io_base)); return 0; } return opl3_detect(hw_config->io_base, hw_config->osp); }
static int ac97_write2 (void *devc_, int index, int data) { fm801_devc *devc = devc_; int idx; oss_native_word flags; MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags); /* * Wait until the codec interface is ready.. */ for (idx = 0; idx < 10000; idx++) { if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))) break; oss_udelay (10); } if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)) { DDB (cmn_err (CE_WARN, "Secondary AC97 busy\n")); MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); return OSS_EIO; } /* write data and address */ OUTW (devc->osdev, data, devc->base + AC97_DATA); OUTW (devc->osdev, index | (0x1 << 10), devc->base + AC97_CMD); /* * Wait until the write command is completed.. */ for (idx = 0; idx < 1000; idx++) { if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))) break; oss_udelay (10); } if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)) { DDB (cmn_err (CE_WARN, "Secondary AC97 busy (1)\n")); MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); return OSS_EIO; } MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); return 0; }
void * yamaha_usb_midi_driver (ossusb_devc * usb_devc) { ymhusb_devc *devc; int i; unsigned char *desc; int desc_len; int caps = MIDI_CAP_EXTERNAL; unsigned int devid; char *name = "Yamaha USB MIDI"; if (usb_devc->dev_name != NULL) name = usb_devc->dev_name; if ((devc = PMALLOC (usb_devc->osdev, sizeof (*devc))) == NULL) { cmn_err (CE_WARN, "Yamaha MIDI: Out of memory\n"); return NULL; } memset (devc, 0, sizeof (*devc)); devc->unload_func = ymhusb_unload; devc->osdev = usb_devc->osdev; devc->usbdev = usb_devc->last_usbdev; MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV); devid = (usb_devc->vendor << 16) | usb_devc->product; DDB (cmn_err (CE_CONT, "Attaching Yamaha MIDI device %08x (%s)\n", devid, name)); switch (devid) { case 0x0499101e: /* PSR-K1 keyboard */ caps |= MIDI_CAP_PTOP; break; } for (i = 0; i < 32; i++) if ((desc = udi_usbdev_get_endpoint (devc->usbdev, 0, i, &desc_len)) != NULL) { if (desc[2] & 0x80) { add_input_device (devc, name, desc, caps); } else { add_output_device (devc, name, desc, caps); } } return devc; }
int hdaudio_asus_a7k_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group) { DDB(cmn_err(CE_CONT, "hdaudio_asus_a7k_GPIO_init got called.\n")); corb_write (mixer, cad, 0x01, 0, SET_GPIO_ENABLE, 3); corb_write (mixer, cad, 0x01, 0, SET_GPIO_DIR, 1); corb_write (mixer, cad, 0x01, 0, SET_GPIO_DATA, 1); return hdaudio_generic_mixer_init(dev, mixer, cad, top_group); }
static int detect_ga(sscape_info * devc) { unsigned char save; DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base)); if (check_region(devc->base, 8)) return 0; /* * First check that the address register of "ODIE" is * there and that it has exactly 4 writable bits. * First 4 bits */ if ((save = inb(PORT(ODIE_ADDR))) & 0xf0) { DDB(printk("soundscape: Detect error A\n")); return 0; } outb((0x00), PORT(ODIE_ADDR)); if (inb(PORT(ODIE_ADDR)) != 0x00) { DDB(printk("soundscape: Detect error B\n")); return 0; } outb((0xff), PORT(ODIE_ADDR)); if (inb(PORT(ODIE_ADDR)) != 0x0f) { DDB(printk("soundscape: Detect error C\n")); return 0; } outb((save), PORT(ODIE_ADDR)); /* * Now verify that some indirect registers return zero on some bits. * This may break the driver with some future revisions of "ODIE" but... */ if (sscape_read(devc, 0) & 0x0c) { DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0))); return 0; } if (sscape_read(devc, 1) & 0x0f) { DDB(printk("soundscape: Detect error E\n")); return 0; } if (sscape_read(devc, 5) & 0x0f) { DDB(printk("soundscape: Detect error F\n")); return 0; } return 1; }
void HwStopDMA (allegro_devc * devc, unsigned char Direction) { if (!Direction) WaveStream = &CaptureStream; else WaveStream = &PlaybackStream; SetState (devc, *WaveStream, KSSTATE_STOP); DDB (cmn_err (CE_WARN, "Wave%s DMA stopped\n", !Direction ? "In" : "Out")); }
int hdaudio_GPIO_init_1 (int dev, hdaudio_mixer_t * mixer, int cad, int top_group) { DDB(cmn_err(CE_CONT, "hdaudio_GPIO_init_1 got called.\n")); /* Acer TravelMate 4060 and similar Aspire series, with ALC260 codec, need * that we init GPIO to get internal speaker and headphone jack working. */ corb_write(mixer, cad, 0x01, 0, SET_GPIO_ENABLE, 1); corb_write(mixer, cad, 0x01, 0, SET_GPIO_DIR, 1); corb_write(mixer, cad, 0x01, 0, SET_GPIO_DATA, 1); return hdaudio_generic_mixer_init(dev, mixer, cad, top_group); }
int sndtable_init_card(int unit, struct address_info * hw_config) { int i, n = num_sound_cards; struct card_info *ci = snd_installed_cards ; DDB(printf("sndtable_init_card(%d) entered\n", unit)); if (!unit) { sndtable_init() ; return TRUE; } for (i = 0; i < n && ci->card_type; ci++, i++) if (ci->card_type == unit) { int drv; ci->config.io_base = hw_config->io_base; ci->config.irq = hw_config->irq; ci->config.dma = hw_config->dma; ci->config.dma2 = hw_config->dma2; ci->config.name = hw_config->name; ci->config.always_detect = hw_config->always_detect; ci->config.card_subtype = hw_config->card_subtype; ci->config.osp = hw_config->osp; if ((drv = snd_find_driver(ci->card_type)) == -1) ci->enabled = 0; /* Mark not fnd */ else { DDB(printf("Located card - calling attach routine\n")); sound_drivers[drv].attach(hw_config) ; DDB(printf("attach routine finished\n")); } start_services(); return TRUE; } DDB(printf("sndtable_init_card: No card defined with type=%d, num cards: %d\n", unit, num_sound_cards)); return FALSE; }
static int wss_init(struct address_info *hw_config) { int ad_flags = 0; /* * Verify the WSS parameters */ if (check_region(hw_config->io_base, 8)) { printk(KERN_ERR "MSS: I/O port conflict\n"); return 0; } if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp)) return 0; /* * Check if the IO port returns valid signature. The original MS Sound * system returns 0x04 while some cards (AudioTrix Pro for example) * return 0x00. */ if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 && (inb(hw_config->io_base + 3) & 0x3f) != 0x00) { DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb(hw_config->io_base + 3))); return 0; } if (hw_config->irq > 11) { printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq); return 0; } if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3) { printk(KERN_ERR "MSS: Bad DMA %d\n", hw_config->dma); return 0; } /* * Check that DMA0 is not in use with a 8 bit board. */ if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80) { printk("MSS: Can't use DMA0 with a 8 bit card/slot\n"); return 0; } if (hw_config->irq > 7 && hw_config->irq != 9 && inb(hw_config->io_base + 3) & 0x80) printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq); return 1; }
static void __exit unload_gus(struct address_info *hw_config) { DDB(printk("unload_gus(%x)\n", hw_config->io_base)); gus_wave_unload(hw_config); release_region(hw_config->io_base, 16); release_region(hw_config->io_base + 0x100, 12); /* 0x10c-> is MAX */ free_irq(hw_config->irq, hw_config); sound_free_dma(hw_config->dma); if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma) sound_free_dma(hw_config->dma2); }
static int reset_uart401(uart401_devc * devc) { int ok, timeout, n; /* * Send the RESET command. Try again if no success at the first time. */ ok = 0; for (n = 0; n < 2 && !ok; n++) { for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--); devc->input_byte = 0; uart401_cmd(devc, MPU_RESET); /* * Wait at least 25 msec. This method is not accurate so let's make the * loop bit longer. Cannot sleep since this is called during boot. */ for (timeout = 50000; timeout > 0 && !ok; timeout--) { if (devc->input_byte == MPU_ACK) /* Interrupt */ ok = 1; else if (input_avail(devc)) { if (uart401_read(devc) == MPU_ACK) ok = 1; } } } if (ok) { DEB(printk("Reset UART401 OK\n")); } else DDB(printk("Reset UART401 failed - No hardware detected.\n")); if (ok) uart401_input_loop(devc); /* * Flush input before enabling interrupts */ return ok; }
int probe_trix_wss (struct address_info *hw_config) { /* * Check if the IO port returns valid signature. The original MS Sound * system returns 0x04 while some cards (AudioTriX Pro for example) * return 0x00. */ if (!trix_set_wss_port (hw_config)) return 0; if ((INB (hw_config->io_base + 3) & 0x3f) != 0x00) { DDB (printk ("No MSS signature detected on port 0x%x\n", hw_config->io_base)); return 0; } if (hw_config->irq > 11) { printk ("AudioTriX: Bad WSS IRQ %d\n", hw_config->irq); return 0; } if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3) { printk ("AudioTriX: Bad WSS DMA %d\n", hw_config->dma); return 0; } /* * Check that DMA0 is not in use with a 8 bit board. */ if (hw_config->dma == 0 && INB (hw_config->io_base + 3) & 0x80) { printk ("AudioTriX: Can't use DMA0 with a 8 bit card\n"); return 0; } if (hw_config->irq > 7 && hw_config->irq != 9 && INB (hw_config->io_base + 3) & 0x80) { printk ("AudioTriX: Can't use IRQ%d with a 8 bit card\n", hw_config->irq); return 0; } return ad1848_detect (hw_config->io_base + 4); }
int probe_uart401(struct address_info *hw_config, struct module *owner) { uart401_devc *devc; char *name = "MPU-401 (UART) MIDI"; int ok = 0; unsigned long flags; DDB(printk("Entered probe_uart401()\n")); /* Default to "not found" */ hw_config->slots[4] = -1; if (!request_region(hw_config->io_base, 4, "MPU-401 UART")) { printk(KERN_INFO "uart401: could not request_region(%d, 4)\n", hw_config->io_base); return 0; } devc = kmalloc(sizeof(uart401_devc), GFP_KERNEL); if (!devc) { printk(KERN_WARNING "uart401: Can't allocate memory\n"); goto cleanup_region; } devc->base = hw_config->io_base; devc->irq = hw_config->irq; devc->osp = hw_config->osp; devc->midi_input_intr = NULL; devc->opened = 0; devc->input_byte = 0; devc->my_dev = 0; devc->share_irq = 0; spin_lock_init(&devc->lock); spin_lock_irqsave(&devc->lock,flags); ok = reset_uart401(devc); spin_unlock_irqrestore(&devc->lock,flags); if (!ok) goto cleanup_devc; if (hw_config->name) name = hw_config->name; if (devc->irq < 0) { devc->share_irq = 1; devc->irq *= -1; } else devc->share_irq = 0; if (!devc->share_irq) if (request_irq(devc->irq, uart401intr, 0, "MPU-401 UART", devc) < 0) { printk(KERN_WARNING "uart401: Failed to allocate IRQ%d\n", devc->irq); devc->share_irq = 1; } devc->my_dev = sound_alloc_mididev(); enter_uart_mode(devc); if (devc->my_dev == -1) { printk(KERN_INFO "uart401: Too many midi devices detected\n"); goto cleanup_irq; } conf_printf(name, hw_config); midi_devs[devc->my_dev] = kmemdup(&uart401_operations, sizeof(struct midi_operations), GFP_KERNEL); if (!midi_devs[devc->my_dev]) { printk(KERN_ERR "uart401: Failed to allocate memory\n"); goto cleanup_unload_mididev; } if (owner) midi_devs[devc->my_dev]->owner = owner; midi_devs[devc->my_dev]->devc = devc; midi_devs[devc->my_dev]->converter = kmemdup(&std_midi_synth, sizeof(struct synth_operations),
void hdaudio_si3055_endpoint_init(hdaudio_mixer_t *mixer, int cad) { codec_t *codec = mixer->codecs[cad]; /* Modem codec */ widget_t *widget; /* MFG widget */ hdaudio_endpointinfo_t *endpoint; unsigned int a, b; /* Used for reading data. */ int tmout; /* Timeout counter. */ /* Output and input stream numbers. */ int playback_stream_num, recording_stream_num; DDB(cmn_err(CE_CONT, "hdaudio_si3055_endpoint_init got called.\n")); /* Reset the modem codec. */ corb_write(mixer, cad, 0x00, 0, SET_CODEC_RESET, 0); corb_write(mixer, cad, codec->afg, 0, SET_CONVERTER, IDDLE_STREAM << 4); corb_write(mixer, cad, codec->afg, 0, SET_CONVERTER_FORMAT, 0); /* Set 9600Hz as the initial line sampling rate. * It can be changed later when desired. */ SI3055_REG_SET(mixer, cad, SI3055_LINE_RATE, 9600); /* Assign the "unused" value to the playback and recording * stream descriptors (ref. HDAudio_03.pdf, page 40). */ SI3055_REG_SET(mixer, cad, SI3055_HDA_STREAMS, 0x0000); /* Write 0x0000 to the Extended Modem Status & Control register * to power up the modem (ref. si3038.pdf, page 22). */ SI3055_REG_SET(mixer, cad, SI3055_EXT_MODEM_STATUS, 0x0000); /* Wait for the modem to complete power up. The lower 8 bits * indicate that it is ready (ref. si3038.pdf, page 22). */ tmout = 10; do { SI3055_REG_GET(mixer, cad, SI3055_EXT_MODEM_STATUS, &a, &b); DDB(cmn_err(CE_CONT, "si3055: ext modem status: %04x.\n", a)); oss_udelay(1000); } while(((a & 0xf) == 0) && --tmout); if ((a & 0xf) == 0) { cmn_err(CE_WARN, "si3055: power up timeout (status: %04x).\n", a); } /* This register contains 0x1fff after reset. We need to set it * to zero to get the modem working. No corresponding register * could be found in the Si3038 datasheet. */ SI3055_REG_SET(mixer, cad, SI3055_GPIO_CONFIG, 0x0000); /* Program line interface parameters. The register value after * a reset is 0xF010. Set it to 0x0010 to unmute the analog * receive and transmit paths. */ SI3055_REG_SET(mixer, cad, SI3055_LINE_CONFIG, 0x0010); /* Setup the widget info. */ widget = &codec->widgets[codec->afg]; widget->endpoint = &codec->inendpoints[0]; widget->sizes = 0x20000; /* 16 bits */ strcpy(widget->name, "modem"); /* Setup the output endpoint. */ codec->num_outendpoints = 1; endpoint = &codec->outendpoints[0]; endpoint->ix = 0; endpoint->iddle_stream = 0; endpoint->cad = cad; endpoint->base_wid = codec->afg; endpoint->recsrc_wid = endpoint->volume_wid = -1; endpoint->nrates = 3; endpoint->rates[0] = 8000; endpoint->rates[1] = 9600; endpoint->rates[2] = 16000; endpoint->name = widget->name; endpoint->channels = 1; endpoint->is_digital = 0; endpoint->is_modem = 1; endpoint->sizemask = widget->sizes; endpoint->fmt_mask = AFMT_S16_LE; endpoint->afg = codec->afg; endpoint->min_rate = 8000; endpoint->max_rate = 16000; /* Setup the input endpoint. */ codec->num_inendpoints = 1; memcpy(&codec->inendpoints[0], endpoint, sizeof(*endpoint)); /* Choose stream numbers for output and input streams. */ playback_stream_num = ++mixer->num_outendpoints; endpoint->stream_number = endpoint->default_stream_number = playback_stream_num; endpoint = &codec->inendpoints[0]; recording_stream_num = ++mixer->num_inendpoints; endpoint->stream_number = endpoint->default_stream_number = recording_stream_num; /* Setup the stream numbers. */ SI3055_REG_SET(mixer, cad, SI3055_HDA_STREAMS, ((playback_stream_num << 4) << 8) | (recording_stream_num << 4)); }
static int detect_c930(void) { unsigned char tmp = mad_read(MC1_PORT); if ((tmp & 0x06) != 0x06) { DDB(printk("Wrong C930 signature (%x)\n", tmp)); /* return 0; */ } mad_write(MC1_PORT, 0); if (mad_read(MC1_PORT) != 0x06) { DDB(printk("Wrong C930 signature2 (%x)\n", tmp)); /* return 0; */ } mad_write(MC1_PORT, tmp); /* Restore bits */ mad_write(MC7_PORT, 0); if ((tmp = mad_read(MC7_PORT)) != 0) { DDB(printk("MC7 not writable (%x)\n", tmp)); return 0; } mad_write(MC7_PORT, 0xcb); if ((tmp = mad_read(MC7_PORT)) != 0xcb) { DDB(printk("MC7 not writable2 (%x)\n", tmp)); return 0; } tmp = mad_read(MC0_PORT+18); if (tmp == 0xff || tmp == 0x00) return 1; /* We probably have a C931 */ DDB(printk("Detected C931 config=0x%02x\n", tmp)); c931_detected = 1; /* * We cannot configure the chip if it is in PnP mode. * If we have a CSN assigned (bit 8 in MC13) we first try * a software reset, then a software power off, finally * Clearing PnP mode. The last option is not * Bit 8 in MC13 */ if ((mad_read(MC0_PORT+13) & 0x80) == 0) return 1; /* Software reset */ mad_write(MC9_PORT, 0x02); mad_write(MC9_PORT, 0x00); if ((mad_read(MC0_PORT+13) & 0x80) == 0) return 1; /* Power off, and on again */ mad_write(MC9_PORT, 0xc2); mad_write(MC9_PORT, 0xc0); if ((mad_read(MC0_PORT+13) & 0x80) == 0) return 1; #if 0 /* Force off PnP mode. This is not recommended because * the PnP bios will not recognize the chip on the next * warm boot and may assignd different resources to other * PnP/PCI cards. */ mad_write(MC0_PORT+17, 0x04); #endif return 1; }
int oss_als3xx_attach (oss_device_t * osdev) { unsigned char pci_irq_line, pci_revision; unsigned short pci_command, vendor, device; unsigned int pci_ioaddr; int err; als300_devc *devc; DDB (cmn_err (CE_WARN, "Entered ALS ALS300 probe routine\n")); pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor); pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision); pci_read_config_word (osdev, PCI_COMMAND, &pci_command); pci_read_config_word (osdev, PCI_DEVICE_ID, &device); pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line); pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr); if (vendor != ALS_VENDOR_ID || (device != ALS_300 && device != ALS_300P)) return 0; DDB (cmn_err (CE_WARN, "rev %x I/O base %04x\n", pci_revision, pci_ioaddr)); if (pci_ioaddr == 0) { cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n"); return 0; } if (pci_irq_line == 0) { cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line); return 0; } if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL) { cmn_err (CE_WARN, "Out of memory\n"); return 0; } devc->osdev = osdev; osdev->devc = devc; devc->open_mode = 0; devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr); /* Remove I/O space marker in bit 0. */ devc->base &= ~3; devc->irq = pci_irq_line; devc->mpu_base = als300_mpu_base; pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO; pci_write_config_word (osdev, PCI_COMMAND, pci_command); switch (device) { case ALS_300: devc->model = MDL_ALS300; devc->chip_name = "Avance Logic ALS300"; devc->chip_rev = pci_revision; break; case ALS_300P: devc->model = MDL_ALS300PLUS; devc->chip_name = "Avance Logic ALS300+"; devc->chip_rev = pci_revision; break; } MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV); MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1); oss_register_device (osdev, devc->chip_name); if ((err = oss_register_interrupts (devc->osdev, 0, als300intr, NULL)) < 0) { cmn_err (CE_WARN, "Can't allocate IRQ%d, err=%d\n", pci_irq_line, err); return 0; } return init_als300 (devc); /* Detected */ }
int sndtable_probe(int unit, struct address_info * hw_config) { int i, sel = -1, n = num_sound_cards; struct card_info *ci = snd_installed_cards ; DDB(printf("-- sndtable_probe(%d)\n", unit)); /* * for some reason unit 0 always succeeds ? */ if (!unit) return TRUE; sound_started = 1; for (i=0; i<n && sel== -1 && ci->card_type; ci++, i++) if ( (ci->enabled) && (ci->card_type == unit) ) { /* DDB(printf("-- found card %d\n", i) ); */ sel = i; /* and break */ } /* * not found. Creates a new entry in the table for this unit. */ if (sel == -1 && num_sound_cards < max_sound_cards) { int i; i = sel = (num_sound_cards++); DDB(printf("-- installing card %d\n", i) ); ci = &snd_installed_cards[sel] ; ci->card_type = unit; ci->enabled = 1; } /* DDB(printf("-- installed card %d\n", sel) ); */ if (sel != -1) { int drv; ci->config.io_base = hw_config->io_base; ci->config.irq = hw_config->irq; ci->config.dma = hw_config->dma; ci->config.dma2 = hw_config->dma2; ci->config.name = hw_config->name; ci->config.always_detect = hw_config->always_detect; ci->config.card_subtype = hw_config->card_subtype; ci->config.osp = hw_config->osp; if ((drv = snd_find_driver(ci->card_type)) == -1) { ci->enabled = 0; DDB(printf("Failed to find driver\n")); return FALSE; } DDB(printf("-- Driver name '%s' probe 0x%08x\n", sound_drivers[drv].name, sound_drivers[drv].probe)); hw_config->card_subtype = ci->config.card_subtype = sound_drivers[drv].card_subtype; if (sound_drivers[drv].probe(hw_config)) { DDB(printf("-- Hardware probed OK\n")); return TRUE; } DDB(printf("-- Failed to find hardware\n")); ci->enabled = 0; /* mark as not detected */ return FALSE; } return FALSE; }
static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag) { unsigned long flags; unsigned char temp; volatile int done, timeout_val; static unsigned char codec_dma_bits = 0; if (flag & CPF_FIRST) { /* * First block. Have to allocate DMA and to reset the board * before continuing. */ save_flags(flags); cli(); codec_dma_bits = sscape_read(devc, GA_CDCFG_REG); if (devc->dma_allocated == 0) devc->dma_allocated = 1; restore_flags(flags); sscape_write(devc, GA_HMCTL_REG, (temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f); /*Reset */ for (timeout_val = 10000; timeout_val > 0; timeout_val--) sscape_read(devc, GA_HMCTL_REG); /* Delay */ /* Take board out of reset */ sscape_write(devc, GA_HMCTL_REG, (temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80); } /* * Transfer one code block using DMA */ if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL) { printk(KERN_WARNING "soundscape: DMA buffer not available\n"); return 0; } memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size); save_flags(flags); cli(); /******** INTERRUPTS DISABLED NOW ********/ do_dma(devc, SSCAPE_DMA_A, audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys, size, DMA_MODE_WRITE); /* * Wait until transfer completes. */ done = 0; timeout_val = 30; while (!done && timeout_val-- > 0) { int resid; if (HZ / 50) sleep(HZ / 50); clear_dma_ff(devc->dma); if ((resid = get_dma_residue(devc->dma)) == 0) done = 1; } restore_flags(flags); if (!done) return 0; if (flag & CPF_LAST) { /* * Take the board out of reset */ outb((0x00), PORT(HOST_CTRL)); outb((0x00), PORT(MIDI_CTRL)); temp = sscape_read(devc, GA_HMCTL_REG); temp |= 0x40; sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */ /* * Wait until the ODB wakes up */ save_flags(flags); cli(); done = 0; timeout_val = 5 * HZ; while (!done && timeout_val-- > 0) { unsigned char x; sleep(1); x = inb(PORT(HOST_DATA)); if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */ { DDB(printk("Soundscape: Acknowledge = %x\n", x)); done = 1; } } sscape_write(devc, GA_CDCFG_REG, codec_dma_bits); restore_flags(flags); if (!done) { printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n"); return 0; } save_flags(flags); cli(); done = 0; timeout_val = 5 * HZ; while (!done && timeout_val-- > 0) { sleep(1); if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */ done = 1; } restore_flags(flags); if (!done) { printk(KERN_ERR "soundscape: OBP Initialization failed.\n"); return 0; } printk(KERN_INFO "SoundScape board initialized OK\n"); set_control(devc, CTL_MASTER_VOL, 100); set_control(devc, CTL_SYNTH_VOL, 100); #ifdef SSCAPE_DEBUG3 /* * Temporary debugging aid. Print contents of the registers after * downloading the code. */ { int i; for (i = 0; i < 13; i++) printk("I%d = %02x (new value)\n", i, sscape_read(devc, i)); } #endif } return 1; }
static int chip_detect(void) { int i; /* * Then try to detect with the old password */ board_type = C924; DDB(printk("Detect using password = 0xE5\n")); if (!detect_mad16()) /* No luck. Try different model */ { board_type = C928; DDB(printk("Detect using password = 0xE2\n")); if (!detect_mad16()) { board_type = C929; DDB(printk("Detect using password = 0xE3\n")); if (!detect_mad16()) { if (inb(PASSWD_REG) != 0xff) return 0; /* * First relocate MC# registers to 0xe0e/0xe0f, disable password */ outb((0xE4), PASSWD_REG); outb((0x80), PASSWD_REG); board_type = C930; DDB(printk("Detect using password = 0xE4\n")); for (i = 0xf8d; i <= 0xf93; i++) DDB(printk("port %03x = %02x\n", i, mad_read(i))); if(!detect_mad16()) { /* The C931 has the password reg at F8D */ outb((0xE4), 0xF8D); outb((0x80), 0xF8D); DDB(printk("Detect using password = 0xE4 for C931\n")); if (!detect_mad16()) { board_type = C924; c924pnp++; DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n")); if (!detect_mad16()) { c924pnp=0; return 0; } DDB(printk("mad16.c: 82C924 PnP detected\n")); } } else DDB(printk("mad16.c: 82C930 detected\n")); } else DDB(printk("mad16.c: 82C929 detected\n")); } else { unsigned char model; if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) { DDB(printk("mad16.c: Mozart detected\n")); board_type = MOZART; } else { DDB(printk("mad16.c: 82C928 detected???\n")); board_type = C928; } } } return 1; }
int hdaudio_vaio_vgn_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group) { int ctl = 0; DDB (cmn_err (CE_CONT, "hdaudio_vaio_vgn_mixer_init got called.\n")); HDA_OUTAMP_F (0x05, top_group, "speaker", 90, MIXF_MAINVOL); /* We sync the volume of the headphone DAC to the speaker DAC */ #if 1 HDA_OUTAMP_F (0x02, top_group, "headphone", 90, MIXF_MAINVOL); #endif HDA_SETSELECT (0x0f, 0); /* Int speaker mode */ HDA_SETSELECT (0x14, 1); /* Int mic mode */ /* Handle PIN widgets */ { int n, group, pin_group; n = 0; HDA_GROUP (pin_group, top_group, "jack"); if (HDA_PIN_GROUP (0x0a, group, pin_group, "headphone", n, "jack", 4)) /* Pin widget 0x0a */ { /* Src 0x2=pcm */ if (HDA_PINSELECT (0x0a, ctl, group, "mode", -1)) HDA_CHOICES (ctl, "pcm-out input"); HDA_OUTMUTE (0x0a, group, "mute", UNMUTE); } if (HDA_PIN_GROUP (0x0b, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x0b */ { /* Src 0x4=pcm */ if (HDA_PINSELECT (0x0b, ctl, group, "mode", -1)) HDA_CHOICES (ctl, "pcm-out input"); HDA_OUTMUTE (0x0b, group, "mute", UNMUTE); /* Widget 0x04 (pcm) */ HDA_OUTAMP (0x04, group, "-", 90); } if (HDA_PIN_GROUP (0x0c, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x0c */ { /* Src 0x3=pcm */ if (HDA_PINSELECT (0x0c, ctl, group, "mode", -1)) HDA_CHOICES (ctl, "pcm-out input"); HDA_OUTMUTE (0x0c, group, "mute", UNMUTE); /* Widget 0x03 (pcm) */ HDA_OUTAMP (0x03, group, "-", 90); } if (HDA_PIN_GROUP (0x0d, group, pin_group, "red", n, "jack", 4)) /* Pin widget 0x0d */ { /* Src 0x2=pcm */ if (HDA_PINSELECT (0x0d, ctl, group, "mode", -1)) HDA_CHOICES (ctl, "pcm-out input"); HDA_OUTMUTE (0x0d, group, "mute", UNMUTE); } if (HDA_PIN_GROUP (0x0e, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x0e */ { if (HDA_PINSELECT (0x0e, ctl, group, "mode", -1)) HDA_CHOICES (ctl, "input"); } } /* Handle ADC widgets */ { int n, group, rec_group; n = 0; HDA_GROUP (rec_group, top_group, "record"); if (HDA_ADC_GROUP (0x06, group, rec_group, "rec1", n, "record", 4)) /* ADC widget 0x06 */ { /* Src 0x7=rec */ /* Widget 0x07 (rec) */ /* Src 0xe=black */ HDA_INAMP_F (0x07, 0, group, "black", 80, MIXF_RECVOL); /* From widget 0x0e */ } if (HDA_ADC_GROUP (0x08, group, rec_group, "rec", n, "record", 8)) /* ADC widget 0x08 */ { /* Src 0x9=rec */ /* Widget 0x09 (rec) */ /* Src 0x15=rec */ HDA_INAMP_F (0x09, 0, group, "rec", 80, MIXF_RECVOL); /* From widget 0x15 */ /* Widget 0x15 (rec) */ /* Src 0xa=black */ /* Src 0xd=red */ /* Src 0x14=int-mic */ /* Src 0x2=pcm */ if (HDA_SELECT (0x15, "src", ctl, group, -1)) { HDA_CHOICES (ctl, "headphone mic int-mic pcm"); } HDA_OUTAMP (0x15, group, "micboost", 0); } if (HDA_ADC_GROUP (0x12, group, rec_group, "spdifin", n, "record", 4)) /* ADC widget 0x12 */ { /* Src 0x13=speaker */ } } /* Handle misc widgets */ { #if 0 if (HDA_MISC_GROUP (0x16, group, misc_group, "beep", n, "misc", 8)) /* Misc widget 0x16 */ { HDA_OUTAMP (0x16, group, "-", 90); } #endif } return 0; }
int oss_fmedia_attach (oss_device_t * osdev) { unsigned char pci_irq_line, pci_revision; unsigned short pci_command, vendor, device; unsigned int pci_ioaddr; int err; fm801_devc *devc; DDB (cmn_err (CE_WARN, "Entered FM801 FM801 probe routine\n")); pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor); pci_read_config_word (osdev, PCI_DEVICE_ID, &device); if (vendor != FORTEMEDIA_VENDOR_ID || device != FORTEMEDIA_FM801) return 0; pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision); pci_read_config_word (osdev, PCI_COMMAND, &pci_command); pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line); pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr); DDB (cmn_err (CE_WARN, "FM801 I/O base %04x\n", pci_ioaddr)); if (pci_irq_line == 0) { cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d). Can't continue\n", pci_irq_line); return 0; } if (pci_ioaddr == 0) { cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n"); return 0; } if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL) { cmn_err (CE_WARN, "Out of memory\n"); return 0; } devc->osdev = osdev; osdev->devc = devc; devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr); /* Remove I/O space marker in bit 0. */ devc->base &= ~3; devc->mpu_irq = fmedia_mpu_irq; devc->mpu_base = devc->base + 0x30; pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO; pci_write_config_word (osdev, PCI_COMMAND, pci_command); switch (pci_revision) { case 0xb1: devc->model = MDL_FM801AS; devc->chip_name = "ForteMedia FM801-AS"; break; case 0xb2: devc->model = MDL_FM801AU; devc->chip_name = "ForteMedia FM801-AU"; break; } oss_register_device (osdev, devc->chip_name); if ((err = oss_register_interrupts (osdev, 0, fm801intr, NULL)) < 0) { cmn_err (CE_WARN, "Error installing interrupt handler: %x\n", err); return 0; } MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV); MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1); return init_fm801 (devc); /* Detected */ }
int probe_mad16(struct address_info *hw_config) { int i; static int valid_ports[] = { 0x530, 0xe80, 0xf40, 0x604 }; unsigned char tmp; unsigned char cs4231_mode = 0; int ad_flags = 0; if (already_initialized) return 0; mad16_osp = hw_config->osp; /* * Check that all ports return 0xff (bus float) when no password * is written to the password register. */ DDB(printk("--- Detecting MAD16 / Mozart ---\n")); if (!chip_detect()) return 0; if (board_type == C930) return init_c930(hw_config); for (i = 0xf8d; i <= 0xf93; i++) if (!c924pnp) DDB(printk("port %03x = %02x\n", i, mad_read(i))) else DDB(printk("port %03x = %02x\n", i-0x80, mad_read(i))); /* * Set the WSS address */ tmp = (mad_read(MC1_PORT) & 0x0f) | 0x80; /* Enable WSS, Disable SB */ for (i = 0; i < 5; i++) { if (i > 3) /* Not a valid port */ { printk(KERN_ERR "MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base); return 0; } if (valid_ports[i] == hw_config->io_base) { tmp |= i << 4; /* WSS port select bits */ break; } } /* * Set optional CD-ROM and joystick settings. */ tmp &= ~0x0f; #if defined(MAD16_CONF) tmp |= ((MAD16_CONF) & 0x0f); /* CD-ROM and joystick bits */ #endif mad_write(MC1_PORT, tmp); #if defined(MAD16_CONF) && defined(MAD16_CDSEL) tmp = MAD16_CDSEL; #else tmp = mad_read(MC2_PORT); #endif #ifdef MAD16_OPL4 tmp |= 0x20; /* Enable OPL4 access */ #endif mad_write(MC2_PORT, tmp); mad_write(MC3_PORT, 0xf0); /* Disable SB */ if (board_type == C924) /* Specific C924 init values */ { mad_write(MC4_PORT, 0xA0); mad_write(MC5_PORT, 0x05); mad_write(MC6_PORT, 0x03); } if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp)) return 0; if (ad_flags & (AD_F_CS4231 | AD_F_CS4248)) cs4231_mode = 0x02; /* CS4248/CS4231 sync delay switch */ if (board_type == C929) { mad_write(MC4_PORT, 0xa2); mad_write(MC5_PORT, 0xA5 | cs4231_mode); mad_write(MC6_PORT, 0x03); /* Disable MPU401 */ } else { mad_write(MC4_PORT, 0x02); mad_write(MC5_PORT, 0x30 | cs4231_mode); } for (i = 0xf8d; i <= 0xf93; i++) if (!c924pnp) DDB(printk("port %03x after init = %02x\n", i, mad_read(i))) else DDB(printk("port %03x after init = %02x\n", i-0x80, mad_read(i))); wss_init(hw_config); return 1; }
static int __init detect_sscape_pnp(sscape_info* devc) { long i, irq_bits = 0xff; unsigned int d; DDB(printk("Entered detect_sscape_pnp(%x)\n", devc->base)); if (check_region(devc->base, 8)) { printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->base); return 0; } if (check_region(devc->codec, 2)) { printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->codec); return 0; } if ( (inb( devc -> base + 2) & 0x78) != 0) return 0; d = inb ( devc -> base + 4) & 0xF0; if ( (d & 0x80) != 0) return 0; if (d == 0) { devc->codec_type = 1; devc->ic_type = IC_ODIE; } else if ( (d & 0x60) != 0) { devc->codec_type = 2; devc->ic_type = IC_OPUS; } else if ( (d & 0x40) != 0) { devc->codec_type = 2; devc->ic_type = IC_ODIE; } else return 0; sscape_is_pnp = 1; outb(0xFA, devc -> base+4); if ((inb( devc -> base+4) & 0x9F) != 0x0A) return 0; outb(0xFE, devc -> base+4); if ( (inb(devc -> base+4) & 0x9F) != 0x0E) return 0; if ( (inb(devc -> base+5) & 0x9F) != 0x0E) return 0; if (devc->codec_type == 2) { if (devc -> codec != devc -> base + 8) printk("soundscape warning: incorrect codec port specified\n"); devc -> codec = devc -> base + 8; d = 0x10 | (sscape_read(devc, 9) & 0xCF); sscape_write(devc, 9, d); sscape_write(devc, 6, 0x80); } else { //todo: check codec is not base + 8 } d = (sscape_read(devc, 9) & 0x3F) | 0xC0; sscape_write(devc, 9, d); for (i = 0; i < 550000; i++) if ( !(inb(devc -> codec) & 0x80) ) break; d = inb(devc -> codec); if (d & 0x80) return 0; if ( inb(devc -> codec + 2) == 0xFF) return 0; sscape_write(devc, 9, sscape_read(devc, 9) & 0x3F ); d = inb(devc -> codec) & 0x80; if ( d == 0) { printk(KERN_INFO "soundscape: hardware detected\n"); valid_interrupts = valid_interrupts_new; } else { printk(KERN_INFO "soundscape: board looks like media fx\n"); valid_interrupts = valid_interrupts_old; old_hardware = 1; } sscape_write( devc, 9, 0xC0 | (sscape_read(devc, 9) & 0x3F) ); for (i = 0; i < 550000; i++) if ( !(inb(devc -> codec) & 0x80)) break; sscape_pnp_init_hw(devc); for (i = 0; i < sizeof(valid_interrupts); i++) { if (devc->codec_irq == valid_interrupts[i]) { irq_bits = i; break; } } sscape_write(devc, GA_INTENA_REG, 0x00); sscape_write(devc, GA_DMACFG_REG, 0x50); sscape_write(devc, GA_DMAA_REG, 0x70); sscape_write(devc, GA_DMAB_REG, 0x20); sscape_write(devc, GA_INTCFG_REG, 0xf0); sscape_write(devc, GA_CDCFG_REG, 0x89 | (devc->dma << 4) | (irq_bits << 1)); sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 0) | 0x20); sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 1) | 0x20); return 1; }