X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fpci%2Fca0106%2Fca0106_main.c;fp=sound%2Fpci%2Fca0106%2Fca0106_main.c;h=12bbbb6afd2df348df3526cf88a3da8a0a6bd7c0;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=fd8bfebfbd541a846a20c908182406e0ce098437;hpb=4e76c8a9fa413ccc09d3f7f664183dcce3555d57;p=linux-2.6.git diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index fd8bfebfb..12bbbb6af 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -186,8 +186,8 @@ static struct snd_ca0106_details ca0106_chip_details[] = { /* New Audigy SE. Has a different DAC. */ /* SB0570: * CTRL:CA0106-DAT - * ADC: WM8768GEDS - * DAC: WM8775EDS + * ADC: WM8775EDS + * DAC: WM8768GEDS */ { .serial = 0x100a1102, .name = "Audigy SE [SB0570]", @@ -195,9 +195,14 @@ static struct snd_ca0106_details ca0106_chip_details[] = { .i2c_adc = 1, .spi_dac = 1 } , /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ + /* SB0438 + * CTRL:CA0106-DAT + * ADC: WM8775SEDS + * DAC: CS4382-KQZ + */ { .serial = 0x10091462, .name = "MSI K8N Diamond MB [SB0438]", - .gpio_type = 1, + .gpio_type = 2, .i2c_adc = 1 } , /* Shuttle XPC SD31P which has an onboard Creative Labs * Sound Blaster Live! 24-bit EAX @@ -326,6 +331,7 @@ int snd_ca0106_spi_write(struct snd_ca0106 * emu, return 0; } +/* The ADC does not support i2c read, so only write is implemented */ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value) @@ -340,6 +346,7 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, } tmp = reg << 25 | value << 16; + // snd_printk("I2C-write:reg=0x%x, value=0x%x\n", reg, value); /* Not sure what this I2C channel controls. */ /* snd_ca0106_ptr_write(emu, I2C_D0, 0, tmp); */ @@ -348,8 +355,9 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, for (retry = 0; retry < 10; retry++) { /* Send the data to i2c */ - tmp = snd_ca0106_ptr_read(emu, I2C_A, 0); - tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK); + //tmp = snd_ca0106_ptr_read(emu, I2C_A, 0); + //tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK); + tmp = 0; tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD); snd_ca0106_ptr_write(emu, I2C_A, 0, tmp); @@ -1181,7 +1189,7 @@ static unsigned int spi_dac_init[] = { 0x02ff, 0x0400, 0x0520, - 0x0600, + 0x0620, /* Set 24 bit. Was 0x0600 */ 0x08ff, 0x0aff, 0x0cff, @@ -1200,6 +1208,22 @@ static unsigned int spi_dac_init[] = { 0x1400, }; +static unsigned int i2c_adc_init[][2] = { + { 0x17, 0x00 }, /* Reset */ + { 0x07, 0x00 }, /* Timeout */ + { 0x0b, 0x22 }, /* Interface control */ + { 0x0c, 0x22 }, /* Master mode control */ + { 0x0d, 0x08 }, /* Powerdown control */ + { 0x0e, 0xcf }, /* Attenuation Left 0x01 = -103dB, 0xff = 24dB */ + { 0x0f, 0xcf }, /* Attenuation Right 0.5dB steps */ + { 0x10, 0x7b }, /* ALC Control 1 */ + { 0x11, 0x00 }, /* ALC Control 2 */ + { 0x12, 0x32 }, /* ALC Control 3 */ + { 0x13, 0x00 }, /* Noise gate control */ + { 0x14, 0xa6 }, /* Limiter control */ + { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */ +}; + static int __devinit snd_ca0106_create(struct snd_card *card, struct pci_dev *pci, struct snd_ca0106 **rchip) @@ -1244,7 +1268,7 @@ static int __devinit snd_ca0106_create(struct snd_card *card, } if (request_irq(pci->irq, snd_ca0106_interrupt, - SA_INTERRUPT|SA_SHIRQ, "snd_ca0106", + IRQF_DISABLED|IRQF_SHARED, "snd_ca0106", (void *)chip)) { snd_ca0106_free(chip); printk(KERN_ERR "cannot grab irq\n"); @@ -1361,7 +1385,12 @@ static int __devinit snd_ca0106_create(struct snd_card *card, snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */ chip->capture_source = 3; /* Set CAPTURE_SOURCE */ - if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */ + if (chip->details->gpio_type == 2) { /* The SB0438 use GPIO differently. */ + /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ + outl(0x0, chip->port+GPIO); + //outl(0x00f0e000, chip->port+GPIO); /* Analog */ + outl(0x005f5301, chip->port+GPIO); /* Analog */ + } else if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */ /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ outl(0x0, chip->port+GPIO); //outl(0x00f0e000, chip->port+GPIO); /* Analog */ @@ -1379,7 +1408,19 @@ static int __devinit snd_ca0106_create(struct snd_card *card, outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */ if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */ - snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */ + int size, n; + + size = ARRAY_SIZE(i2c_adc_init); + //snd_printk("I2C:array size=0x%x\n", size); + for (n=0; n < size; n++) { + snd_ca0106_i2c_write(chip, i2c_adc_init[n][0], i2c_adc_init[n][1]); + } + for (n=0; n < 4; n++) { + chip->i2c_capture_volume[n][0]= 0xcf; + chip->i2c_capture_volume[n][1]= 0xcf; + } + chip->i2c_capture_source=2; /* Line in */ + //snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */ } if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */ int size, n; @@ -1561,7 +1602,7 @@ static void __devexit snd_ca0106_remove(struct pci_dev *pci) } // PCI IDs -static struct pci_device_id snd_ca0106_ids[] __devinitdata = { +static struct pci_device_id snd_ca0106_ids[] = { { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */ { 0, } };