aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ca0106/ca0106_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ca0106/ca0106_main.c')
-rw-r--r--sound/pci/ca0106/ca0106_main.c70
1 files changed, 66 insertions, 4 deletions
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index a56e68ea87bc..58d9026c8ca6 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk> 2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit 3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
4 * Version: 0.0.22 4 * Version: 0.0.23
5 * 5 *
6 * FEATURES currently supported: 6 * FEATURES currently supported:
7 * Front, Rear and Center/LFE. 7 * Front, Rear and Center/LFE.
@@ -77,6 +77,8 @@
77 * Add SPDIF capture using optional digital I/O module for SB Live 24bit. (Analog capture does not yet work.) 77 * Add SPDIF capture using optional digital I/O module for SB Live 24bit. (Analog capture does not yet work.)
78 * 0.0.22 78 * 0.0.22
79 * Add support for MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97. From kiksen, bug #901 79 * Add support for MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97. From kiksen, bug #901
80 * 0.0.23
81 * Implement support for Line-in capture on SB Live 24bit.
80 * 82 *
81 * BUGS: 83 * BUGS:
82 * Some stability problems when unloading the snd-ca0106 kernel module. 84 * Some stability problems when unloading the snd-ca0106 kernel module.
@@ -173,15 +175,18 @@ static ca0106_details_t ca0106_chip_details[] = {
173 /* New Sound Blaster Live! 7.1 24bit. This does not have an AC97. 53SB041000001 */ 175 /* New Sound Blaster Live! 7.1 24bit. This does not have an AC97. 53SB041000001 */
174 { .serial = 0x10061102, 176 { .serial = 0x10061102,
175 .name = "Live! 7.1 24bit [SB0410]", 177 .name = "Live! 7.1 24bit [SB0410]",
176 .gpio_type = 1 } , 178 .gpio_type = 1,
179 .i2c_adc = 1 } ,
177 /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */ 180 /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */
178 { .serial = 0x10071102, 181 { .serial = 0x10071102,
179 .name = "Live! 7.1 24bit [SB0413]", 182 .name = "Live! 7.1 24bit [SB0413]",
180 .gpio_type = 1 } , 183 .gpio_type = 1,
184 .i2c_adc = 1 } ,
181 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ 185 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
182 { .serial = 0x10091462, 186 { .serial = 0x10091462,
183 .name = "MSI K8N Diamond MB [SB0438]", 187 .name = "MSI K8N Diamond MB [SB0438]",
184 .gpio_type = 1 } , 188 .gpio_type = 1,
189 .i2c_adc = 1 } ,
185 { .serial = 0, 190 { .serial = 0,
186 .name = "AudigyLS [Unknown]" } 191 .name = "AudigyLS [Unknown]" }
187}; 192};
@@ -257,6 +262,59 @@ void snd_ca0106_ptr_write(ca0106_t *emu,
257 spin_unlock_irqrestore(&emu->emu_lock, flags); 262 spin_unlock_irqrestore(&emu->emu_lock, flags);
258} 263}
259 264
265int snd_ca0106_i2c_write(ca0106_t *emu,
266 u32 reg,
267 u32 value)
268{
269 u32 tmp;
270 int timeout=0;
271 int status;
272 int retry;
273 if ((reg > 0x7f) || (value > 0x1ff))
274 {
275 snd_printk("i2c_write: invalid values.\n");
276 return -EINVAL;
277 }
278
279 tmp = reg << 25 | value << 16;
280 snd_ca0106_ptr_write(emu, I2C_D0, 0, tmp);
281 snd_ca0106_ptr_write(emu, I2C_D1, 0, tmp);
282
283 for(retry=0;retry<10;retry++)
284 {
285 /* Send the data to i2c */
286 tmp = snd_ca0106_ptr_read(emu, I2C_A, 0);
287 tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK);
288 tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
289 snd_ca0106_ptr_write(emu, I2C_A, 0, tmp);
290
291 /* Wait till the transaction ends */
292 while(1)
293 {
294 status = snd_ca0106_ptr_read(emu, I2C_A, 0);
295 //snd_printk("I2C:status=0x%x\n", status);
296 timeout++;
297 if((status & I2C_A_ADC_START)==0)
298 break;
299
300 if(timeout>1000)
301 break;
302 }
303 //Read back and see if the transaction is successful
304 if((status & I2C_A_ADC_ABORT)==0)
305 break;
306 }
307
308 if(retry==10)
309 {
310 snd_printk("Writing to ADC failed!\n");
311 return -EINVAL;
312 }
313
314 return 0;
315}
316
317
260static void snd_ca0106_intr_enable(ca0106_t *emu, unsigned int intrenb) 318static void snd_ca0106_intr_enable(ca0106_t *emu, unsigned int intrenb)
261{ 319{
262 unsigned long flags; 320 unsigned long flags;
@@ -1177,6 +1235,10 @@ static int __devinit snd_ca0106_create(snd_card_t *card,
1177 //outl(0x00000009, chip->port+HCFG); 1235 //outl(0x00000009, chip->port+HCFG);
1178 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */ 1236 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */
1179 1237
1238 if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */
1239 snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */
1240 }
1241
1180 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, 1242 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
1181 chip, &ops)) < 0) { 1243 chip, &ops)) < 0) {
1182 snd_ca0106_free(chip); 1244 snd_ca0106_free(chip);