Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/w1-2.6
[linux-2.6] / sound / pci / hda / patch_sigmatel.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for SigmaTel STAC92xx
5  *
6  * Copyright (c) 2005 Embedded Alley Solutions, Inc.
7  * <matt@embeddedalley.com>
8  *
9  * Based on patch_cmedia.c and patch_realtek.c
10  * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
11  *
12  *  This driver is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This driver is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
25  */
26
27 #include <sound/driver.h>
28 #include <linux/init.h>
29 #include <linux/delay.h>
30 #include <linux/slab.h>
31 #include <linux/pci.h>
32 #include <sound/core.h>
33 #include "hda_codec.h"
34 #include "hda_local.h"
35
36 #undef STAC_TEST
37
38 struct sigmatel_spec {
39         /* playback */
40         struct hda_multi_out multiout;
41         hda_nid_t playback_nid;
42
43         /* capture */
44         hda_nid_t *adc_nids;
45         unsigned int num_adcs;
46         hda_nid_t *mux_nids;
47         unsigned int num_muxes;
48         hda_nid_t capture_nid;
49         hda_nid_t dig_in_nid;
50
51         /* power management*/
52         hda_nid_t *pstate_nids;
53         unsigned int num_pstates;
54
55         /* pin widgets */
56         hda_nid_t *pin_nids;
57         unsigned int num_pins;
58 #ifdef STAC_TEST
59         unsigned int *pin_configs;
60 #endif
61
62         /* codec specific stuff */
63         struct hda_verb *init;
64         snd_kcontrol_new_t *mixer;
65
66         /* capture source */
67         struct hda_input_mux input_mux;
68         char input_labels[HDA_MAX_NUM_INPUTS][16];
69         unsigned int cur_mux[2];
70
71         /* channel mode */
72         unsigned int num_ch_modes;
73         unsigned int cur_ch_mode;
74         const struct sigmatel_channel_mode *channel_modes;
75
76         struct hda_pcm pcm_rec[1];      /* PCM information */
77 };
78
79 static hda_nid_t stac9200_adc_nids[1] = {
80         0x03,
81 };
82
83 static hda_nid_t stac9200_mux_nids[1] = {
84         0x0c,
85 };
86
87 static hda_nid_t stac9200_dac_nids[1] = {
88         0x02,
89 };
90
91 static hda_nid_t stac9200_pstate_nids[3] = {
92         0x01, 0x02, 0x03,
93 };
94
95 static hda_nid_t stac9200_pin_nids[8] = {
96         0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
97 };
98
99 static hda_nid_t stac922x_adc_nids[2] = {
100         0x06, 0x07,
101 };
102
103 static hda_nid_t stac922x_mux_nids[2] = {
104         0x12, 0x13,
105 };
106
107 static hda_nid_t stac922x_dac_nids[4] = {
108         0x02, 0x03, 0x04, 0x05,
109 };
110
111 static hda_nid_t stac922x_pstate_nids[8] = {
112         0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x11,
113 };
114
115 static hda_nid_t stac922x_pin_nids[10] = {
116         0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
117         0x0f, 0x10, 0x11, 0x15, 0x1b,
118 };
119
120 static int stac92xx_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
121 {
122         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
123         struct sigmatel_spec *spec = codec->spec;
124         return snd_hda_input_mux_info(&spec->input_mux, uinfo);
125 }
126
127 static int stac92xx_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
128 {
129         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
130         struct sigmatel_spec *spec = codec->spec;
131         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
132
133         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
134         return 0;
135 }
136
137 static int stac92xx_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
138 {
139         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
140         struct sigmatel_spec *spec = codec->spec;
141         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
142
143         return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol,
144                                      spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
145 }
146
147 static struct hda_verb stac9200_ch2_init[] = {
148         /* set dac0mux for dac converter */
149         { 0x07, 0x701, 0x00},
150         {}
151 };
152
153 static struct hda_verb stac922x_ch2_init[] = {
154         /* set master volume and direct control */      
155         { 0x16, 0x70f, 0xff},
156         {}
157 };
158
159 struct sigmatel_channel_mode {
160         unsigned int channels;
161         const struct hda_verb *sequence;
162 };
163
164 static snd_kcontrol_new_t stac9200_mixer[] = {
165         HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
166         HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
167         {
168                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
169                 .name = "Input Source",
170                 .count = 1,
171                 .info = stac92xx_mux_enum_info,
172                 .get = stac92xx_mux_enum_get,
173                 .put = stac92xx_mux_enum_put,
174         },
175         HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
176         HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
177         HDA_CODEC_VOLUME("Input Mux Volume", 0x0c, 0, HDA_OUTPUT),
178         { } /* end */
179 };
180
181 static 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         {
185                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
186                 .name = "Input Source",
187                 .count = 1,
188                 .info = stac92xx_mux_enum_info,
189                 .get = stac92xx_mux_enum_get,
190                 .put = stac92xx_mux_enum_put,
191         },
192         HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT),
193         HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT),
194         HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT),
195         { } /* end */
196 };
197
198 static int stac92xx_build_controls(struct hda_codec *codec)
199 {
200         struct sigmatel_spec *spec = codec->spec;
201         int err;
202
203         err = snd_hda_add_new_ctls(codec, spec->mixer);
204         if (err < 0)
205                 return err;
206         if (spec->multiout.dig_out_nid) {
207                 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
208                 if (err < 0)
209                         return err;
210         }
211         if (spec->dig_in_nid) {
212                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
213                 if (err < 0)
214                         return err;
215         }
216         return 0;       
217 }
218
219 #ifdef STAC_TEST
220 static unsigned int stac9200_pin_configs[8] = {
221         0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
222         0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
223 };
224
225 static unsigned int stac922x_pin_configs[14] = {
226         0x40000100, 0x40000100, 0x40000100, 0x01114010,
227         0x01813122, 0x40000100, 0x01447010, 0x01c47010,
228         0x40000100, 0x40000100,
229 };
230
231 static void stac92xx_set_config_regs(struct hda_codec *codec)
232 {
233         int i;
234         struct sigmatel_spec *spec = codec->spec;
235         unsigned int pin_cfg;
236
237         for (i=0; i < spec->num_pins; i++) {
238                 snd_hda_codec_write(codec, spec->pin_nids[i], 0,
239                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
240                                     spec->pin_configs[i] & 0x000000ff);
241                 snd_hda_codec_write(codec, spec->pin_nids[i], 0,
242                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
243                                     (spec->pin_configs[i] & 0x0000ff00) >> 8);
244                 snd_hda_codec_write(codec, spec->pin_nids[i], 0,
245                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
246                                     (spec->pin_configs[i] & 0x00ff0000) >> 16);
247                 snd_hda_codec_write(codec, spec->pin_nids[i], 0,
248                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
249                                     spec->pin_configs[i] >> 24);
250                 pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0,
251                                              AC_VERB_GET_CONFIG_DEFAULT,
252                                              0x00);     
253                 printk("pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg);
254         }
255 }
256 #endif
257
258 static 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
271 static 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 /*
291  * retrieve the default device type from the default config value
292  */
293 #define get_defcfg_type(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
294 #define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
295
296 static int stac92xx_config_pin(struct hda_codec *codec, hda_nid_t nid, unsigned int pin_cfg)
297 {
298         struct sigmatel_spec *spec = codec->spec;
299         u32 location = get_defcfg_location(pin_cfg);
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 }
375
376 static int stac92xx_config_pins(struct hda_codec *codec)
377 {
378         struct sigmatel_spec *spec = codec->spec;
379         int i;
380         unsigned int pin_cfg;
381
382         for (i=0; i < spec->num_pins; i++) {
383                 /* Default to disabled */
384                 snd_hda_codec_write(codec, spec->pin_nids[i], 0,
385                                     AC_VERB_SET_PIN_WIDGET_CONTROL,
386                                     0x00);
387
388                 pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0,
389                                              AC_VERB_GET_CONFIG_DEFAULT,
390                                              0x00);
391                 if (((pin_cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) == AC_JACK_PORT_NONE)
392                         continue;       /* Move on */
393
394                 stac92xx_config_pin(codec, spec->pin_nids[i], pin_cfg);
395         }
396
397         return 0;
398 }
399
400 static int stac92xx_init(struct hda_codec *codec)
401 {
402         struct sigmatel_spec *spec = codec->spec;
403         int i;
404
405         for (i=0; i < spec->num_pstates; i++)
406                 snd_hda_codec_write(codec, spec->pstate_nids[i], 0,
407                                     AC_VERB_SET_POWER_STATE, 0x00);
408
409         mdelay(100);
410
411         snd_hda_sequence_write(codec, spec->init);
412
413 #ifdef STAC_TEST
414         stac92xx_set_config_regs(codec);
415 #endif
416
417         stac92xx_config_pins(codec);
418
419         return 0;
420 }
421
422 /*
423  * Analog playback callbacks
424  */
425 static 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
433 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
434                                          struct hda_codec *codec,
435                                          unsigned int stream_tag,
436                                          unsigned int format,
437                                          snd_pcm_substream_t *substream)
438 {
439         struct sigmatel_spec *spec = codec->spec;
440         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
441                                                 format, substream);
442 }
443
444 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
445                                         struct hda_codec *codec,
446                                         snd_pcm_substream_t *substream)
447 {
448         struct sigmatel_spec *spec = codec->spec;
449         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
450 }
451
452 /*
453  * Digital playback callbacks
454  */
455 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
456                                           struct hda_codec *codec,
457                                           snd_pcm_substream_t *substream)
458 {
459         struct sigmatel_spec *spec = codec->spec;
460         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
461 }
462
463 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
464                                            struct hda_codec *codec,
465                                            snd_pcm_substream_t *substream)
466 {
467         struct sigmatel_spec *spec = codec->spec;
468         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
469 }
470
471
472 /*
473  * Analog capture callbacks
474  */
475 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
476                                         struct hda_codec *codec,
477                                         unsigned int stream_tag,
478                                         unsigned int format,
479                                         snd_pcm_substream_t *substream)
480 {
481         struct sigmatel_spec *spec = codec->spec;
482
483         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
484                                    stream_tag, 0, format);
485         return 0;
486 }
487
488 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
489                                         struct hda_codec *codec,
490                                         snd_pcm_substream_t *substream)
491 {
492         struct sigmatel_spec *spec = codec->spec;
493
494         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
495         return 0;
496 }
497
498 static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
499         .substreams = 1,
500         .channels_min = 2,
501         .channels_max = 2,
502         /* NID is set in stac92xx_build_pcms */
503         .ops = {
504                 .open = stac92xx_dig_playback_pcm_open,
505                 .close = stac92xx_dig_playback_pcm_close
506         },
507 };
508
509 static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
510         .substreams = 1,
511         .channels_min = 2,
512         .channels_max = 2,
513         /* NID is set in stac92xx_build_pcms */
514 };
515
516 static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
517         .substreams = 1,
518         .channels_min = 2,
519         .channels_max = 2,
520         .nid = 0x02, /* NID to query formats and rates */
521         .ops = {
522                 .open = stac92xx_playback_pcm_open,
523                 .prepare = stac92xx_playback_pcm_prepare,
524                 .cleanup = stac92xx_playback_pcm_cleanup
525         },
526 };
527
528 static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
529         .substreams = 2,
530         .channels_min = 2,
531         .channels_max = 2,
532         .nid = 0x06, /* NID to query formats and rates */
533         .ops = {
534                 .prepare = stac92xx_capture_pcm_prepare,
535                 .cleanup = stac92xx_capture_pcm_cleanup
536         },
537 };
538
539 static int stac92xx_build_pcms(struct hda_codec *codec)
540 {
541         struct sigmatel_spec *spec = codec->spec;
542         struct hda_pcm *info = spec->pcm_rec;
543
544         codec->num_pcms = 1;
545         codec->pcm_info = info;
546
547         info->name = "STAC92xx";
548         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;
551         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->capture_nid;
552
553         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
554                 codec->num_pcms++;
555                 info++;
556                 info->name = "STAC92xx Digital";
557                 if (spec->multiout.dig_out_nid) {
558                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
559                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
560                 }
561                 if (spec->dig_in_nid) {
562                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
563                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
564                 }
565         }
566
567         return 0;
568 }
569
570 static void stac92xx_free(struct hda_codec *codec)
571 {
572         kfree(codec->spec);
573 }
574
575 static struct hda_codec_ops stac92xx_patch_ops = {
576         .build_controls = stac92xx_build_controls,
577         .build_pcms = stac92xx_build_pcms,
578         .init = stac92xx_init,
579         .free = stac92xx_free,
580 };
581
582 static int patch_stac9200(struct hda_codec *codec)
583 {
584         struct sigmatel_spec *spec;
585
586         spec  = kcalloc(1, sizeof(*spec), GFP_KERNEL);
587         if (spec == NULL)
588                 return -ENOMEM;
589
590         codec->spec = spec;
591
592         spec->multiout.max_channels = 2;
593         spec->multiout.num_dacs = 1;
594         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;
598         spec->mux_nids = stac9200_mux_nids;
599         spec->num_muxes = 1;
600         spec->input_mux.num_items = 0;
601         spec->pstate_nids = stac9200_pstate_nids;
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;
610         spec->playback_nid = 0x02;
611         spec->capture_nid = 0x03;
612
613         codec->patch_ops = stac92xx_patch_ops;
614
615         return 0;
616 }
617
618 static int patch_stac922x(struct hda_codec *codec)
619 {
620         struct sigmatel_spec *spec;
621
622         spec  = kcalloc(1, sizeof(*spec), GFP_KERNEL);
623         if (spec == NULL)
624                 return -ENOMEM;
625
626         codec->spec = spec;
627
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
641         spec->pin_configs = stac922x_pin_configs;
642 #endif
643         spec->num_pins = 10;
644         spec->init = stac922x_ch2_init;
645         spec->mixer = stac922x_mixer;
646         spec->playback_nid = 0x02;
647         spec->capture_nid = 0x06;
648
649         codec->patch_ops = stac92xx_patch_ops;
650
651         return 0;
652 }
653
654 /*
655  * patch entries
656  */
657 struct hda_codec_preset snd_hda_preset_sigmatel[] = {
658         { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
659         { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
660         { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
661         { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
662         { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
663         { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
664         { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
665         {} /* terminator */
666 };