aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_codec.h3
-rw-r--r--sound/pci/hda/hda_intel.c6
-rw-r--r--sound/pci/hda/patch_cmedia.c5
-rw-r--r--sound/pci/hda/patch_realtek.c28
-rw-r--r--sound/pci/hda/patch_sigmatel.c812
5 files changed, 608 insertions, 246 deletions
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 59991560d492..dd0d99d2ad27 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -262,6 +262,9 @@ enum {
262#define AC_PINCTL_OUT_EN (1<<6) 262#define AC_PINCTL_OUT_EN (1<<6)
263#define AC_PINCTL_HP_EN (1<<7) 263#define AC_PINCTL_HP_EN (1<<7)
264 264
265/* Unsolicited response - 8bit */
266#define AC_USRSP_EN (1<<7)
267
265/* configuration default - 32bit */ 268/* configuration default - 32bit */
266#define AC_DEFCFG_SEQUENCE (0xf<<0) 269#define AC_DEFCFG_SEQUENCE (0xf<<0)
267#define AC_DEFCFG_DEF_ASSOC (0xf<<4) 270#define AC_DEFCFG_DEF_ASSOC (0xf<<4)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 5e0cca36ed57..288ab0764830 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -178,6 +178,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
178#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */ 178#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */
179#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */ 179#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */
180 180
181/* GCTL unsolicited response enable bit */
182#define ICH6_GCTL_UREN (1<<8)
183
181/* GCTL reset bit */ 184/* GCTL reset bit */
182#define ICH6_GCTL_RESET (1<<0) 185#define ICH6_GCTL_RESET (1<<0)
183 186
@@ -562,6 +565,9 @@ static int azx_reset(azx_t *chip)
562 return -EBUSY; 565 return -EBUSY;
563 } 566 }
564 567
568 /* Accept unsolicited responses */
569 azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UREN);
570
565 /* detect codecs */ 571 /* detect codecs */
566 if (! chip->codec_mask) { 572 if (! chip->codec_mask) {
567 chip->codec_mask = azx_readw(chip, STATESTS); 573 chip->codec_mask = azx_readw(chip, STATESTS);
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 2d6e3e3d0a38..86f195f19eef 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -408,7 +408,7 @@ static int cmi9880_fill_multi_dac_nids(struct hda_codec *codec, const struct aut
408 /* search for an empty channel */ 408 /* search for an empty channel */
409 for (j = 0; j < cfg->line_outs; j++) { 409 for (j = 0; j < cfg->line_outs; j++) {
410 if (! assigned[j]) { 410 if (! assigned[j]) {
411 spec->dac_nids[i] = i + 0x03; 411 spec->dac_nids[i] = j + 0x03;
412 assigned[j] = 1; 412 assigned[j] = 1;
413 break; 413 break;
414 } 414 }
@@ -444,11 +444,10 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pi
444 len = snd_hda_get_connections(codec, nid, conn, 4); 444 len = snd_hda_get_connections(codec, nid, conn, 4);
445 for (k = 0; k < len; k++) 445 for (k = 0; k < len; k++)
446 if (conn[k] == spec->dac_nids[i]) { 446 if (conn[k] == spec->dac_nids[i]) {
447 spec->multi_init[j].param = j; 447 spec->multi_init[j].param = k;
448 break; 448 break;
449 } 449 }
450 j++; 450 j++;
451 break;
452 } 451 }
453 } 452 }
454 return 0; 453 return 0;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index bab89843d850..9b8569900787 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -40,6 +40,7 @@ enum {
40 ALC880_W810, 40 ALC880_W810,
41 ALC880_Z71V, 41 ALC880_Z71V,
42 ALC880_AUTO, 42 ALC880_AUTO,
43 ALC880_6ST,
43 ALC880_6ST_DIG, 44 ALC880_6ST_DIG,
44 ALC880_F1734, 45 ALC880_F1734,
45 ALC880_ASUS, 46 ALC880_ASUS,
@@ -119,6 +120,7 @@ struct alc_spec {
119 unsigned int num_kctl_alloc, num_kctl_used; 120 unsigned int num_kctl_alloc, num_kctl_used;
120 snd_kcontrol_new_t *kctl_alloc; 121 snd_kcontrol_new_t *kctl_alloc;
121 struct hda_input_mux private_imux; 122 struct hda_input_mux private_imux;
123 hda_nid_t private_dac_nids[4];
122}; 124};
123 125
124 126
@@ -1547,9 +1549,10 @@ static struct hda_board_config alc880_cfg_tbl[] = {
1547 { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, 1549 { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
1548 { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, 1550 { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
1549 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG }, 1551 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG },
1550 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, 1552 /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */
1551 { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG }, 1553 { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG },
1552 { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, 1554 /* note subvendor = 0 below */
1555 /* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */
1553 1556
1554 { .modelname = "w810", .config = ALC880_W810 }, 1557 { .modelname = "w810", .config = ALC880_W810 },
1555 { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 }, 1558 { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
@@ -1557,7 +1560,10 @@ static struct hda_board_config alc880_cfg_tbl[] = {
1557 { .modelname = "z71v", .config = ALC880_Z71V }, 1560 { .modelname = "z71v", .config = ALC880_Z71V },
1558 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V }, 1561 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
1559 1562
1560 { .modelname = "6statack-digout", .config = ALC880_6ST_DIG }, 1563 { .modelname = "6stack", .config = ALC880_6ST },
1564 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */
1565
1566 { .modelname = "6stack-digout", .config = ALC880_6ST_DIG },
1561 { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG }, 1567 { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG },
1562 { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG }, 1568 { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG },
1563 { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG }, 1569 { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG },
@@ -1644,6 +1650,15 @@ static struct alc_config_preset alc880_presets[] = {
1644 .channel_mode = alc880_fivestack_modes, 1650 .channel_mode = alc880_fivestack_modes,
1645 .input_mux = &alc880_capture_source, 1651 .input_mux = &alc880_capture_source,
1646 }, 1652 },
1653 [ALC880_6ST] = {
1654 .mixers = { alc880_six_stack_mixer },
1655 .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
1656 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1657 .dac_nids = alc880_6st_dac_nids,
1658 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1659 .channel_mode = alc880_sixstack_modes,
1660 .input_mux = &alc880_6stack_capture_source,
1661 },
1647 [ALC880_6ST_DIG] = { 1662 [ALC880_6ST_DIG] = {
1648 .mixers = { alc880_six_stack_mixer }, 1663 .mixers = { alc880_six_stack_mixer },
1649 .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, 1664 .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
@@ -1656,7 +1671,8 @@ static struct alc_config_preset alc880_presets[] = {
1656 }, 1671 },
1657 [ALC880_W810] = { 1672 [ALC880_W810] = {
1658 .mixers = { alc880_w810_base_mixer }, 1673 .mixers = { alc880_w810_base_mixer },
1659 .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs }, 1674 .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs,
1675 alc880_gpio2_init_verbs },
1660 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 1676 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
1661 .dac_nids = alc880_w810_dac_nids, 1677 .dac_nids = alc880_w810_dac_nids,
1662 .dig_out_nid = ALC880_DIGOUT_NID, 1678 .dig_out_nid = ALC880_DIGOUT_NID,
@@ -1666,8 +1682,7 @@ static struct alc_config_preset alc880_presets[] = {
1666 }, 1682 },
1667 [ALC880_Z71V] = { 1683 [ALC880_Z71V] = {
1668 .mixers = { alc880_z71v_mixer }, 1684 .mixers = { alc880_z71v_mixer },
1669 .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs, 1685 .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs },
1670 alc880_gpio2_init_verbs },
1671 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 1686 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
1672 .dac_nids = alc880_z71v_dac_nids, 1687 .dac_nids = alc880_z71v_dac_nids,
1673 .dig_out_nid = ALC880_DIGOUT_NID, 1688 .dig_out_nid = ALC880_DIGOUT_NID,
@@ -1809,6 +1824,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pi
1809 int i, j; 1824 int i, j;
1810 1825
1811 memset(assigned, 0, sizeof(assigned)); 1826 memset(assigned, 0, sizeof(assigned));
1827 spec->multiout.dac_nids = spec->private_dac_nids;
1812 1828
1813 /* check the pins hardwired to audio widget */ 1829 /* check the pins hardwired to audio widget */
1814 for (i = 0; i < cfg->line_outs; i++) { 1830 for (i = 0; i < cfg->line_outs; i++) {
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 013be2ea513a..9d503da7320d 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -30,32 +30,37 @@
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/pci.h> 31#include <linux/pci.h>
32#include <sound/core.h> 32#include <sound/core.h>
33#include <sound/asoundef.h>
33#include "hda_codec.h" 34#include "hda_codec.h"
34#include "hda_local.h" 35#include "hda_local.h"
35 36
36#undef STAC_TEST 37#undef STAC_TEST
37 38
39#define NUM_CONTROL_ALLOC 32
40#define STAC_HP_EVENT 0x37
41#define STAC_UNSOL_ENABLE (AC_USRSP_EN | STAC_HP_EVENT)
42
38struct sigmatel_spec { 43struct sigmatel_spec {
44 snd_kcontrol_new_t *mixers[4];
45 unsigned int num_mixers;
46
47 unsigned int surr_switch: 1;
48
39 /* playback */ 49 /* playback */
40 struct hda_multi_out multiout; 50 struct hda_multi_out multiout;
41 hda_nid_t playback_nid; 51 hda_nid_t dac_nids[4];
42 52
43 /* capture */ 53 /* capture */
44 hda_nid_t *adc_nids; 54 hda_nid_t *adc_nids;
45 unsigned int num_adcs; 55 unsigned int num_adcs;
46 hda_nid_t *mux_nids; 56 hda_nid_t *mux_nids;
47 unsigned int num_muxes; 57 unsigned int num_muxes;
48 hda_nid_t capture_nid;
49 hda_nid_t dig_in_nid; 58 hda_nid_t dig_in_nid;
50 59
51 /* power management*/ 60#ifdef STAC_TEST
52 hda_nid_t *pstate_nids;
53 unsigned int num_pstates;
54
55 /* pin widgets */ 61 /* pin widgets */
56 hda_nid_t *pin_nids; 62 hda_nid_t *pin_nids;
57 unsigned int num_pins; 63 unsigned int num_pins;
58#ifdef STAC_TEST
59 unsigned int *pin_configs; 64 unsigned int *pin_configs;
60#endif 65#endif
61 66
@@ -64,16 +69,20 @@ struct sigmatel_spec {
64 snd_kcontrol_new_t *mixer; 69 snd_kcontrol_new_t *mixer;
65 70
66 /* capture source */ 71 /* capture source */
67 struct hda_input_mux input_mux; 72 struct hda_input_mux *input_mux;
68 char input_labels[HDA_MAX_NUM_INPUTS][16];
69 unsigned int cur_mux[2]; 73 unsigned int cur_mux[2];
70 74
71 /* channel mode */ 75 /* channel mode */
72 unsigned int num_ch_modes; 76 unsigned int num_ch_modes;
73 unsigned int cur_ch_mode; 77 unsigned int cur_ch_mode;
74 const struct sigmatel_channel_mode *channel_modes;
75 78
76 struct hda_pcm pcm_rec[1]; /* PCM information */ 79 struct hda_pcm pcm_rec[2]; /* PCM information */
80
81 /* dynamic controls and input_mux */
82 struct auto_pin_cfg autocfg;
83 unsigned int num_kctl_alloc, num_kctl_used;
84 snd_kcontrol_new_t *kctl_alloc;
85 struct hda_input_mux private_imux;
77}; 86};
78 87
79static hda_nid_t stac9200_adc_nids[1] = { 88static hda_nid_t stac9200_adc_nids[1] = {
@@ -88,14 +97,6 @@ static hda_nid_t stac9200_dac_nids[1] = {
88 0x02, 97 0x02,
89}; 98};
90 99
91static hda_nid_t stac9200_pstate_nids[3] = {
92 0x01, 0x02, 0x03,
93};
94
95static hda_nid_t stac9200_pin_nids[8] = {
96 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
97};
98
99static hda_nid_t stac922x_adc_nids[2] = { 100static hda_nid_t stac922x_adc_nids[2] = {
100 0x06, 0x07, 101 0x06, 0x07,
101}; 102};
@@ -104,24 +105,22 @@ static hda_nid_t stac922x_mux_nids[2] = {
104 0x12, 0x13, 105 0x12, 0x13,
105}; 106};
106 107
107static hda_nid_t stac922x_dac_nids[4] = { 108#ifdef STAC_TEST
108 0x02, 0x03, 0x04, 0x05, 109static hda_nid_t stac9200_pin_nids[8] = {
109}; 110 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
110
111static hda_nid_t stac922x_pstate_nids[8] = {
112 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x11,
113}; 111};
114 112
115static hda_nid_t stac922x_pin_nids[10] = { 113static hda_nid_t stac922x_pin_nids[10] = {
116 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 114 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
117 0x0f, 0x10, 0x11, 0x15, 0x1b, 115 0x0f, 0x10, 0x11, 0x15, 0x1b,
118}; 116};
117#endif
119 118
120static int stac92xx_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 119static int stac92xx_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
121{ 120{
122 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 121 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
123 struct sigmatel_spec *spec = codec->spec; 122 struct sigmatel_spec *spec = codec->spec;
124 return snd_hda_input_mux_info(&spec->input_mux, uinfo); 123 return snd_hda_input_mux_info(spec->input_mux, uinfo);
125} 124}
126 125
127static int stac92xx_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 126static int stac92xx_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
@@ -140,26 +139,64 @@ static int stac92xx_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
140 struct sigmatel_spec *spec = codec->spec; 139 struct sigmatel_spec *spec = codec->spec;
141 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 140 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
142 141
143 return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol, 142 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
144 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); 143 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
145} 144}
146 145
147static struct hda_verb stac9200_ch2_init[] = { 146static struct hda_verb stac9200_core_init[] = {
148 /* set dac0mux for dac converter */ 147 /* set dac0mux for dac converter */
149 { 0x07, 0x701, 0x00}, 148 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
150 {} 149 {}
151}; 150};
152 151
153static struct hda_verb stac922x_ch2_init[] = { 152static struct hda_verb stac922x_core_init[] = {
154 /* set master volume and direct control */ 153 /* set master volume and direct control */
155 { 0x16, 0x70f, 0xff}, 154 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
156 {} 155 {}
157}; 156};
158 157
159struct sigmatel_channel_mode { 158static int stac922x_channel_modes[3] = {2, 6, 8};
160 unsigned int channels; 159
161 const struct hda_verb *sequence; 160static int stac922x_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
162}; 161{
162 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
163 struct sigmatel_spec *spec = codec->spec;
164
165 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
166 uinfo->count = 1;
167 uinfo->value.enumerated.items = spec->num_ch_modes;
168 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
169 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
170 sprintf(uinfo->value.enumerated.name, "%dch",
171 stac922x_channel_modes[uinfo->value.enumerated.item]);
172 return 0;
173}
174
175static int stac922x_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
176{
177 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
178 struct sigmatel_spec *spec = codec->spec;
179
180 ucontrol->value.enumerated.item[0] = spec->cur_ch_mode;
181 return 0;
182}
183
184static int stac922x_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
185{
186 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
187 struct sigmatel_spec *spec = codec->spec;
188
189 if (ucontrol->value.enumerated.item[0] >= spec->num_ch_modes)
190 ucontrol->value.enumerated.item[0] = spec->num_ch_modes;
191 if (ucontrol->value.enumerated.item[0] == spec->cur_ch_mode &&
192 ! codec->in_resume)
193 return 0;
194
195 spec->cur_ch_mode = ucontrol->value.enumerated.item[0];
196 spec->multiout.max_channels = stac922x_channel_modes[spec->cur_ch_mode];
197
198 return 1;
199}
163 200
164static snd_kcontrol_new_t stac9200_mixer[] = { 201static snd_kcontrol_new_t stac9200_mixer[] = {
165 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), 202 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
@@ -174,13 +211,12 @@ static snd_kcontrol_new_t stac9200_mixer[] = {
174 }, 211 },
175 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), 212 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
176 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), 213 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
177 HDA_CODEC_VOLUME("Input Mux Volume", 0x0c, 0, HDA_OUTPUT), 214 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
178 { } /* end */ 215 { } /* end */
179}; 216};
180 217
218/* This needs to be generated dynamically based on sequence */
181static snd_kcontrol_new_t stac922x_mixer[] = { 219static snd_kcontrol_new_t stac922x_mixer[] = {
182 HDA_CODEC_VOLUME("PCM Playback Volume", 0x2, 0x0, HDA_OUTPUT),
183 HDA_CODEC_MUTE("PCM Playback Switch", 0x2, 0x0, HDA_OUTPUT),
184 { 220 {
185 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 221 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
186 .name = "Input Source", 222 .name = "Input Source",
@@ -195,14 +231,38 @@ static snd_kcontrol_new_t stac922x_mixer[] = {
195 { } /* end */ 231 { } /* end */
196}; 232};
197 233
234static snd_kcontrol_new_t stac922x_ch_mode_mixer[] = {
235 {
236 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
237 .name = "Channel Mode",
238 .info = stac922x_ch_mode_info,
239 .get = stac922x_ch_mode_get,
240 .put = stac922x_ch_mode_put,
241 },
242 { } /* end */
243};
244
198static int stac92xx_build_controls(struct hda_codec *codec) 245static int stac92xx_build_controls(struct hda_codec *codec)
199{ 246{
200 struct sigmatel_spec *spec = codec->spec; 247 struct sigmatel_spec *spec = codec->spec;
201 int err; 248 int err;
249 int i;
202 250
203 err = snd_hda_add_new_ctls(codec, spec->mixer); 251 err = snd_hda_add_new_ctls(codec, spec->mixer);
204 if (err < 0) 252 if (err < 0)
205 return err; 253 return err;
254
255 for (i = 0; i < spec->num_mixers; i++) {
256 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
257 if (err < 0)
258 return err;
259 }
260
261 if (spec->surr_switch) {
262 err = snd_hda_add_new_ctls(codec, stac922x_ch_mode_mixer);
263 if (err < 0)
264 return err;
265 }
206 if (spec->multiout.dig_out_nid) { 266 if (spec->multiout.dig_out_nid) {
207 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 267 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
208 if (err < 0) 268 if (err < 0)
@@ -222,9 +282,9 @@ static unsigned int stac9200_pin_configs[8] = {
222 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, 282 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
223}; 283};
224 284
225static unsigned int stac922x_pin_configs[14] = { 285static unsigned int stac922x_pin_configs[10] = {
226 0x40000100, 0x40000100, 0x40000100, 0x01114010, 286 0x01014010, 0x01014011, 0x01014012, 0x0221401f,
227 0x01813122, 0x40000100, 0x01447010, 0x01c47010, 287 0x01813122, 0x01014014, 0x01441030, 0x01c41030,
228 0x40000100, 0x40000100, 288 0x40000100, 0x40000100,
229}; 289};
230 290
@@ -255,180 +315,66 @@ static void stac92xx_set_config_regs(struct hda_codec *codec)
255} 315}
256#endif 316#endif
257 317
258static int stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, unsigned int value)
259{
260 unsigned int pin_ctl;
261
262 pin_ctl = snd_hda_codec_read(codec, nid, 0,
263 AC_VERB_GET_PIN_WIDGET_CONTROL,
264 0x00);
265 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
266 pin_ctl | value);
267
268 return 0;
269}
270
271static int stac92xx_set_vref(struct hda_codec *codec, hda_nid_t nid)
272{
273 unsigned int vref_caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) >> AC_PINCAP_VREF_SHIFT;
274 unsigned int vref_ctl = AC_PINCTL_VREF_HIZ;
275
276 if (vref_caps & AC_PINCAP_VREF_100)
277 vref_ctl = AC_PINCTL_VREF_100;
278 else if (vref_caps & AC_PINCAP_VREF_80)
279 vref_ctl = AC_PINCTL_VREF_80;
280 else if (vref_caps & AC_PINCAP_VREF_50)
281 vref_ctl = AC_PINCTL_VREF_50;
282 else if (vref_caps & AC_PINCAP_VREF_GRD)
283 vref_ctl = AC_PINCTL_VREF_GRD;
284
285 stac92xx_set_pinctl(codec, nid, vref_ctl);
286
287 return 0;
288}
289
290/* 318/*
291 * retrieve the default device type from the default config value 319 * Analog playback callbacks
292 */ 320 */
293#define get_defcfg_type(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) 321static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
294#define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) 322 struct hda_codec *codec,
295 323 snd_pcm_substream_t *substream)
296static int stac92xx_config_pin(struct hda_codec *codec, hda_nid_t nid, unsigned int pin_cfg)
297{ 324{
298 struct sigmatel_spec *spec = codec->spec; 325 struct sigmatel_spec *spec = codec->spec;
299 u32 location = get_defcfg_location(pin_cfg); 326 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
300 char *label;
301 const char *type = NULL;
302 int ainput = 0;
303
304 switch(get_defcfg_type(pin_cfg)) {
305 case AC_JACK_HP_OUT:
306 /* Enable HP amp */
307 stac92xx_set_pinctl(codec, nid, AC_PINCTL_HP_EN);
308 /* Fall through */
309 case AC_JACK_SPDIF_OUT:
310 case AC_JACK_LINE_OUT:
311 case AC_JACK_SPEAKER:
312 /* Enable output */
313 stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
314 break;
315 case AC_JACK_SPDIF_IN:
316 stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN);
317 break;
318 case AC_JACK_MIC_IN:
319 if ((location & 0x0f) == AC_JACK_LOC_FRONT)
320 type = "Front Mic";
321 else
322 type = "Mic";
323 ainput = 1;
324 /* Set vref */
325 stac92xx_set_vref(codec, nid);
326 stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN);
327 break;
328 case AC_JACK_CD:
329 type = "CD";
330 ainput = 1;
331 stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN);
332 break;
333 case AC_JACK_LINE_IN:
334 if ((location & 0x0f) == AC_JACK_LOC_FRONT)
335 type = "Front Line";
336 else
337 type = "Line";
338 ainput = 1;
339 stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN);
340 break;
341 case AC_JACK_AUX:
342 if ((location & 0x0f) == AC_JACK_LOC_FRONT)
343 type = "Front Aux";
344 else
345 type = "Aux";
346 ainput = 1;
347 stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN);
348 break;
349 }
350
351 if (ainput) {
352 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
353 int i, j, num_cons, index = -1;
354 if (!type)
355 type = "Input";
356 label = spec->input_labels[spec->input_mux.num_items];
357 strcpy(label, type);
358 spec->input_mux.items[spec->input_mux.num_items].label = label;
359 for (i=0; i<spec->num_muxes; i++) {
360 num_cons = snd_hda_get_connections(codec, spec->mux_nids[i], con_lst, HDA_MAX_NUM_INPUTS);
361 for (j=0; j<num_cons; j++)
362 if (con_lst[j] == nid) {
363 index = j;
364 break;
365 }
366 if (index >= 0)
367 break;
368 }
369 spec->input_mux.items[spec->input_mux.num_items].index = index;
370 spec->input_mux.num_items++;
371 }
372
373 return 0;
374} 327}
375 328
376static int stac92xx_config_pins(struct hda_codec *codec) 329/*
330 * set up the i/o for analog out
331 * when the digital out is available, copy the front out to digital out, too.
332 */
333static int stac92xx_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
334 unsigned int stream_tag,
335 unsigned int format,
336 snd_pcm_substream_t *substream)
377{ 337{
378 struct sigmatel_spec *spec = codec->spec; 338 hda_nid_t *nids = mout->dac_nids;
339 int chs = substream->runtime->channels;
379 int i; 340 int i;
380 unsigned int pin_cfg;
381 341
382 for (i=0; i < spec->num_pins; i++) { 342 down(&codec->spdif_mutex);
383 /* Default to disabled */ 343 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
384 snd_hda_codec_write(codec, spec->pin_nids[i], 0, 344 if (chs == 2 &&
385 AC_VERB_SET_PIN_WIDGET_CONTROL, 345 snd_hda_is_supported_format(codec, mout->dig_out_nid, format) &&
386 0x00); 346 ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) {
387 347 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
388 pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0, 348 /* setup digital receiver */
389 AC_VERB_GET_CONFIG_DEFAULT, 349 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
390 0x00); 350 stream_tag, 0, format);
391 if (((pin_cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) == AC_JACK_PORT_NONE) 351 } else {
392 continue; /* Move on */ 352 mout->dig_out_used = 0;
393 353 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
394 stac92xx_config_pin(codec, spec->pin_nids[i], pin_cfg); 354 }
395 } 355 }
396 356 up(&codec->spdif_mutex);
397 return 0; 357
398} 358 /* front */
399 359 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format);
400static int stac92xx_init(struct hda_codec *codec) 360 if (mout->hp_nid)
401{ 361 /* headphone out will just decode front left/right (stereo) */
402 struct sigmatel_spec *spec = codec->spec; 362 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
403 int i; 363 /* surrounds */
404 364 if (mout->max_channels > 2)
405 for (i=0; i < spec->num_pstates; i++) 365 for (i = 1; i < mout->num_dacs; i++) {
406 snd_hda_codec_write(codec, spec->pstate_nids[i], 0, 366 if ((mout->max_channels == 6) && (i == 3))
407 AC_VERB_SET_POWER_STATE, 0x00); 367 break;
408 368 if (chs >= (i + 1) * 2) /* independent out */
409 mdelay(100); 369 snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2,
410 370 format);
411 snd_hda_sequence_write(codec, spec->init); 371 else /* copy front */
412 372 snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0,
413#ifdef STAC_TEST 373 format);
414 stac92xx_set_config_regs(codec); 374 }
415#endif
416
417 stac92xx_config_pins(codec);
418
419 return 0; 375 return 0;
420} 376}
421 377
422/*
423 * Analog playback callbacks
424 */
425static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
426 struct hda_codec *codec,
427 snd_pcm_substream_t *substream)
428{
429 struct sigmatel_spec *spec = codec->spec;
430 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
431}
432 378
433static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 379static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
434 struct hda_codec *codec, 380 struct hda_codec *codec,
@@ -437,7 +383,7 @@ static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
437 snd_pcm_substream_t *substream) 383 snd_pcm_substream_t *substream)
438{ 384{
439 struct sigmatel_spec *spec = codec->spec; 385 struct sigmatel_spec *spec = codec->spec;
440 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, 386 return stac92xx_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
441 format, substream); 387 format, substream);
442} 388}
443 389
@@ -516,7 +462,7 @@ static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
516static struct hda_pcm_stream stac92xx_pcm_analog_playback = { 462static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
517 .substreams = 1, 463 .substreams = 1,
518 .channels_min = 2, 464 .channels_min = 2,
519 .channels_max = 2, 465 .channels_max = 8,
520 .nid = 0x02, /* NID to query formats and rates */ 466 .nid = 0x02, /* NID to query formats and rates */
521 .ops = { 467 .ops = {
522 .open = stac92xx_playback_pcm_open, 468 .open = stac92xx_playback_pcm_open,
@@ -544,11 +490,9 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
544 codec->num_pcms = 1; 490 codec->num_pcms = 1;
545 codec->pcm_info = info; 491 codec->pcm_info = info;
546 492
547 info->name = "STAC92xx"; 493 info->name = "STAC92xx Analog";
548 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; 494 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
549 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->playback_nid;
550 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; 495 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
551 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->capture_nid;
552 496
553 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 497 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
554 codec->num_pcms++; 498 codec->num_pcms++;
@@ -567,21 +511,413 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
567 return 0; 511 return 0;
568} 512}
569 513
514enum {
515 STAC_CTL_WIDGET_VOL,
516 STAC_CTL_WIDGET_MUTE,
517};
518
519static snd_kcontrol_new_t stac92xx_control_templates[] = {
520 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
521 HDA_CODEC_MUTE(NULL, 0, 0, 0),
522};
523
524/* add dynamic controls */
525static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
526{
527 snd_kcontrol_new_t *knew;
528
529 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
530 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
531
532 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
533 if (! knew)
534 return -ENOMEM;
535 if (spec->kctl_alloc) {
536 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
537 kfree(spec->kctl_alloc);
538 }
539 spec->kctl_alloc = knew;
540 spec->num_kctl_alloc = num;
541 }
542
543 knew = &spec->kctl_alloc[spec->num_kctl_used];
544 *knew = stac92xx_control_templates[type];
545 knew->name = kstrdup(name, GFP_KERNEL);
546 if (! knew->name)
547 return -ENOMEM;
548 knew->private_value = val;
549 spec->num_kctl_used++;
550 return 0;
551}
552
553/* fill in the dac_nids table from the parsed pin configuration */
554static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
555{
556 struct sigmatel_spec *spec = codec->spec;
557 hda_nid_t nid;
558 int i;
559
560 /* check the pins hardwired to audio widget */
561 for (i = 0; i < cfg->line_outs; i++) {
562 nid = cfg->line_out_pins[i];
563 spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0,
564 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
565 }
566
567 spec->multiout.num_dacs = cfg->line_outs;
568
569 return 0;
570}
571
572/* add playback controls from the parsed DAC table */
573static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, const struct auto_pin_cfg *cfg)
574{
575 char name[32];
576 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
577 hda_nid_t nid;
578 int i, err;
579
580 for (i = 0; i < cfg->line_outs; i++) {
581 if (! spec->multiout.dac_nids[i])
582 continue;
583
584 nid = spec->multiout.dac_nids[i];
585
586 if (i == 2) {
587 /* Center/LFE */
588 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Center Playback Volume",
589 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
590 return err;
591 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "LFE Playback Volume",
592 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
593 return err;
594 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Center Playback Switch",
595 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
596 return err;
597 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "LFE Playback Switch",
598 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
599 return err;
600 } else {
601 sprintf(name, "%s Playback Volume", chname[i]);
602 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
603 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
604 return err;
605 sprintf(name, "%s Playback Switch", chname[i]);
606 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
607 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
608 return err;
609 }
610 }
611
612 return 0;
613}
614
615/* add playback controls for HP output */
616static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin_cfg *cfg)
617{
618 struct sigmatel_spec *spec = codec->spec;
619 hda_nid_t pin = cfg->hp_pin;
620 hda_nid_t nid;
621 int i, err;
622 unsigned int wid_caps;
623
624 if (! pin)
625 return 0;
626
627 wid_caps = snd_hda_param_read(codec, pin, AC_PAR_AUDIO_WIDGET_CAP);
628 if (wid_caps & AC_WCAP_UNSOL_CAP)
629 /* Enable unsolicited responses on the HP widget */
630 snd_hda_codec_write(codec, pin, 0,
631 AC_VERB_SET_UNSOLICITED_ENABLE,
632 STAC_UNSOL_ENABLE);
633
634 nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
635 for (i = 0; i < cfg->line_outs; i++) {
636 if (! spec->multiout.dac_nids[i])
637 continue;
638 if (spec->multiout.dac_nids[i] == nid)
639 return 0;
640 }
641
642 spec->multiout.hp_nid = nid;
643
644 /* control HP volume/switch on the output mixer amp */
645 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Headphone Playback Volume",
646 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
647 return err;
648 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
649 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
650 return err;
651
652 return 0;
653}
654
655/* create playback/capture controls for input pins */
656static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
657{
658 struct sigmatel_spec *spec = codec->spec;
659 static char *labels[AUTO_PIN_LAST] = {
660 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
661 };
662 struct hda_input_mux *imux = &spec->private_imux;
663 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
664 int i, j, k;
665
666 for (i = 0; i < AUTO_PIN_LAST; i++) {
667 int index = -1;
668 if (cfg->input_pins[i]) {
669 imux->items[imux->num_items].label = labels[i];
670
671 for (j=0; j<spec->num_muxes; j++) {
672 int num_cons = snd_hda_get_connections(codec, spec->mux_nids[j], con_lst, HDA_MAX_NUM_INPUTS);
673 for (k=0; k<num_cons; k++)
674 if (con_lst[k] == cfg->input_pins[i]) {
675 index = k;
676 break;
677 }
678 if (index >= 0)
679 break;
680 }
681 imux->items[imux->num_items].index = index;
682 imux->num_items++;
683 }
684 }
685
686 return 0;
687}
688
689static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
690
691{
692 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
693}
694
695static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
696{
697 struct sigmatel_spec *spec = codec->spec;
698 int i;
699
700 for (i = 0; i < spec->autocfg.line_outs; i++) {
701 hda_nid_t nid = spec->autocfg.line_out_pins[i];
702 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
703 }
704}
705
706static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
707{
708 struct sigmatel_spec *spec = codec->spec;
709 hda_nid_t pin;
710
711 pin = spec->autocfg.hp_pin;
712 if (pin) /* connect to front */
713 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
714}
715
716static int stac922x_parse_auto_config(struct hda_codec *codec)
717{
718 struct sigmatel_spec *spec = codec->spec;
719 int err;
720
721 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0)
722 return err;
723 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
724 return err;
725 if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin)
726 return 0; /* can't find valid pin config */
727
728 if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
729 (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 ||
730 (err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
731 return err;
732
733 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
734 if (spec->multiout.max_channels > 2) {
735 spec->surr_switch = 1;
736 spec->cur_ch_mode = 1;
737 spec->num_ch_modes = 2;
738 if (spec->multiout.max_channels == 8) {
739 spec->cur_ch_mode++;
740 spec->num_ch_modes++;
741 }
742 }
743
744 if (spec->autocfg.dig_out_pin) {
745 spec->multiout.dig_out_nid = 0x08;
746 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN);
747 }
748 if (spec->autocfg.dig_in_pin) {
749 spec->dig_in_nid = 0x09;
750 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN);
751 }
752
753 if (spec->kctl_alloc)
754 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
755
756 spec->input_mux = &spec->private_imux;
757
758 return 1;
759}
760
761static int stac9200_parse_auto_config(struct hda_codec *codec)
762{
763 struct sigmatel_spec *spec = codec->spec;
764 int err;
765
766 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0)
767 return err;
768
769 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
770 return err;
771
772 if (spec->autocfg.dig_out_pin) {
773 spec->multiout.dig_out_nid = 0x05;
774 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN);
775 }
776 if (spec->autocfg.dig_in_pin) {
777 spec->dig_in_nid = 0x04;
778 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN);
779 }
780
781 if (spec->kctl_alloc)
782 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
783
784 spec->input_mux = &spec->private_imux;
785
786 return 1;
787}
788
789static int stac92xx_init_pstate(struct hda_codec *codec)
790{
791 hda_nid_t nid, nid_start;
792 int nodes;
793
794 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_POWER_STATE, 0x00);
795
796 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start);
797 for (nid = nid_start; nid < nodes + nid_start; nid++) {
798 unsigned int wid_caps = snd_hda_param_read(codec, nid,
799 AC_PAR_AUDIO_WIDGET_CAP);
800 if (wid_caps & AC_WCAP_POWER)
801 snd_hda_codec_write(codec, nid, 0,
802 AC_VERB_SET_POWER_STATE, 0x00);
803 }
804
805 mdelay(100);
806
807 return 0;
808}
809
810static int stac92xx_init(struct hda_codec *codec)
811{
812 struct sigmatel_spec *spec = codec->spec;
813
814 stac92xx_init_pstate(codec);
815
816 snd_hda_sequence_write(codec, spec->init);
817
818 stac92xx_auto_init_multi_out(codec);
819 stac92xx_auto_init_hp_out(codec);
820
821 return 0;
822}
823
570static void stac92xx_free(struct hda_codec *codec) 824static void stac92xx_free(struct hda_codec *codec)
571{ 825{
572 kfree(codec->spec); 826 struct sigmatel_spec *spec = codec->spec;
827 int i;
828
829 if (! spec)
830 return;
831
832 if (spec->kctl_alloc) {
833 for (i = 0; i < spec->num_kctl_used; i++)
834 kfree(spec->kctl_alloc[i].name);
835 kfree(spec->kctl_alloc);
836 }
837
838 kfree(spec);
839}
840
841static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
842 unsigned int flag)
843{
844 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
845 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
846 snd_hda_codec_write(codec, nid, 0,
847 AC_VERB_SET_PIN_WIDGET_CONTROL,
848 pin_ctl | flag);
849}
850
851static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
852 unsigned int flag)
853{
854 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
855 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
856 snd_hda_codec_write(codec, nid, 0,
857 AC_VERB_SET_PIN_WIDGET_CONTROL,
858 pin_ctl & ~flag);
859}
860
861static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
862{
863 struct sigmatel_spec *spec = codec->spec;
864 struct auto_pin_cfg *cfg = &spec->autocfg;
865 int i, presence;
866
867 if ((res >> 26) != STAC_HP_EVENT)
868 return;
869
870 presence = snd_hda_codec_read(codec, cfg->hp_pin, 0,
871 AC_VERB_GET_PIN_SENSE, 0x00) >> 31;
872
873 if (presence) {
874 /* disable lineouts, enable hp */
875 for (i = 0; i < cfg->line_outs; i++)
876 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
877 AC_PINCTL_OUT_EN);
878 stac92xx_set_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN);
879 } else {
880 /* enable lineouts, disable hp */
881 for (i = 0; i < cfg->line_outs; i++)
882 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
883 AC_PINCTL_OUT_EN);
884 stac92xx_reset_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN);
885 }
886}
887
888#ifdef CONFIG_PM
889static int stac92xx_resume(struct hda_codec *codec)
890{
891 struct sigmatel_spec *spec = codec->spec;
892 int i;
893
894 stac92xx_init(codec);
895 for (i = 0; i < spec->num_mixers; i++)
896 snd_hda_resume_ctls(codec, spec->mixers[i]);
897 if (spec->multiout.dig_out_nid)
898 snd_hda_resume_spdif_out(codec);
899 if (spec->dig_in_nid)
900 snd_hda_resume_spdif_in(codec);
901
902 return 0;
573} 903}
904#endif
574 905
575static struct hda_codec_ops stac92xx_patch_ops = { 906static struct hda_codec_ops stac92xx_patch_ops = {
576 .build_controls = stac92xx_build_controls, 907 .build_controls = stac92xx_build_controls,
577 .build_pcms = stac92xx_build_pcms, 908 .build_pcms = stac92xx_build_pcms,
578 .init = stac92xx_init, 909 .init = stac92xx_init,
579 .free = stac92xx_free, 910 .free = stac92xx_free,
911 .unsol_event = stac92xx_unsol_event,
912#ifdef CONFIG_PM
913 .resume = stac92xx_resume,
914#endif
580}; 915};
581 916
582static int patch_stac9200(struct hda_codec *codec) 917static int patch_stac9200(struct hda_codec *codec)
583{ 918{
584 struct sigmatel_spec *spec; 919 struct sigmatel_spec *spec;
920 int err;
585 921
586 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 922 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
587 if (spec == NULL) 923 if (spec == NULL)
@@ -589,26 +925,27 @@ static int patch_stac9200(struct hda_codec *codec)
589 925
590 codec->spec = spec; 926 codec->spec = spec;
591 927
928#ifdef STAC_TEST
929 spec->pin_nids = stac9200_pin_nids;
930 spec->num_pins = 8;
931 spec->pin_configs = stac9200_pin_configs;
932 stac92xx_set_config_regs(codec);
933#endif
592 spec->multiout.max_channels = 2; 934 spec->multiout.max_channels = 2;
593 spec->multiout.num_dacs = 1; 935 spec->multiout.num_dacs = 1;
594 spec->multiout.dac_nids = stac9200_dac_nids; 936 spec->multiout.dac_nids = stac9200_dac_nids;
595 spec->multiout.dig_out_nid = 0x05;
596 spec->dig_in_nid = 0x04;
597 spec->adc_nids = stac9200_adc_nids; 937 spec->adc_nids = stac9200_adc_nids;
598 spec->mux_nids = stac9200_mux_nids; 938 spec->mux_nids = stac9200_mux_nids;
599 spec->num_muxes = 1; 939 spec->num_muxes = 1;
600 spec->input_mux.num_items = 0; 940
601 spec->pstate_nids = stac9200_pstate_nids; 941 spec->init = stac9200_core_init;
602 spec->num_pstates = 3;
603 spec->pin_nids = stac9200_pin_nids;
604#ifdef STAC_TEST
605 spec->pin_configs = stac9200_pin_configs;
606#endif
607 spec->num_pins = 8;
608 spec->init = stac9200_ch2_init;
609 spec->mixer = stac9200_mixer; 942 spec->mixer = stac9200_mixer;
610 spec->playback_nid = 0x02; 943
611 spec->capture_nid = 0x03; 944 err = stac9200_parse_auto_config(codec);
945 if (err < 0) {
946 stac92xx_free(codec);
947 return err;
948 }
612 949
613 codec->patch_ops = stac92xx_patch_ops; 950 codec->patch_ops = stac92xx_patch_ops;
614 951
@@ -618,6 +955,7 @@ static int patch_stac9200(struct hda_codec *codec)
618static int patch_stac922x(struct hda_codec *codec) 955static int patch_stac922x(struct hda_codec *codec)
619{ 956{
620 struct sigmatel_spec *spec; 957 struct sigmatel_spec *spec;
958 int err;
621 959
622 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 960 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
623 if (spec == NULL) 961 if (spec == NULL)
@@ -625,26 +963,26 @@ static int patch_stac922x(struct hda_codec *codec)
625 963
626 codec->spec = spec; 964 codec->spec = spec;
627 965
628 spec->multiout.max_channels = 2;
629 spec->multiout.num_dacs = 4;
630 spec->multiout.dac_nids = stac922x_dac_nids;
631 spec->multiout.dig_out_nid = 0x08;
632 spec->dig_in_nid = 0x09;
633 spec->adc_nids = stac922x_adc_nids;
634 spec->mux_nids = stac922x_mux_nids;
635 spec->num_muxes = 2;
636 spec->input_mux.num_items = 0;
637 spec->pstate_nids = stac922x_pstate_nids;
638 spec->num_pstates = 8;
639 spec->pin_nids = stac922x_pin_nids;
640#ifdef STAC_TEST 966#ifdef STAC_TEST
967 spec->num_pins = 10;
968 spec->pin_nids = stac922x_pin_nids;
641 spec->pin_configs = stac922x_pin_configs; 969 spec->pin_configs = stac922x_pin_configs;
970 stac92xx_set_config_regs(codec);
642#endif 971#endif
643 spec->num_pins = 10; 972 spec->adc_nids = stac922x_adc_nids;
644 spec->init = stac922x_ch2_init; 973 spec->mux_nids = stac922x_mux_nids;
974 spec->num_muxes = 2;
975
976 spec->init = stac922x_core_init;
645 spec->mixer = stac922x_mixer; 977 spec->mixer = stac922x_mixer;
646 spec->playback_nid = 0x02; 978
647 spec->capture_nid = 0x06; 979 spec->multiout.dac_nids = spec->dac_nids;
980
981 err = stac922x_parse_auto_config(codec);
982 if (err < 0) {
983 stac92xx_free(codec);
984 return err;
985 }
648 986
649 codec->patch_ops = stac92xx_patch_ops; 987 codec->patch_ops = stac92xx_patch_ops;
650 988