diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-11-09 10:47:26 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 03:01:23 -0500 |
commit | 56255060ea51984e728223d8056b3faaba0dadf6 (patch) | |
tree | e5a68da414caec33bc6e0e4a950c97b5e331f403 /sound/pci/ice1712 | |
parent | bd903b6ed7fb107e122682db5ac8aaa323ab84c9 (diff) |
[ALSA] ice1724 - Add support of M-Audio Audiophile 192
Added the (experimental) support of M-Audio Audiophile 192 board.
Currently, the analog and the digital playbacks seem working fine.
The inputs seem not working as far as I've tested yet.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/ice1712')
-rw-r--r-- | sound/pci/ice1712/revo.c | 204 | ||||
-rw-r--r-- | sound/pci/ice1712/revo.h | 5 |
2 files changed, 208 insertions, 1 deletions
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 233e9a5a2e70..0e578aa38af2 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c | |||
@@ -303,6 +303,181 @@ static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { | |||
303 | 303 | ||
304 | static struct snd_pt2258 ptc_revo51_volume; | 304 | static struct snd_pt2258 ptc_revo51_volume; |
305 | 305 | ||
306 | /* AK4358 for AP192 DAC, AK5385A for ADC */ | ||
307 | static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | ||
308 | { | ||
309 | struct snd_ice1712 *ice = ak->private_data[0]; | ||
310 | |||
311 | revo_set_rate_val(ak, rate); | ||
312 | |||
313 | #if 1 /* FIXME: do we need this procedure? */ | ||
314 | /* reset DFS pin of AK5385A for ADC, too */ | ||
315 | /* DFS0 (pin 18) -- GPIO10 pin 77 */ | ||
316 | snd_ice1712_save_gpio_status(ice); | ||
317 | snd_ice1712_gpio_write_bits(ice, 1 << 10, | ||
318 | rate > 48000 ? (1 << 10) : 0); | ||
319 | snd_ice1712_restore_gpio_status(ice); | ||
320 | #endif | ||
321 | } | ||
322 | |||
323 | static struct snd_akm4xxx_dac_channel ap192_dac[] = { | ||
324 | AK_DAC("PCM Playback Volume", 2) | ||
325 | }; | ||
326 | |||
327 | static struct snd_akm4xxx akm_ap192 __devinitdata = { | ||
328 | .type = SND_AK4358, | ||
329 | .num_dacs = 2, | ||
330 | .ops = { | ||
331 | .set_rate_val = ap192_set_rate_val | ||
332 | }, | ||
333 | .dac_info = ap192_dac, | ||
334 | }; | ||
335 | |||
336 | static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { | ||
337 | .caddr = 2, | ||
338 | .cif = 0, | ||
339 | .data_mask = VT1724_REVO_CDOUT, | ||
340 | .clk_mask = VT1724_REVO_CCLK, | ||
341 | .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3, | ||
342 | .cs_addr = VT1724_REVO_CS3, | ||
343 | .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3, | ||
344 | .add_flags = VT1724_REVO_CCLK, /* high at init */ | ||
345 | .mask_flags = 0, | ||
346 | }; | ||
347 | |||
348 | #if 0 | ||
349 | /* FIXME: ak4114 makes the sound much lower due to some confliction, | ||
350 | * so let's disable it right now... | ||
351 | */ | ||
352 | #define BUILD_AK4114_AP192 | ||
353 | #endif | ||
354 | |||
355 | #ifdef BUILD_AK4114_AP192 | ||
356 | /* AK4114 support on Audiophile 192 */ | ||
357 | /* CDTO (pin 32) -- GPIO2 pin 52 | ||
358 | * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358) | ||
359 | * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358) | ||
360 | * CSN (pin 35) -- GPIO7 pin 59 | ||
361 | */ | ||
362 | #define AK4114_ADDR 0x00 | ||
363 | |||
364 | static void write_data(struct snd_ice1712 *ice, unsigned int gpio, | ||
365 | unsigned int data, int idx) | ||
366 | { | ||
367 | for (; idx >= 0; idx--) { | ||
368 | /* drop clock */ | ||
369 | gpio &= ~VT1724_REVO_CCLK; | ||
370 | snd_ice1712_gpio_write(ice, gpio); | ||
371 | udelay(1); | ||
372 | /* set data */ | ||
373 | if (data & (1 << idx)) | ||
374 | gpio |= VT1724_REVO_CDOUT; | ||
375 | else | ||
376 | gpio &= ~VT1724_REVO_CDOUT; | ||
377 | snd_ice1712_gpio_write(ice, gpio); | ||
378 | udelay(1); | ||
379 | /* raise clock */ | ||
380 | gpio |= VT1724_REVO_CCLK; | ||
381 | snd_ice1712_gpio_write(ice, gpio); | ||
382 | udelay(1); | ||
383 | } | ||
384 | } | ||
385 | |||
386 | static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, | ||
387 | int idx) | ||
388 | { | ||
389 | unsigned char data = 0; | ||
390 | |||
391 | for (; idx >= 0; idx--) { | ||
392 | /* drop clock */ | ||
393 | gpio &= ~VT1724_REVO_CCLK; | ||
394 | snd_ice1712_gpio_write(ice, gpio); | ||
395 | udelay(1); | ||
396 | /* read data */ | ||
397 | if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN) | ||
398 | data |= (1 << idx); | ||
399 | udelay(1); | ||
400 | /* raise clock */ | ||
401 | gpio |= VT1724_REVO_CCLK; | ||
402 | snd_ice1712_gpio_write(ice, gpio); | ||
403 | udelay(1); | ||
404 | } | ||
405 | return data; | ||
406 | } | ||
407 | |||
408 | static unsigned char ap192_4wire_start(struct snd_ice1712 *ice) | ||
409 | { | ||
410 | unsigned int tmp; | ||
411 | |||
412 | snd_ice1712_save_gpio_status(ice); | ||
413 | tmp = snd_ice1712_gpio_read(ice); | ||
414 | tmp |= VT1724_REVO_CCLK; /* high at init */ | ||
415 | tmp |= VT1724_REVO_CS0; | ||
416 | tmp &= ~VT1724_REVO_CS3; | ||
417 | snd_ice1712_gpio_write(ice, tmp); | ||
418 | udelay(1); | ||
419 | return tmp; | ||
420 | } | ||
421 | |||
422 | static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) | ||
423 | { | ||
424 | tmp |= VT1724_REVO_CS3; | ||
425 | tmp |= VT1724_REVO_CS0; | ||
426 | snd_ice1712_gpio_write(ice, tmp); | ||
427 | udelay(1); | ||
428 | snd_ice1712_restore_gpio_status(ice); | ||
429 | } | ||
430 | |||
431 | static void ap192_ak4114_write(void *private_data, unsigned char addr, | ||
432 | unsigned char data) | ||
433 | { | ||
434 | struct snd_ice1712 *ice = private_data; | ||
435 | unsigned int tmp, addrdata; | ||
436 | |||
437 | tmp = ap192_4wire_start(ice); | ||
438 | addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); | ||
439 | addrdata = (addrdata << 8) | data; | ||
440 | write_data(ice, tmp, addrdata, 15); | ||
441 | ap192_4wire_finish(ice, tmp); | ||
442 | } | ||
443 | |||
444 | static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) | ||
445 | { | ||
446 | struct snd_ice1712 *ice = private_data; | ||
447 | unsigned int tmp; | ||
448 | unsigned char data; | ||
449 | |||
450 | tmp = ap192_4wire_start(ice); | ||
451 | write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); | ||
452 | data = read_data(ice, tmp, 7); | ||
453 | ap192_4wire_finish(ice, tmp); | ||
454 | return data; | ||
455 | } | ||
456 | |||
457 | static int ap192_ak4114_init(struct snd_ice1712 *ice) | ||
458 | { | ||
459 | static unsigned char ak4114_init_vals[] = { | ||
460 | AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, | ||
461 | AK4114_DIF_I24I2S, | ||
462 | AK4114_TX1E, | ||
463 | AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1), | ||
464 | 0, | ||
465 | 0 | ||
466 | }; | ||
467 | static unsigned char ak4114_init_txcsb[] = { | ||
468 | 0x41, 0x02, 0x2c, 0x00, 0x00 | ||
469 | }; | ||
470 | struct ak4114 *ak; | ||
471 | int err; | ||
472 | |||
473 | return snd_ak4114_create(ice->card, | ||
474 | ap192_ak4114_read, | ||
475 | ap192_ak4114_write, | ||
476 | ak4114_init_vals, ak4114_init_txcsb, | ||
477 | ice, &ak); | ||
478 | } | ||
479 | #endif /* BUILD_AK4114_AP192 */ | ||
480 | |||
306 | static int __devinit revo_init(struct snd_ice1712 *ice) | 481 | static int __devinit revo_init(struct snd_ice1712 *ice) |
307 | { | 482 | { |
308 | struct snd_akm4xxx *ak; | 483 | struct snd_akm4xxx *ak; |
@@ -319,6 +494,10 @@ static int __devinit revo_init(struct snd_ice1712 *ice) | |||
319 | ice->num_total_dacs = 6; | 494 | ice->num_total_dacs = 6; |
320 | ice->num_total_adcs = 2; | 495 | ice->num_total_adcs = 2; |
321 | break; | 496 | break; |
497 | case VT1724_SUBDEVICE_AUDIOPHILE192: | ||
498 | ice->num_total_dacs = 2; | ||
499 | ice->num_total_adcs = 2; | ||
500 | break; | ||
322 | default: | 501 | default: |
323 | snd_BUG(); | 502 | snd_BUG(); |
324 | return -EINVAL; | 503 | return -EINVAL; |
@@ -356,6 +535,14 @@ static int __devinit revo_init(struct snd_ice1712 *ice) | |||
356 | snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, | 535 | snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, |
357 | VT1724_REVO_MUTE); | 536 | VT1724_REVO_MUTE); |
358 | break; | 537 | break; |
538 | case VT1724_SUBDEVICE_AUDIOPHILE192: | ||
539 | ice->akm_codecs = 1; | ||
540 | err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv, | ||
541 | ice); | ||
542 | if (err < 0) | ||
543 | return err; | ||
544 | |||
545 | break; | ||
359 | } | 546 | } |
360 | 547 | ||
361 | return 0; | 548 | return 0; |
@@ -380,6 +567,16 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice) | |||
380 | if (err < 0) | 567 | if (err < 0) |
381 | return err; | 568 | return err; |
382 | break; | 569 | break; |
570 | case VT1724_SUBDEVICE_AUDIOPHILE192: | ||
571 | err = snd_ice1712_akm4xxx_build_controls(ice); | ||
572 | if (err < 0) | ||
573 | return err; | ||
574 | #ifdef BUILD_AK4114_AP192 | ||
575 | err = ap192_ak4114_init(ice); | ||
576 | if (err < 0) | ||
577 | return err; | ||
578 | #endif | ||
579 | break; | ||
383 | } | 580 | } |
384 | return 0; | 581 | return 0; |
385 | } | 582 | } |
@@ -400,5 +597,12 @@ struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { | |||
400 | .chip_init = revo_init, | 597 | .chip_init = revo_init, |
401 | .build_controls = revo_add_controls, | 598 | .build_controls = revo_add_controls, |
402 | }, | 599 | }, |
600 | { | ||
601 | .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192, | ||
602 | .name = "M Audio Audiophile192", | ||
603 | .model = "ap192", | ||
604 | .chip_init = revo_init, | ||
605 | .build_controls = revo_add_controls, | ||
606 | }, | ||
403 | { } /* terminator */ | 607 | { } /* terminator */ |
404 | }; | 608 | }; |
diff --git a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h index c70adaf017c1..a3ba425911cc 100644 --- a/sound/pci/ice1712/revo.h +++ b/sound/pci/ice1712/revo.h | |||
@@ -26,10 +26,12 @@ | |||
26 | 26 | ||
27 | #define REVO_DEVICE_DESC \ | 27 | #define REVO_DEVICE_DESC \ |
28 | "{MidiMan M Audio,Revolution 7.1},"\ | 28 | "{MidiMan M Audio,Revolution 7.1},"\ |
29 | "{MidiMan M Audio,Revolution 5.1}," | 29 | "{MidiMan M Audio,Revolution 5.1},"\ |
30 | "{MidiMan M Audio,Audiophile 192}," | ||
30 | 31 | ||
31 | #define VT1724_SUBDEVICE_REVOLUTION71 0x12143036 | 32 | #define VT1724_SUBDEVICE_REVOLUTION71 0x12143036 |
32 | #define VT1724_SUBDEVICE_REVOLUTION51 0x12143136 | 33 | #define VT1724_SUBDEVICE_REVOLUTION51 0x12143136 |
34 | #define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236 | ||
33 | 35 | ||
34 | /* entry point */ | 36 | /* entry point */ |
35 | extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; | 37 | extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; |
@@ -47,6 +49,7 @@ extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; | |||
47 | #define VT1724_REVO_CS2 0x40 /* surround AKM4355 CS (revo71) */ | 49 | #define VT1724_REVO_CS2 0x40 /* surround AKM4355 CS (revo71) */ |
48 | #define VT1724_REVO_I2C_DATA 0x40 /* I2C: PT 2258 SDA (on revo51) */ | 50 | #define VT1724_REVO_I2C_DATA 0x40 /* I2C: PT 2258 SDA (on revo51) */ |
49 | #define VT1724_REVO_I2C_CLOCK 0x80 /* I2C: PT 2258 SCL (on revo51) */ | 51 | #define VT1724_REVO_I2C_CLOCK 0x80 /* I2C: PT 2258 SCL (on revo51) */ |
52 | #define VT1724_REVO_CS3 0x80 /* AK4114 for AP192 */ | ||
50 | #define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */ | 53 | #define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */ |
51 | 54 | ||
52 | #endif /* __SOUND_REVO_H */ | 55 | #endif /* __SOUND_REVO_H */ |