diff options
Diffstat (limited to 'sound/pci/ca0106/ca0106_main.c')
-rw-r--r-- | sound/pci/ca0106/ca0106_main.c | 103 |
1 files changed, 76 insertions, 27 deletions
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index fcab8fb97e38..31d8db9f7a4c 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.23 | 4 | * Version: 0.0.25 |
5 | * | 5 | * |
6 | * FEATURES currently supported: | 6 | * FEATURES currently supported: |
7 | * Front, Rear and Center/LFE. | 7 | * Front, Rear and Center/LFE. |
@@ -79,6 +79,10 @@ | |||
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 | 80 | * 0.0.23 |
81 | * Implement support for Line-in capture on SB Live 24bit. | 81 | * Implement support for Line-in capture on SB Live 24bit. |
82 | * 0.0.24 | ||
83 | * Add support for mute control on SB Live 24bit (cards w/ SPI DAC) | ||
84 | * 0.0.25 | ||
85 | * Powerdown SPI DAC channels when not in use | ||
82 | * | 86 | * |
83 | * BUGS: | 87 | * BUGS: |
84 | * Some stability problems when unloading the snd-ca0106 kernel module. | 88 | * Some stability problems when unloading the snd-ca0106 kernel module. |
@@ -170,6 +174,15 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model."); | |||
170 | static struct snd_ca0106_details ca0106_chip_details[] = { | 174 | static struct snd_ca0106_details ca0106_chip_details[] = { |
171 | /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */ | 175 | /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */ |
172 | /* It is really just a normal SB Live 24bit. */ | 176 | /* It is really just a normal SB Live 24bit. */ |
177 | /* Tested: | ||
178 | * See ALSA bug#3251 | ||
179 | */ | ||
180 | { .serial = 0x10131102, | ||
181 | .name = "X-Fi Extreme Audio [SBxxxx]", | ||
182 | .gpio_type = 1, | ||
183 | .i2c_adc = 1 } , | ||
184 | /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */ | ||
185 | /* It is really just a normal SB Live 24bit. */ | ||
173 | /* | 186 | /* |
174 | * CTRL:CA0111-WTLF | 187 | * CTRL:CA0111-WTLF |
175 | * ADC: WM8775SEDS | 188 | * ADC: WM8775SEDS |
@@ -261,10 +274,11 @@ static struct snd_ca0106_details ca0106_chip_details[] = { | |||
261 | 274 | ||
262 | /* hardware definition */ | 275 | /* hardware definition */ |
263 | static struct snd_pcm_hardware snd_ca0106_playback_hw = { | 276 | static struct snd_pcm_hardware snd_ca0106_playback_hw = { |
264 | .info = (SNDRV_PCM_INFO_MMAP | | 277 | .info = SNDRV_PCM_INFO_MMAP | |
265 | SNDRV_PCM_INFO_INTERLEAVED | | 278 | SNDRV_PCM_INFO_INTERLEAVED | |
266 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 279 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
267 | SNDRV_PCM_INFO_MMAP_VALID), | 280 | SNDRV_PCM_INFO_MMAP_VALID | |
281 | SNDRV_PCM_INFO_SYNC_START, | ||
268 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, | 282 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, |
269 | .rates = (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | | 283 | .rates = (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | |
270 | SNDRV_PCM_RATE_192000), | 284 | SNDRV_PCM_RATE_192000), |
@@ -447,6 +461,19 @@ static void snd_ca0106_pcm_free_substream(struct snd_pcm_runtime *runtime) | |||
447 | kfree(runtime->private_data); | 461 | kfree(runtime->private_data); |
448 | } | 462 | } |
449 | 463 | ||
464 | static const int spi_dacd_reg[] = { | ||
465 | [PCM_FRONT_CHANNEL] = SPI_DACD4_REG, | ||
466 | [PCM_REAR_CHANNEL] = SPI_DACD0_REG, | ||
467 | [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_REG, | ||
468 | [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_REG, | ||
469 | }; | ||
470 | static const int spi_dacd_bit[] = { | ||
471 | [PCM_FRONT_CHANNEL] = SPI_DACD4_BIT, | ||
472 | [PCM_REAR_CHANNEL] = SPI_DACD0_BIT, | ||
473 | [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_BIT, | ||
474 | [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT, | ||
475 | }; | ||
476 | |||
450 | /* open_playback callback */ | 477 | /* open_playback callback */ |
451 | static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, | 478 | static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, |
452 | int channel_id) | 479 | int channel_id) |
@@ -481,6 +508,17 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr | |||
481 | return err; | 508 | return err; |
482 | if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0) | 509 | if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0) |
483 | return err; | 510 | return err; |
511 | snd_pcm_set_sync(substream); | ||
512 | |||
513 | if (chip->details->spi_dac && channel_id != PCM_FRONT_CHANNEL) { | ||
514 | const int reg = spi_dacd_reg[channel_id]; | ||
515 | |||
516 | /* Power up dac */ | ||
517 | chip->spi_dac_reg[reg] &= ~spi_dacd_bit[channel_id]; | ||
518 | err = snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]); | ||
519 | if (err < 0) | ||
520 | return err; | ||
521 | } | ||
484 | return 0; | 522 | return 0; |
485 | } | 523 | } |
486 | 524 | ||
@@ -491,6 +529,14 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream) | |||
491 | struct snd_pcm_runtime *runtime = substream->runtime; | 529 | struct snd_pcm_runtime *runtime = substream->runtime; |
492 | struct snd_ca0106_pcm *epcm = runtime->private_data; | 530 | struct snd_ca0106_pcm *epcm = runtime->private_data; |
493 | chip->playback_channels[epcm->channel_id].use = 0; | 531 | chip->playback_channels[epcm->channel_id].use = 0; |
532 | |||
533 | if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) { | ||
534 | const int reg = spi_dacd_reg[epcm->channel_id]; | ||
535 | |||
536 | /* Power down DAC */ | ||
537 | chip->spi_dac_reg[reg] |= spi_dacd_bit[epcm->channel_id]; | ||
538 | snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]); | ||
539 | } | ||
494 | /* FIXME: maybe zero others */ | 540 | /* FIXME: maybe zero others */ |
495 | return 0; | 541 | return 0; |
496 | } | 542 | } |
@@ -809,6 +855,9 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream, | |||
809 | break; | 855 | break; |
810 | } | 856 | } |
811 | snd_pcm_group_for_each_entry(s, substream) { | 857 | snd_pcm_group_for_each_entry(s, substream) { |
858 | if (snd_pcm_substream_chip(s) != emu || | ||
859 | s->stream != SNDRV_PCM_STREAM_PLAYBACK) | ||
860 | continue; | ||
812 | runtime = s->runtime; | 861 | runtime = s->runtime; |
813 | epcm = runtime->private_data; | 862 | epcm = runtime->private_data; |
814 | channel = epcm->channel_id; | 863 | channel = epcm->channel_id; |
@@ -1214,28 +1263,23 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s | |||
1214 | return 0; | 1263 | return 0; |
1215 | } | 1264 | } |
1216 | 1265 | ||
1266 | #define SPI_REG(reg, value) (((reg) << SPI_REG_SHIFT) | (value)) | ||
1217 | static unsigned int spi_dac_init[] = { | 1267 | static unsigned int spi_dac_init[] = { |
1218 | 0x00ff, | 1268 | SPI_REG(SPI_LDA1_REG, SPI_DA_BIT_0dB), /* 0dB dig. attenuation */ |
1219 | 0x02ff, | 1269 | SPI_REG(SPI_RDA1_REG, SPI_DA_BIT_0dB), |
1220 | 0x0400, | 1270 | SPI_REG(SPI_PL_REG, SPI_PL_BIT_L_L | SPI_PL_BIT_R_R | SPI_IZD_BIT), |
1221 | 0x0520, | 1271 | SPI_REG(SPI_FMT_REG, SPI_FMT_BIT_I2S | SPI_IWL_BIT_24), |
1222 | 0x0620, /* Set 24 bit. Was 0x0600 */ | 1272 | SPI_REG(SPI_LDA2_REG, SPI_DA_BIT_0dB), |
1223 | 0x08ff, | 1273 | SPI_REG(SPI_RDA2_REG, SPI_DA_BIT_0dB), |
1224 | 0x0aff, | 1274 | SPI_REG(SPI_LDA3_REG, SPI_DA_BIT_0dB), |
1225 | 0x0cff, | 1275 | SPI_REG(SPI_RDA3_REG, SPI_DA_BIT_0dB), |
1226 | 0x0eff, | 1276 | SPI_REG(SPI_MASTDA_REG, SPI_DA_BIT_0dB), |
1227 | 0x10ff, | 1277 | SPI_REG(9, 0x00), |
1228 | 0x1200, | 1278 | SPI_REG(SPI_MS_REG, SPI_DACD0_BIT | SPI_DACD1_BIT | SPI_DACD2_BIT), |
1229 | 0x1400, | 1279 | SPI_REG(12, 0x00), |
1230 | 0x1480, | 1280 | SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB), |
1231 | 0x1800, | 1281 | SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE), |
1232 | 0x1aff, | 1282 | SPI_REG(SPI_DACD4_REG, 0x00), |
1233 | 0x1cff, | ||
1234 | 0x1e00, | ||
1235 | 0x0530, | ||
1236 | 0x0602, | ||
1237 | 0x0622, | ||
1238 | 0x1400, | ||
1239 | }; | 1283 | }; |
1240 | 1284 | ||
1241 | static unsigned int i2c_adc_init[][2] = { | 1285 | static unsigned int i2c_adc_init[][2] = { |
@@ -1475,8 +1519,13 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card, | |||
1475 | int size, n; | 1519 | int size, n; |
1476 | 1520 | ||
1477 | size = ARRAY_SIZE(spi_dac_init); | 1521 | size = ARRAY_SIZE(spi_dac_init); |
1478 | for (n=0; n < size; n++) | 1522 | for (n = 0; n < size; n++) { |
1523 | int reg = spi_dac_init[n] >> SPI_REG_SHIFT; | ||
1524 | |||
1479 | snd_ca0106_spi_write(chip, spi_dac_init[n]); | 1525 | snd_ca0106_spi_write(chip, spi_dac_init[n]); |
1526 | if (reg < ARRAY_SIZE(chip->spi_dac_reg)) | ||
1527 | chip->spi_dac_reg[reg] = spi_dac_init[n]; | ||
1528 | } | ||
1480 | } | 1529 | } |
1481 | 1530 | ||
1482 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, | 1531 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, |