2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for VIA VT1708 codec
6 * Copyright (c) 2006 Lydia Wang <lydiawang@viatech.com>
7 * Takashi Iwai <tiwai@suse.de>
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */
26 /* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */
27 /* 2006-03-14 Lydia Wang Modify hard code for some pin widget nid */
28 /* 2006-08-02 Lydia Wang Add support to VT1709 codec */
29 /* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */
31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
34 #include <sound/driver.h>
35 #include <linux/init.h>
36 #include <linux/delay.h>
37 #include <linux/slab.h>
38 #include <sound/core.h>
39 #include "hda_codec.h"
40 #include "hda_local.h"
44 #define AMP_VAL_IDX_SHIFT 19
45 #define AMP_VAL_IDX_MASK (0x0f<<19)
47 #define NUM_CONTROL_ALLOC 32
48 #define NUM_VERB_ALLOC 32
51 #define VT1708_HP_NID 0x13
52 #define VT1708_DIGOUT_NID 0x14
53 #define VT1708_DIGIN_NID 0x16
55 #define VT1709_HP_DAC_NID 0x28
56 #define VT1709_DIGOUT_NID 0x13
57 #define VT1709_DIGIN_NID 0x17
59 #define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b)
60 #define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713)
61 #define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717)
76 static struct snd_kcontrol_new vt1708_control_templates
[] = {
77 HDA_CODEC_VOLUME(NULL
, 0, 0, 0),
78 HDA_CODEC_MUTE(NULL
, 0, 0, 0),
83 /* codec parameterization */
84 struct snd_kcontrol_new
*mixers
[3];
85 unsigned int num_mixers
;
87 struct hda_verb
*init_verbs
;
89 char *stream_name_analog
;
90 struct hda_pcm_stream
*stream_analog_playback
;
91 struct hda_pcm_stream
*stream_analog_capture
;
93 char *stream_name_digital
;
94 struct hda_pcm_stream
*stream_digital_playback
;
95 struct hda_pcm_stream
*stream_digital_capture
;
98 struct hda_multi_out multiout
;
101 unsigned int num_adc_nids
;
103 hda_nid_t dig_in_nid
;
106 const struct hda_input_mux
*input_mux
;
107 unsigned int cur_mux
[3];
109 /* PCM information */
110 struct hda_pcm pcm_rec
[2];
112 /* dynamic controls, init_verbs and input_mux */
113 struct auto_pin_cfg autocfg
;
114 unsigned int num_kctl_alloc
, num_kctl_used
;
115 struct snd_kcontrol_new
*kctl_alloc
;
116 struct hda_input_mux private_imux
;
117 hda_nid_t private_dac_nids
[4];
120 static hda_nid_t vt1708_adc_nids
[2] = {
125 static hda_nid_t vt1709_adc_nids
[3] = {
130 /* add dynamic controls */
131 static int via_add_control(struct via_spec
*spec
, int type
, const char *name
,
134 struct snd_kcontrol_new
*knew
;
136 if (spec
->num_kctl_used
>= spec
->num_kctl_alloc
) {
137 int num
= spec
->num_kctl_alloc
+ NUM_CONTROL_ALLOC
;
139 /* array + terminator */
140 knew
= kcalloc(num
+ 1, sizeof(*knew
), GFP_KERNEL
);
143 if (spec
->kctl_alloc
) {
144 memcpy(knew
, spec
->kctl_alloc
,
145 sizeof(*knew
) * spec
->num_kctl_alloc
);
146 kfree(spec
->kctl_alloc
);
148 spec
->kctl_alloc
= knew
;
149 spec
->num_kctl_alloc
= num
;
152 knew
= &spec
->kctl_alloc
[spec
->num_kctl_used
];
153 *knew
= vt1708_control_templates
[type
];
154 knew
->name
= kstrdup(name
, GFP_KERNEL
);
158 knew
->private_value
= val
;
159 spec
->num_kctl_used
++;
163 /* create input playback/capture controls for the given pin */
164 static int via_new_analog_input(struct via_spec
*spec
, hda_nid_t pin
,
165 const char *ctlname
, int idx
, int mix_nid
)
170 sprintf(name
, "%s Playback Volume", ctlname
);
171 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
, name
,
172 HDA_COMPOSE_AMP_VAL(mix_nid
, 3, idx
, HDA_INPUT
));
175 sprintf(name
, "%s Playback Switch", ctlname
);
176 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
, name
,
177 HDA_COMPOSE_AMP_VAL(mix_nid
, 3, idx
, HDA_INPUT
));
183 static void via_auto_set_output_and_unmute(struct hda_codec
*codec
,
184 hda_nid_t nid
, int pin_type
,
188 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
190 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
195 static void via_auto_init_multi_out(struct hda_codec
*codec
)
197 struct via_spec
*spec
= codec
->spec
;
200 for (i
= 0; i
<= AUTO_SEQ_SIDE
; i
++) {
201 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
203 via_auto_set_output_and_unmute(codec
, nid
, PIN_OUT
, i
);
207 static void via_auto_init_hp_out(struct hda_codec
*codec
)
209 struct via_spec
*spec
= codec
->spec
;
212 pin
= spec
->autocfg
.hp_pins
[0];
213 if (pin
) /* connect to front */
214 via_auto_set_output_and_unmute(codec
, pin
, PIN_HP
, 0);
217 static void via_auto_init_analog_input(struct hda_codec
*codec
)
219 struct via_spec
*spec
= codec
->spec
;
222 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
223 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
225 snd_hda_codec_write(codec
, nid
, 0,
226 AC_VERB_SET_PIN_WIDGET_CONTROL
,
227 (i
<= AUTO_PIN_FRONT_MIC
?
228 PIN_VREF50
: PIN_IN
));
235 static int via_mux_enum_info(struct snd_kcontrol
*kcontrol
,
236 struct snd_ctl_elem_info
*uinfo
)
238 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
239 struct via_spec
*spec
= codec
->spec
;
240 return snd_hda_input_mux_info(spec
->input_mux
, uinfo
);
243 static int via_mux_enum_get(struct snd_kcontrol
*kcontrol
,
244 struct snd_ctl_elem_value
*ucontrol
)
246 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
247 struct via_spec
*spec
= codec
->spec
;
248 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
250 ucontrol
->value
.enumerated
.item
[0] = spec
->cur_mux
[adc_idx
];
254 static int via_mux_enum_put(struct snd_kcontrol
*kcontrol
,
255 struct snd_ctl_elem_value
*ucontrol
)
257 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
258 struct via_spec
*spec
= codec
->spec
;
259 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
260 unsigned int vendor_id
= codec
->vendor_id
;
262 /* AIW0 lydia 060801 add for correct sw0 input select */
263 if (IS_VT1708_VENDORID(vendor_id
) && (adc_idx
== 0))
264 return snd_hda_input_mux_put(codec
, spec
->input_mux
, ucontrol
,
265 0x18, &spec
->cur_mux
[adc_idx
]);
266 else if ((IS_VT1709_10CH_VENDORID(vendor_id
) ||
267 IS_VT1709_6CH_VENDORID(vendor_id
)) && (adc_idx
== 0) )
268 return snd_hda_input_mux_put(codec
, spec
->input_mux
, ucontrol
,
269 0x19, &spec
->cur_mux
[adc_idx
]);
271 return snd_hda_input_mux_put(codec
, spec
->input_mux
, ucontrol
,
272 spec
->adc_nids
[adc_idx
],
273 &spec
->cur_mux
[adc_idx
]);
276 /* capture mixer elements */
277 static struct snd_kcontrol_new vt1708_capture_mixer
[] = {
278 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT
),
279 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT
),
280 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT
),
281 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT
),
283 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
284 /* The multiple "Capture Source" controls confuse alsamixer
285 * So call somewhat different..
286 * FIXME: the controls appear in the "playback" view!
288 /* .name = "Capture Source", */
289 .name
= "Input Source",
291 .info
= via_mux_enum_info
,
292 .get
= via_mux_enum_get
,
293 .put
= via_mux_enum_put
,
298 * generic initialization of ADC, input mixers and output mixers
300 static struct hda_verb vt1708_volume_init_verbs
[] = {
302 * Unmute ADC0-1 and set the default input to mic-in
304 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
305 {0x27, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
308 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
311 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
312 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
313 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
314 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
315 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
316 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
319 * Set up output mixers (0x19 - 0x1b)
321 /* set vol=0 to output mixers */
322 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
323 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
324 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
326 /* Setup default input to PW4 */
327 {0x20, AC_VERB_SET_CONNECT_SEL
, 0x1},
328 /* Set mic as default input of sw0 */
329 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x2},
330 /* PW9 Output enable */
331 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
334 static int via_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
335 struct hda_codec
*codec
,
336 struct snd_pcm_substream
*substream
)
338 struct via_spec
*spec
= codec
->spec
;
339 return snd_hda_multi_out_analog_open(codec
, &spec
->multiout
, substream
);
342 static int via_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
343 struct hda_codec
*codec
,
344 unsigned int stream_tag
,
346 struct snd_pcm_substream
*substream
)
348 struct via_spec
*spec
= codec
->spec
;
349 return snd_hda_multi_out_analog_prepare(codec
, &spec
->multiout
,
350 stream_tag
, format
, substream
);
353 static int via_playback_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
354 struct hda_codec
*codec
,
355 struct snd_pcm_substream
*substream
)
357 struct via_spec
*spec
= codec
->spec
;
358 return snd_hda_multi_out_analog_cleanup(codec
, &spec
->multiout
);
364 static int via_dig_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
365 struct hda_codec
*codec
,
366 struct snd_pcm_substream
*substream
)
368 struct via_spec
*spec
= codec
->spec
;
369 return snd_hda_multi_out_dig_open(codec
, &spec
->multiout
);
372 static int via_dig_playback_pcm_close(struct hda_pcm_stream
*hinfo
,
373 struct hda_codec
*codec
,
374 struct snd_pcm_substream
*substream
)
376 struct via_spec
*spec
= codec
->spec
;
377 return snd_hda_multi_out_dig_close(codec
, &spec
->multiout
);
380 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
381 struct hda_codec
*codec
,
382 unsigned int stream_tag
,
384 struct snd_pcm_substream
*substream
)
386 struct via_spec
*spec
= codec
->spec
;
387 return snd_hda_multi_out_dig_prepare(codec
, &spec
->multiout
,
388 stream_tag
, format
, substream
);
394 static int via_capture_pcm_prepare(struct hda_pcm_stream
*hinfo
,
395 struct hda_codec
*codec
,
396 unsigned int stream_tag
,
398 struct snd_pcm_substream
*substream
)
400 struct via_spec
*spec
= codec
->spec
;
402 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
403 stream_tag
, 0, format
);
407 static int via_capture_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
408 struct hda_codec
*codec
,
409 struct snd_pcm_substream
*substream
)
411 struct via_spec
*spec
= codec
->spec
;
412 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
417 static struct hda_pcm_stream vt1708_pcm_analog_playback
= {
421 .nid
= 0x10, /* NID to query formats and rates */
423 .open
= via_playback_pcm_open
,
424 .prepare
= via_playback_pcm_prepare
,
425 .cleanup
= via_playback_pcm_cleanup
429 static struct hda_pcm_stream vt1708_pcm_analog_capture
= {
433 .nid
= 0x15, /* NID to query formats and rates */
435 .prepare
= via_capture_pcm_prepare
,
436 .cleanup
= via_capture_pcm_cleanup
440 static struct hda_pcm_stream vt1708_pcm_digital_playback
= {
444 /* NID is set in via_build_pcms */
446 .open
= via_dig_playback_pcm_open
,
447 .close
= via_dig_playback_pcm_close
,
448 .prepare
= via_dig_playback_pcm_prepare
452 static struct hda_pcm_stream vt1708_pcm_digital_capture
= {
458 static int via_build_controls(struct hda_codec
*codec
)
460 struct via_spec
*spec
= codec
->spec
;
464 for (i
= 0; i
< spec
->num_mixers
; i
++) {
465 err
= snd_hda_add_new_ctls(codec
, spec
->mixers
[i
]);
470 if (spec
->multiout
.dig_out_nid
) {
471 err
= snd_hda_create_spdif_out_ctls(codec
,
472 spec
->multiout
.dig_out_nid
);
476 if (spec
->dig_in_nid
) {
477 err
= snd_hda_create_spdif_in_ctls(codec
, spec
->dig_in_nid
);
484 static int via_build_pcms(struct hda_codec
*codec
)
486 struct via_spec
*spec
= codec
->spec
;
487 struct hda_pcm
*info
= spec
->pcm_rec
;
490 codec
->pcm_info
= info
;
492 info
->name
= spec
->stream_name_analog
;
493 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = *(spec
->stream_analog_playback
);
494 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= spec
->multiout
.dac_nids
[0];
495 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = *(spec
->stream_analog_capture
);
496 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->adc_nids
[0];
498 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].channels_max
=
499 spec
->multiout
.max_channels
;
501 if (spec
->multiout
.dig_out_nid
|| spec
->dig_in_nid
) {
504 info
->name
= spec
->stream_name_digital
;
505 if (spec
->multiout
.dig_out_nid
) {
506 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] =
507 *(spec
->stream_digital_playback
);
508 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
=
509 spec
->multiout
.dig_out_nid
;
511 if (spec
->dig_in_nid
) {
512 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] =
513 *(spec
->stream_digital_capture
);
514 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
=
522 static void via_free(struct hda_codec
*codec
)
524 struct via_spec
*spec
= codec
->spec
;
530 if (spec
->kctl_alloc
) {
531 for (i
= 0; i
< spec
->num_kctl_used
; i
++)
532 kfree(spec
->kctl_alloc
[i
].name
);
533 kfree(spec
->kctl_alloc
);
539 static int via_init(struct hda_codec
*codec
)
541 struct via_spec
*spec
= codec
->spec
;
542 snd_hda_sequence_write(codec
, spec
->init_verbs
);
550 static int via_resume(struct hda_codec
*codec
)
552 struct via_spec
*spec
= codec
->spec
;
556 for (i
= 0; i
< spec
->num_mixers
; i
++)
557 snd_hda_resume_ctls(codec
, spec
->mixers
[i
]);
558 if (spec
->multiout
.dig_out_nid
)
559 snd_hda_resume_spdif_out(codec
);
560 if (spec
->dig_in_nid
)
561 snd_hda_resume_spdif_in(codec
);
569 static struct hda_codec_ops via_patch_ops
= {
570 .build_controls
= via_build_controls
,
571 .build_pcms
= via_build_pcms
,
575 .resume
= via_resume
,
579 /* fill in the dac_nids table from the parsed pin configuration */
580 static int vt1708_auto_fill_dac_nids(struct via_spec
*spec
,
581 const struct auto_pin_cfg
*cfg
)
586 spec
->multiout
.num_dacs
= cfg
->line_outs
;
588 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
590 for(i
= 0; i
< 4; i
++) {
591 nid
= cfg
->line_out_pins
[i
];
593 /* config dac list */
596 spec
->multiout
.dac_nids
[i
] = 0x10;
598 case AUTO_SEQ_CENLFE
:
599 spec
->multiout
.dac_nids
[i
] = 0x12;
601 case AUTO_SEQ_SURROUND
:
602 spec
->multiout
.dac_nids
[i
] = 0x13;
605 spec
->multiout
.dac_nids
[i
] = 0x11;
614 /* add playback controls from the parsed DAC table */
615 static int vt1708_auto_create_multi_out_ctls(struct via_spec
*spec
,
616 const struct auto_pin_cfg
*cfg
)
619 static const char *chname
[4] = { "Front", "Surround", "C/LFE", "Side" };
620 hda_nid_t nid
, nid_vol
= 0;
623 for (i
= 0; i
<= AUTO_SEQ_SIDE
; i
++) {
624 nid
= cfg
->line_out_pins
[i
];
629 if (i
!= AUTO_SEQ_FRONT
)
630 nid_vol
= 0x1b - i
+ 1;
632 if (i
== AUTO_SEQ_CENLFE
) {
634 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
,
635 "Center Playback Volume",
636 HDA_COMPOSE_AMP_VAL(nid_vol
, 1, 0, HDA_OUTPUT
));
639 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
,
640 "LFE Playback Volume",
641 HDA_COMPOSE_AMP_VAL(nid_vol
, 2, 0, HDA_OUTPUT
));
644 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
,
645 "Center Playback Switch",
646 HDA_COMPOSE_AMP_VAL(nid_vol
, 1, 0, HDA_OUTPUT
));
649 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
,
650 "LFE Playback Switch",
651 HDA_COMPOSE_AMP_VAL(nid_vol
, 2, 0, HDA_OUTPUT
));
654 } else if (i
== AUTO_SEQ_FRONT
){
655 /* add control to mixer index 0 */
656 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
,
657 "Master Front Playback Volume",
658 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT
));
661 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
,
662 "Master Front Playback Switch",
663 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT
));
667 /* add control to PW3 */
668 sprintf(name
, "%s Playback Volume", chname
[i
]);
669 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
, name
,
670 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
673 sprintf(name
, "%s Playback Switch", chname
[i
]);
674 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
, name
,
675 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
679 sprintf(name
, "%s Playback Volume", chname
[i
]);
680 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
, name
,
681 HDA_COMPOSE_AMP_VAL(nid_vol
, 3, 0, HDA_OUTPUT
));
684 sprintf(name
, "%s Playback Switch", chname
[i
]);
685 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
, name
,
686 HDA_COMPOSE_AMP_VAL(nid_vol
, 3, 0, HDA_OUTPUT
));
695 static int vt1708_auto_create_hp_ctls(struct via_spec
*spec
, hda_nid_t pin
)
702 spec
->multiout
.hp_nid
= VT1708_HP_NID
; /* AOW3 */
704 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
,
705 "Headphone Playback Volume",
706 HDA_COMPOSE_AMP_VAL(pin
, 3, 0, HDA_OUTPUT
));
709 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
,
710 "Headphone Playback Switch",
711 HDA_COMPOSE_AMP_VAL(pin
, 3, 0, HDA_OUTPUT
));
718 /* create playback/capture controls for input pins */
719 static int vt1708_auto_create_analog_input_ctls(struct via_spec
*spec
,
720 const struct auto_pin_cfg
*cfg
)
722 static char *labels
[] = {
723 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
725 struct hda_input_mux
*imux
= &spec
->private_imux
;
728 /* for internal loopback recording select */
729 imux
->items
[imux
->num_items
].label
= "Stereo Mixer";
730 imux
->items
[imux
->num_items
].index
= idx
;
733 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
734 if (!cfg
->input_pins
[i
])
737 switch (cfg
->input_pins
[i
]) {
742 case 0x1e: /* Line In */
746 case 0x21: /* Front Mic */
754 err
= via_new_analog_input(spec
, cfg
->input_pins
[i
], labels
[i
],
758 imux
->items
[imux
->num_items
].label
= labels
[i
];
759 imux
->items
[imux
->num_items
].index
= idx
;
765 static int vt1708_parse_auto_config(struct hda_codec
*codec
)
767 struct via_spec
*spec
= codec
->spec
;
770 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
, NULL
);
773 err
= vt1708_auto_fill_dac_nids(spec
, &spec
->autocfg
);
776 if (!spec
->autocfg
.line_outs
&& !spec
->autocfg
.hp_pins
[0])
777 return 0; /* can't find valid BIOS pin config */
779 err
= vt1708_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
782 err
= vt1708_auto_create_hp_ctls(spec
, spec
->autocfg
.hp_pins
[0]);
785 err
= vt1708_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
789 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
791 if (spec
->autocfg
.dig_out_pin
)
792 spec
->multiout
.dig_out_nid
= VT1708_DIGOUT_NID
;
793 if (spec
->autocfg
.dig_in_pin
)
794 spec
->dig_in_nid
= VT1708_DIGIN_NID
;
796 if (spec
->kctl_alloc
)
797 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
799 spec
->init_verbs
= vt1708_volume_init_verbs
;
801 spec
->input_mux
= &spec
->private_imux
;
806 /* init callback for auto-configuration model -- overriding the default init */
807 static int via_auto_init(struct hda_codec
*codec
)
810 via_auto_init_multi_out(codec
);
811 via_auto_init_hp_out(codec
);
812 via_auto_init_analog_input(codec
);
816 static int patch_vt1708(struct hda_codec
*codec
)
818 struct via_spec
*spec
;
821 /* create a codec specific record */
822 spec
= kcalloc(1, sizeof(*spec
), GFP_KERNEL
);
828 /* automatic parse from the BIOS config */
829 err
= vt1708_parse_auto_config(codec
);
834 printk(KERN_INFO
"hda_codec: Cannot set up configuration "
835 "from BIOS. Using genenic mode...\n");
839 spec
->stream_name_analog
= "VT1708 Analog";
840 spec
->stream_analog_playback
= &vt1708_pcm_analog_playback
;
841 spec
->stream_analog_capture
= &vt1708_pcm_analog_capture
;
843 spec
->stream_name_digital
= "VT1708 Digital";
844 spec
->stream_digital_playback
= &vt1708_pcm_digital_playback
;
845 spec
->stream_digital_capture
= &vt1708_pcm_digital_capture
;
848 if (!spec
->adc_nids
&& spec
->input_mux
) {
849 spec
->adc_nids
= vt1708_adc_nids
;
850 spec
->num_adc_nids
= ARRAY_SIZE(vt1708_adc_nids
);
851 spec
->mixers
[spec
->num_mixers
] = vt1708_capture_mixer
;
855 codec
->patch_ops
= via_patch_ops
;
857 codec
->patch_ops
.init
= via_auto_init
;
862 /* capture mixer elements */
863 static struct snd_kcontrol_new vt1709_capture_mixer
[] = {
864 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT
),
865 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT
),
866 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT
),
867 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT
),
868 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT
),
869 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT
),
871 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
872 /* The multiple "Capture Source" controls confuse alsamixer
873 * So call somewhat different..
874 * FIXME: the controls appear in the "playback" view!
876 /* .name = "Capture Source", */
877 .name
= "Input Source",
879 .info
= via_mux_enum_info
,
880 .get
= via_mux_enum_get
,
881 .put
= via_mux_enum_put
,
887 * generic initialization of ADC, input mixers and output mixers
889 static struct hda_verb vt1709_10ch_volume_init_verbs
[] = {
891 * Unmute ADC0-2 and set the default input to mic-in
893 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
894 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
895 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
898 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
901 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
902 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
903 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
904 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
905 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
906 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
909 * Set up output selector (0x1a, 0x1b, 0x29)
911 /* set vol=0 to output mixers */
912 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
913 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
914 {0x29, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
919 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
920 {0x20, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
922 /* Set input of PW4 as AOW4 */
923 {0x20, AC_VERB_SET_CONNECT_SEL
, 0x1},
924 /* Set mic as default input of sw0 */
925 {0x19, AC_VERB_SET_CONNECT_SEL
, 0x2},
926 /* PW9 Output enable */
927 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
931 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback
= {
935 .nid
= 0x10, /* NID to query formats and rates */
937 .open
= via_playback_pcm_open
,
938 .prepare
= via_playback_pcm_prepare
,
939 .cleanup
= via_playback_pcm_cleanup
943 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback
= {
947 .nid
= 0x10, /* NID to query formats and rates */
949 .open
= via_playback_pcm_open
,
950 .prepare
= via_playback_pcm_prepare
,
951 .cleanup
= via_playback_pcm_cleanup
955 static struct hda_pcm_stream vt1709_pcm_analog_capture
= {
959 .nid
= 0x14, /* NID to query formats and rates */
961 .prepare
= via_capture_pcm_prepare
,
962 .cleanup
= via_capture_pcm_cleanup
966 static struct hda_pcm_stream vt1709_pcm_digital_playback
= {
970 /* NID is set in via_build_pcms */
972 .open
= via_dig_playback_pcm_open
,
973 .close
= via_dig_playback_pcm_close
977 static struct hda_pcm_stream vt1709_pcm_digital_capture
= {
983 static int vt1709_auto_fill_dac_nids(struct via_spec
*spec
,
984 const struct auto_pin_cfg
*cfg
)
989 if (cfg
->line_outs
== 4) /* 10 channels */
990 spec
->multiout
.num_dacs
= cfg
->line_outs
+1; /* AOW0~AOW4 */
991 else if (cfg
->line_outs
== 3) /* 6 channels */
992 spec
->multiout
.num_dacs
= cfg
->line_outs
; /* AOW0~AOW2 */
994 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
996 if (cfg
->line_outs
== 4) { /* 10 channels */
997 for (i
= 0; i
< cfg
->line_outs
; i
++) {
998 nid
= cfg
->line_out_pins
[i
];
1000 /* config dac list */
1002 case AUTO_SEQ_FRONT
:
1004 spec
->multiout
.dac_nids
[i
] = 0x10;
1006 case AUTO_SEQ_CENLFE
:
1008 spec
->multiout
.dac_nids
[i
] = 0x12;
1010 case AUTO_SEQ_SURROUND
:
1012 spec
->multiout
.dac_nids
[i
] = 0x27;
1016 spec
->multiout
.dac_nids
[i
] = 0x11;
1023 spec
->multiout
.dac_nids
[cfg
->line_outs
] = 0x28; /* AOW4 */
1025 } else if (cfg
->line_outs
== 3) { /* 6 channels */
1026 for(i
= 0; i
< cfg
->line_outs
; i
++) {
1027 nid
= cfg
->line_out_pins
[i
];
1029 /* config dac list */
1031 case AUTO_SEQ_FRONT
:
1033 spec
->multiout
.dac_nids
[i
] = 0x10;
1035 case AUTO_SEQ_CENLFE
:
1037 spec
->multiout
.dac_nids
[i
] = 0x12;
1039 case AUTO_SEQ_SURROUND
:
1041 spec
->multiout
.dac_nids
[i
] = 0x11;
1053 /* add playback controls from the parsed DAC table */
1054 static int vt1709_auto_create_multi_out_ctls(struct via_spec
*spec
,
1055 const struct auto_pin_cfg
*cfg
)
1058 static const char *chname
[4] = { "Front", "Surround", "C/LFE", "Side" };
1062 for (i
= 0; i
<= AUTO_SEQ_SIDE
; i
++) {
1063 nid
= cfg
->line_out_pins
[i
];
1068 if (i
== AUTO_SEQ_CENLFE
) {
1070 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
,
1071 "Center Playback Volume",
1072 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT
));
1075 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
,
1076 "LFE Playback Volume",
1077 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT
));
1080 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
,
1081 "Center Playback Switch",
1082 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT
));
1085 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
,
1086 "LFE Playback Switch",
1087 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT
));
1090 } else if (i
== AUTO_SEQ_FRONT
){
1091 /* add control to mixer index 0 */
1092 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
,
1093 "Master Front Playback Volume",
1094 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT
));
1097 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
,
1098 "Master Front Playback Switch",
1099 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT
));
1103 /* add control to PW3 */
1104 sprintf(name
, "%s Playback Volume", chname
[i
]);
1105 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
, name
,
1106 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
1109 sprintf(name
, "%s Playback Switch", chname
[i
]);
1110 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
, name
,
1111 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
1114 } else if (i
== AUTO_SEQ_SURROUND
) {
1115 sprintf(name
, "%s Playback Volume", chname
[i
]);
1116 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
, name
,
1117 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT
));
1120 sprintf(name
, "%s Playback Switch", chname
[i
]);
1121 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
, name
,
1122 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT
));
1125 } else if (i
== AUTO_SEQ_SIDE
) {
1126 sprintf(name
, "%s Playback Volume", chname
[i
]);
1127 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
, name
,
1128 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT
));
1131 sprintf(name
, "%s Playback Switch", chname
[i
]);
1132 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
, name
,
1133 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT
));
1142 static int vt1709_auto_create_hp_ctls(struct via_spec
*spec
, hda_nid_t pin
)
1149 if (spec
->multiout
.num_dacs
== 5) /* 10 channels */
1150 spec
->multiout
.hp_nid
= VT1709_HP_DAC_NID
;
1151 else if (spec
->multiout
.num_dacs
== 3) /* 6 channels */
1152 spec
->multiout
.hp_nid
= 0;
1154 err
= via_add_control(spec
, VIA_CTL_WIDGET_VOL
,
1155 "Headphone Playback Volume",
1156 HDA_COMPOSE_AMP_VAL(pin
, 3, 0, HDA_OUTPUT
));
1159 err
= via_add_control(spec
, VIA_CTL_WIDGET_MUTE
,
1160 "Headphone Playback Switch",
1161 HDA_COMPOSE_AMP_VAL(pin
, 3, 0, HDA_OUTPUT
));
1168 /* create playback/capture controls for input pins */
1169 static int vt1709_auto_create_analog_input_ctls(struct via_spec
*spec
,
1170 const struct auto_pin_cfg
*cfg
)
1172 static char *labels
[] = {
1173 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1175 struct hda_input_mux
*imux
= &spec
->private_imux
;
1176 int i
, err
, idx
= 0;
1178 /* for internal loopback recording select */
1179 imux
->items
[imux
->num_items
].label
= "Stereo Mixer";
1180 imux
->items
[imux
->num_items
].index
= idx
;
1183 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
1184 if (!cfg
->input_pins
[i
])
1187 switch (cfg
->input_pins
[i
]) {
1188 case 0x1d: /* Mic */
1192 case 0x1e: /* Line In */
1196 case 0x21: /* Front Mic */
1204 err
= via_new_analog_input(spec
, cfg
->input_pins
[i
], labels
[i
],
1208 imux
->items
[imux
->num_items
].label
= labels
[i
];
1209 imux
->items
[imux
->num_items
].index
= idx
;
1215 static int vt1709_parse_auto_config(struct hda_codec
*codec
)
1217 struct via_spec
*spec
= codec
->spec
;
1220 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
, NULL
);
1223 err
= vt1709_auto_fill_dac_nids(spec
, &spec
->autocfg
);
1226 if (!spec
->autocfg
.line_outs
&& !spec
->autocfg
.hp_pins
[0])
1227 return 0; /* can't find valid BIOS pin config */
1229 err
= vt1709_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
1232 err
= vt1709_auto_create_hp_ctls(spec
, spec
->autocfg
.hp_pins
[0]);
1235 err
= vt1709_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
1239 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
1241 if (spec
->autocfg
.dig_out_pin
)
1242 spec
->multiout
.dig_out_nid
= VT1709_DIGOUT_NID
;
1243 if (spec
->autocfg
.dig_in_pin
)
1244 spec
->dig_in_nid
= VT1709_DIGIN_NID
;
1246 if (spec
->kctl_alloc
)
1247 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
1249 spec
->input_mux
= &spec
->private_imux
;
1254 static int patch_vt1709_10ch(struct hda_codec
*codec
)
1256 struct via_spec
*spec
;
1259 /* create a codec specific record */
1260 spec
= kcalloc(1, sizeof(*spec
), GFP_KERNEL
);
1266 err
= vt1709_parse_auto_config(codec
);
1271 printk(KERN_INFO
"hda_codec: Cannot set up configuration. "
1272 "Using genenic mode...\n");
1275 spec
->init_verbs
= vt1709_10ch_volume_init_verbs
;
1277 spec
->stream_name_analog
= "VT1709 Analog";
1278 spec
->stream_analog_playback
= &vt1709_10ch_pcm_analog_playback
;
1279 spec
->stream_analog_capture
= &vt1709_pcm_analog_capture
;
1281 spec
->stream_name_digital
= "VT1709 Digital";
1282 spec
->stream_digital_playback
= &vt1709_pcm_digital_playback
;
1283 spec
->stream_digital_capture
= &vt1709_pcm_digital_capture
;
1286 if (!spec
->adc_nids
&& spec
->input_mux
) {
1287 spec
->adc_nids
= vt1709_adc_nids
;
1288 spec
->num_adc_nids
= ARRAY_SIZE(vt1709_adc_nids
);
1289 spec
->mixers
[spec
->num_mixers
] = vt1709_capture_mixer
;
1293 codec
->patch_ops
= via_patch_ops
;
1295 codec
->patch_ops
.init
= via_auto_init
;
1300 * generic initialization of ADC, input mixers and output mixers
1302 static struct hda_verb vt1709_6ch_volume_init_verbs
[] = {
1304 * Unmute ADC0-2 and set the default input to mic-in
1306 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
1307 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
1308 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
1311 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1314 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1315 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
1316 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
1317 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
1318 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
1319 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
1322 * Set up output selector (0x1a, 0x1b, 0x29)
1324 /* set vol=0 to output mixers */
1325 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
1326 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
1327 {0x29, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
1330 * Unmute PW3 and PW4
1332 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
1333 {0x20, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
1335 /* Set input of PW4 as MW0 */
1336 {0x20, AC_VERB_SET_CONNECT_SEL
, 0},
1337 /* Set mic as default input of sw0 */
1338 {0x19, AC_VERB_SET_CONNECT_SEL
, 0x2},
1339 /* PW9 Output enable */
1340 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
1344 static int patch_vt1709_6ch(struct hda_codec
*codec
)
1346 struct via_spec
*spec
;
1349 /* create a codec specific record */
1350 spec
= kcalloc(1, sizeof(*spec
), GFP_KERNEL
);
1356 err
= vt1709_parse_auto_config(codec
);
1361 printk(KERN_INFO
"hda_codec: Cannot set up configuration. "
1362 "Using genenic mode...\n");
1365 spec
->init_verbs
= vt1709_6ch_volume_init_verbs
;
1367 spec
->stream_name_analog
= "VT1709 Analog";
1368 spec
->stream_analog_playback
= &vt1709_6ch_pcm_analog_playback
;
1369 spec
->stream_analog_capture
= &vt1709_pcm_analog_capture
;
1371 spec
->stream_name_digital
= "VT1709 Digital";
1372 spec
->stream_digital_playback
= &vt1709_pcm_digital_playback
;
1373 spec
->stream_digital_capture
= &vt1709_pcm_digital_capture
;
1376 if (!spec
->adc_nids
&& spec
->input_mux
) {
1377 spec
->adc_nids
= vt1709_adc_nids
;
1378 spec
->num_adc_nids
= ARRAY_SIZE(vt1709_adc_nids
);
1379 spec
->mixers
[spec
->num_mixers
] = vt1709_capture_mixer
;
1383 codec
->patch_ops
= via_patch_ops
;
1385 codec
->patch_ops
.init
= via_auto_init
;
1393 struct hda_codec_preset snd_hda_preset_via
[] = {
1394 { .id
= 0x11061708, .name
= "VIA VT1708", .patch
= patch_vt1708
},
1395 { .id
= 0x11061709, .name
= "VIA VT1708", .patch
= patch_vt1708
},
1396 { .id
= 0x1106170A, .name
= "VIA VT1708", .patch
= patch_vt1708
},
1397 { .id
= 0x1106170B, .name
= "VIA VT1708", .patch
= patch_vt1708
},
1398 { .id
= 0x1106E710, .name
= "VIA VT1709 10-Ch", .patch
= patch_vt1709_10ch
},
1399 { .id
= 0x1106E711, .name
= "VIA VT1709 10-Ch", .patch
= patch_vt1709_10ch
},
1400 { .id
= 0x1106E712, .name
= "VIA VT1709 10-Ch", .patch
= patch_vt1709_10ch
},
1401 { .id
= 0x1106E713, .name
= "VIA VT1709 10-Ch", .patch
= patch_vt1709_10ch
},
1402 { .id
= 0x1106E714, .name
= "VIA VT1709 6-Ch", .patch
= patch_vt1709_6ch
},
1403 { .id
= 0x1106E715, .name
= "VIA VT1709 6-Ch", .patch
= patch_vt1709_6ch
},
1404 { .id
= 0x1106E716, .name
= "VIA VT1709 6-Ch", .patch
= patch_vt1709_6ch
},
1405 { .id
= 0x1106E717, .name
= "VIA VT1709 6-Ch", .patch
= patch_vt1709_6ch
},