diff options
Diffstat (limited to 'sound/pci/ca0106/ca0106_main.c')
-rw-r--r-- | sound/pci/ca0106/ca0106_main.c | 70 |
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 | ||
265 | int 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 | |||
260 | static void snd_ca0106_intr_enable(ca0106_t *emu, unsigned int intrenb) | 318 | static 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); |