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.c72
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
287int snd_ca0106_spi_write(struct snd_ca0106 *emu, 287int 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
294int 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
301int snd_ca0106_i2c_write(struct snd_ca0106 *emu, 319int 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
1169static 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
1151static int __devinit snd_ca0106_create(struct snd_card *card, 1193static 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,