diff options
author | James Courtier-Dutton <James@superbug.co.uk> | 2005-12-21 16:26:26 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:31:08 -0500 |
commit | aad9095322c0c7d9637f29b71167458c36a4cdf6 (patch) | |
tree | f321047c62f3583a3a3990db6a8d165682b454d8 | |
parent | 18f3c59f2b14225bd23c41a87a5eec39439bc8b9 (diff) |
[ALSA] snd-ca0106: Fix SPI driver code. Fixes speaker output.
Modules: CA0106 driver
Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
-rw-r--r-- | sound/pci/ca0106/ca0106_main.c | 72 |
1 files changed, 57 insertions, 15 deletions
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 1cf6f1fa98b1..6ed7c0bfa091 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -284,20 +284,38 @@ void snd_ca0106_ptr_write(struct snd_ca0106 *emu, | |||
284 | spin_unlock_irqrestore(&emu->emu_lock, flags); | 284 | spin_unlock_irqrestore(&emu->emu_lock, flags); |
285 | } | 285 | } |
286 | 286 | ||
287 | int snd_ca0106_spi_write(struct snd_ca0106 *emu, | 287 | int snd_ca0106_spi_write(struct snd_ca0106 * emu, |
288 | u32 value) | 288 | unsigned int data) |
289 | { | 289 | { |
290 | snd_ca0106_ptr_write(emu, SPI, 0, value); | 290 | unsigned int reset, set; |
291 | unsigned int reg, tmp; | ||
292 | int n, result; | ||
293 | reg = SPI; | ||
294 | if (data > 0xffff) /* Only 16bit values allowed */ | ||
295 | return 1; | ||
296 | tmp = snd_ca0106_ptr_read(emu, reg, 0); | ||
297 | reset = (tmp & ~0x3ffff) | 0x20000; /* Set xxx20000 */ | ||
298 | set = reset | 0x10000; /* Set xxx1xxxx */ | ||
299 | snd_ca0106_ptr_write(emu, reg, 0, reset | data); | ||
300 | tmp = snd_ca0106_ptr_read(emu, reg, 0); /* write post */ | ||
301 | snd_ca0106_ptr_write(emu, reg, 0, set | data); | ||
302 | result = 1; | ||
303 | /* Wait for status bit to return to 0 */ | ||
304 | for (n = 0; n < 100; n++) { | ||
305 | udelay(10); | ||
306 | tmp = snd_ca0106_ptr_read(emu, reg, 0); | ||
307 | if (!(tmp & 0x10000)) { | ||
308 | result = 0; | ||
309 | break; | ||
310 | } | ||
311 | } | ||
312 | if (result) /* Timed out */ | ||
313 | return 1; | ||
314 | snd_ca0106_ptr_write(emu, reg, 0, reset | data); | ||
315 | tmp = snd_ca0106_ptr_read(emu, reg, 0); /* Write post */ | ||
291 | return 0; | 316 | return 0; |
292 | } | 317 | } |
293 | 318 | ||
294 | int snd_ca0106_spi_read(struct snd_ca0106 *emu, | ||
295 | u32 *value) | ||
296 | { | ||
297 | *value = snd_ca0106_ptr_read(emu, SPI, 0); | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | int snd_ca0106_i2c_write(struct snd_ca0106 *emu, | 319 | int snd_ca0106_i2c_write(struct snd_ca0106 *emu, |
302 | u32 reg, | 320 | u32 reg, |
303 | u32 value) | 321 | u32 value) |
@@ -1148,6 +1166,30 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s | |||
1148 | return 0; | 1166 | return 0; |
1149 | } | 1167 | } |
1150 | 1168 | ||
1169 | static unsigned int spi_dac_init[] = { | ||
1170 | 0x00ff, | ||
1171 | 0x02ff, | ||
1172 | 0x0400, | ||
1173 | 0x0520, | ||
1174 | 0x0600, | ||
1175 | 0x08ff, | ||
1176 | 0x0aff, | ||
1177 | 0x0cff, | ||
1178 | 0x0eff, | ||
1179 | 0x10ff, | ||
1180 | 0x1200, | ||
1181 | 0x1400, | ||
1182 | 0x1480, | ||
1183 | 0x1800, | ||
1184 | 0x1aff, | ||
1185 | 0x1cff, | ||
1186 | 0x1e00, | ||
1187 | 0x0530, | ||
1188 | 0x0602, | ||
1189 | 0x0622, | ||
1190 | 0x1400, | ||
1191 | }; | ||
1192 | |||
1151 | static int __devinit snd_ca0106_create(struct snd_card *card, | 1193 | static int __devinit snd_ca0106_create(struct snd_card *card, |
1152 | struct pci_dev *pci, | 1194 | struct pci_dev *pci, |
1153 | struct snd_ca0106 **rchip) | 1195 | struct snd_ca0106 **rchip) |
@@ -1330,11 +1372,11 @@ static int __devinit snd_ca0106_create(struct snd_card *card, | |||
1330 | snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */ | 1372 | snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */ |
1331 | } | 1373 | } |
1332 | if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */ | 1374 | if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */ |
1333 | u32 tmp; | 1375 | int size, n; |
1334 | snd_ca0106_spi_write(chip, 0xf0622); /* Enable speakers output. */ | 1376 | |
1335 | snd_ca0106_spi_read(chip, &tmp); /* Read the value. */ | 1377 | size = ARRAY_SIZE(spi_dac_init); |
1336 | snd_ca0106_spi_write(chip, 0xe1400); | 1378 | for (n=0; n < size; n++) |
1337 | snd_ca0106_spi_read(chip, &tmp); /* Read the value. */ | 1379 | snd_ca0106_spi_write(chip, spi_dac_init[n]); |
1338 | } | 1380 | } |
1339 | 1381 | ||
1340 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, | 1382 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, |