diff options
Diffstat (limited to 'sound/pci/ice1712/prodigy192.c')
-rw-r--r-- | sound/pci/ice1712/prodigy192.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index 733937807da3..48cf40a8f32a 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c | |||
@@ -67,6 +67,12 @@ | |||
67 | #include "stac946x.h" | 67 | #include "stac946x.h" |
68 | #include <sound/tlv.h> | 68 | #include <sound/tlv.h> |
69 | 69 | ||
70 | struct prodigy192_spec { | ||
71 | struct ak4114 *ak4114; | ||
72 | /* rate change needs atomic mute/unmute of all dacs*/ | ||
73 | struct mutex mute_mutex; | ||
74 | }; | ||
75 | |||
70 | static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val) | 76 | static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val) |
71 | { | 77 | { |
72 | snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val); | 78 | snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val); |
@@ -118,6 +124,7 @@ static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
118 | static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 124 | static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
119 | { | 125 | { |
120 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 126 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
127 | struct prodigy192_spec *spec = ice->spec; | ||
121 | int idx, change; | 128 | int idx, change; |
122 | 129 | ||
123 | if (kcontrol->private_value) | 130 | if (kcontrol->private_value) |
@@ -125,11 +132,11 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
125 | else | 132 | else |
126 | idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; | 133 | idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; |
127 | /* due to possible conflicts with stac9460_set_rate_val, mutexing */ | 134 | /* due to possible conflicts with stac9460_set_rate_val, mutexing */ |
128 | mutex_lock(&ice->spec.prodigy192.mute_mutex); | 135 | mutex_lock(&spec->mute_mutex); |
129 | /*printk("Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx, | 136 | /*printk("Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx, |
130 | ucontrol->value.integer.value[0]);*/ | 137 | ucontrol->value.integer.value[0]);*/ |
131 | change = stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]); | 138 | change = stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]); |
132 | mutex_unlock(&ice->spec.prodigy192.mute_mutex); | 139 | mutex_unlock(&spec->mute_mutex); |
133 | return change; | 140 | return change; |
134 | } | 141 | } |
135 | 142 | ||
@@ -318,6 +325,7 @@ static void stac9460_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | |||
318 | int idx; | 325 | int idx; |
319 | unsigned char changed[7]; | 326 | unsigned char changed[7]; |
320 | struct snd_ice1712 *ice = ak->private_data[0]; | 327 | struct snd_ice1712 *ice = ak->private_data[0]; |
328 | struct prodigy192_spec *spec = ice->spec; | ||
321 | 329 | ||
322 | if (rate == 0) /* no hint - S/PDIF input is master, simply return */ | 330 | if (rate == 0) /* no hint - S/PDIF input is master, simply return */ |
323 | return; | 331 | return; |
@@ -332,7 +340,7 @@ static void stac9460_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | |||
332 | return; | 340 | return; |
333 | /* change detected, setting master clock, muting first */ | 341 | /* change detected, setting master clock, muting first */ |
334 | /* due to possible conflicts with mute controls - mutexing */ | 342 | /* due to possible conflicts with mute controls - mutexing */ |
335 | mutex_lock(&ice->spec.prodigy192.mute_mutex); | 343 | mutex_lock(&spec->mute_mutex); |
336 | /* we have to remember current mute status for each DAC */ | 344 | /* we have to remember current mute status for each DAC */ |
337 | for (idx = 0; idx < 7 ; ++idx) | 345 | for (idx = 0; idx < 7 ; ++idx) |
338 | changed[idx] = stac9460_dac_mute(ice, | 346 | changed[idx] = stac9460_dac_mute(ice, |
@@ -346,7 +354,7 @@ static void stac9460_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | |||
346 | if (changed[idx]) | 354 | if (changed[idx]) |
347 | stac9460_dac_mute(ice, STAC946X_MASTER_VOLUME + idx, 1); | 355 | stac9460_dac_mute(ice, STAC946X_MASTER_VOLUME + idx, 1); |
348 | } | 356 | } |
349 | mutex_unlock(&ice->spec.prodigy192.mute_mutex); | 357 | mutex_unlock(&spec->mute_mutex); |
350 | } | 358 | } |
351 | 359 | ||
352 | /* using akm infrastructure for setting rate of the codec */ | 360 | /* using akm infrastructure for setting rate of the codec */ |
@@ -633,12 +641,13 @@ static int prodigy192_ak4114_init(struct snd_ice1712 *ice) | |||
633 | static const unsigned char ak4114_init_txcsb[] = { | 641 | static const unsigned char ak4114_init_txcsb[] = { |
634 | 0x41, 0x02, 0x2c, 0x00, 0x00 | 642 | 0x41, 0x02, 0x2c, 0x00, 0x00 |
635 | }; | 643 | }; |
644 | struct prodigy192_spec *spec = ice->spec; | ||
636 | 645 | ||
637 | return snd_ak4114_create(ice->card, | 646 | return snd_ak4114_create(ice->card, |
638 | prodigy192_ak4114_read, | 647 | prodigy192_ak4114_read, |
639 | prodigy192_ak4114_write, | 648 | prodigy192_ak4114_write, |
640 | ak4114_init_vals, ak4114_init_txcsb, | 649 | ak4114_init_vals, ak4114_init_txcsb, |
641 | ice, &ice->spec.prodigy192.ak4114); | 650 | ice, &spec->ak4114); |
642 | } | 651 | } |
643 | 652 | ||
644 | static void stac9460_proc_regs_read(struct snd_info_entry *entry, | 653 | static void stac9460_proc_regs_read(struct snd_info_entry *entry, |
@@ -664,6 +673,7 @@ static void stac9460_proc_init(struct snd_ice1712 *ice) | |||
664 | 673 | ||
665 | static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) | 674 | static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) |
666 | { | 675 | { |
676 | struct prodigy192_spec *spec = ice->spec; | ||
667 | unsigned int i; | 677 | unsigned int i; |
668 | int err; | 678 | int err; |
669 | 679 | ||
@@ -673,7 +683,7 @@ static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) | |||
673 | if (err < 0) | 683 | if (err < 0) |
674 | return err; | 684 | return err; |
675 | } | 685 | } |
676 | if (ice->spec.prodigy192.ak4114) { | 686 | if (spec->ak4114) { |
677 | /* ak4114 is connected */ | 687 | /* ak4114 is connected */ |
678 | for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) { | 688 | for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) { |
679 | err = snd_ctl_add(ice->card, | 689 | err = snd_ctl_add(ice->card, |
@@ -682,7 +692,7 @@ static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) | |||
682 | if (err < 0) | 692 | if (err < 0) |
683 | return err; | 693 | return err; |
684 | } | 694 | } |
685 | err = snd_ak4114_build(ice->spec.prodigy192.ak4114, | 695 | err = snd_ak4114_build(spec->ak4114, |
686 | NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */ | 696 | NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */ |
687 | ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); | 697 | ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); |
688 | if (err < 0) | 698 | if (err < 0) |
@@ -734,12 +744,19 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) | |||
734 | const unsigned short *p; | 744 | const unsigned short *p; |
735 | int err = 0; | 745 | int err = 0; |
736 | struct snd_akm4xxx *ak; | 746 | struct snd_akm4xxx *ak; |
747 | struct prodigy192_spec *spec; | ||
737 | 748 | ||
738 | /* prodigy 192 */ | 749 | /* prodigy 192 */ |
739 | ice->num_total_dacs = 6; | 750 | ice->num_total_dacs = 6; |
740 | ice->num_total_adcs = 2; | 751 | ice->num_total_adcs = 2; |
741 | ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */ | 752 | ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */ |
742 | 753 | ||
754 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
755 | if (!spec) | ||
756 | return -ENOMEM; | ||
757 | ice->spec = spec; | ||
758 | mutex_init(&spec->mute_mutex); | ||
759 | |||
743 | /* initialize codec */ | 760 | /* initialize codec */ |
744 | p = stac_inits_prodigy; | 761 | p = stac_inits_prodigy; |
745 | for (; *p != (unsigned short)-1; p += 2) | 762 | for (; *p != (unsigned short)-1; p += 2) |
@@ -758,7 +775,7 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) | |||
758 | if (prodigy192_miodio_exists(ice)) { | 775 | if (prodigy192_miodio_exists(ice)) { |
759 | err = prodigy192_ak4114_init(ice); | 776 | err = prodigy192_ak4114_init(ice); |
760 | /* from this moment if err = 0 then | 777 | /* from this moment if err = 0 then |
761 | * ice->spec.prodigy192.ak4114 should not be null | 778 | * spec->ak4114 should not be null |
762 | */ | 779 | */ |
763 | snd_printdd("AK4114 initialized with status %d\n", err); | 780 | snd_printdd("AK4114 initialized with status %d\n", err); |
764 | } else | 781 | } else |
@@ -766,8 +783,6 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) | |||
766 | if (err < 0) | 783 | if (err < 0) |
767 | return err; | 784 | return err; |
768 | 785 | ||
769 | mutex_init(&ice->spec.prodigy192.mute_mutex); | ||
770 | |||
771 | return 0; | 786 | return 0; |
772 | } | 787 | } |
773 | 788 | ||