2 * HD audio interface patch for Conexant HDA audio codec
4 * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
5 * Takashi Iwai <tiwai@suse.de>
6 * Tobin Davis <tdavis@dsl-only.net>
8 * This driver is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This driver is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <sound/driver.h>
24 #include <linux/init.h>
25 #include <linux/delay.h>
26 #include <linux/slab.h>
27 #include <linux/pci.h>
28 #include <sound/core.h>
29 #include "hda_codec.h"
30 #include "hda_local.h"
32 #define CXT_PIN_DIR_IN 0x00
33 #define CXT_PIN_DIR_OUT 0x01
34 #define CXT_PIN_DIR_INOUT 0x02
35 #define CXT_PIN_DIR_IN_NOMICBIAS 0x03
36 #define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
38 #define CONEXANT_HP_EVENT 0x37
39 #define CONEXANT_MIC_EVENT 0x38
43 struct conexant_spec
{
45 struct snd_kcontrol_new
*mixers
[5];
48 const struct hda_verb
*init_verbs
[5]; /* initialization verbs
52 unsigned int num_init_verbs
;
55 struct hda_multi_out multiout
; /* playback set-up
56 * max_channels, dacs must be set
57 * dig_out_nid and hp_nid are optional
59 unsigned int cur_eapd
;
60 unsigned int need_dac_fix
;
63 unsigned int num_adc_nids
;
65 hda_nid_t dig_in_nid
; /* digital-in NID; optional */
68 const struct hda_input_mux
*input_mux
;
69 hda_nid_t
*capsrc_nids
;
70 unsigned int cur_mux
[3];
73 const struct hda_channel_mode
*channel_mode
;
77 struct hda_pcm pcm_rec
[2]; /* used in build_pcms() */
79 struct mutex amp_mutex
; /* PCM volume/mute control mutex */
80 unsigned int spdif_route
;
82 /* dynamic controls, init_verbs and input_mux */
83 struct auto_pin_cfg autocfg
;
84 unsigned int num_kctl_alloc
, num_kctl_used
;
85 struct snd_kcontrol_new
*kctl_alloc
;
86 struct hda_input_mux private_imux
;
87 hda_nid_t private_dac_nids
[4];
91 static int conexant_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
92 struct hda_codec
*codec
,
93 struct snd_pcm_substream
*substream
)
95 struct conexant_spec
*spec
= codec
->spec
;
96 return snd_hda_multi_out_analog_open(codec
, &spec
->multiout
, substream
);
99 static int conexant_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
100 struct hda_codec
*codec
,
101 unsigned int stream_tag
,
103 struct snd_pcm_substream
*substream
)
105 struct conexant_spec
*spec
= codec
->spec
;
106 return snd_hda_multi_out_analog_prepare(codec
, &spec
->multiout
,
111 static int conexant_playback_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
112 struct hda_codec
*codec
,
113 struct snd_pcm_substream
*substream
)
115 struct conexant_spec
*spec
= codec
->spec
;
116 return snd_hda_multi_out_analog_cleanup(codec
, &spec
->multiout
);
122 static int conexant_dig_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
123 struct hda_codec
*codec
,
124 struct snd_pcm_substream
*substream
)
126 struct conexant_spec
*spec
= codec
->spec
;
127 return snd_hda_multi_out_dig_open(codec
, &spec
->multiout
);
130 static int conexant_dig_playback_pcm_close(struct hda_pcm_stream
*hinfo
,
131 struct hda_codec
*codec
,
132 struct snd_pcm_substream
*substream
)
134 struct conexant_spec
*spec
= codec
->spec
;
135 return snd_hda_multi_out_dig_close(codec
, &spec
->multiout
);
141 static int conexant_capture_pcm_prepare(struct hda_pcm_stream
*hinfo
,
142 struct hda_codec
*codec
,
143 unsigned int stream_tag
,
145 struct snd_pcm_substream
*substream
)
147 struct conexant_spec
*spec
= codec
->spec
;
148 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
149 stream_tag
, 0, format
);
153 static int conexant_capture_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
154 struct hda_codec
*codec
,
155 struct snd_pcm_substream
*substream
)
157 struct conexant_spec
*spec
= codec
->spec
;
158 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
165 static struct hda_pcm_stream conexant_pcm_analog_playback
= {
169 .nid
= 0, /* fill later */
171 .open
= conexant_playback_pcm_open
,
172 .prepare
= conexant_playback_pcm_prepare
,
173 .cleanup
= conexant_playback_pcm_cleanup
177 static struct hda_pcm_stream conexant_pcm_analog_capture
= {
181 .nid
= 0, /* fill later */
183 .prepare
= conexant_capture_pcm_prepare
,
184 .cleanup
= conexant_capture_pcm_cleanup
189 static struct hda_pcm_stream conexant_pcm_digital_playback
= {
193 .nid
= 0, /* fill later */
195 .open
= conexant_dig_playback_pcm_open
,
196 .close
= conexant_dig_playback_pcm_close
200 static struct hda_pcm_stream conexant_pcm_digital_capture
= {
204 /* NID is set in alc_build_pcms */
207 static int conexant_build_pcms(struct hda_codec
*codec
)
209 struct conexant_spec
*spec
= codec
->spec
;
210 struct hda_pcm
*info
= spec
->pcm_rec
;
213 codec
->pcm_info
= info
;
215 info
->name
= "CONEXANT Analog";
216 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = conexant_pcm_analog_playback
;
217 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].channels_max
=
218 spec
->multiout
.max_channels
;
219 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
=
220 spec
->multiout
.dac_nids
[0];
221 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = conexant_pcm_analog_capture
;
222 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].substreams
= spec
->num_adc_nids
;
223 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->adc_nids
[0];
225 if (spec
->multiout
.dig_out_nid
) {
228 info
->name
= "Conexant Digital";
229 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] =
230 conexant_pcm_digital_playback
;
231 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
=
232 spec
->multiout
.dig_out_nid
;
233 if (spec
->dig_in_nid
) {
234 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] =
235 conexant_pcm_digital_capture
;
236 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
=
244 static int conexant_mux_enum_info(struct snd_kcontrol
*kcontrol
,
245 struct snd_ctl_elem_info
*uinfo
)
247 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
248 struct conexant_spec
*spec
= codec
->spec
;
250 return snd_hda_input_mux_info(spec
->input_mux
, uinfo
);
253 static int conexant_mux_enum_get(struct snd_kcontrol
*kcontrol
,
254 struct snd_ctl_elem_value
*ucontrol
)
256 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
257 struct conexant_spec
*spec
= codec
->spec
;
258 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
260 ucontrol
->value
.enumerated
.item
[0] = spec
->cur_mux
[adc_idx
];
264 static int conexant_mux_enum_put(struct snd_kcontrol
*kcontrol
,
265 struct snd_ctl_elem_value
*ucontrol
)
267 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
268 struct conexant_spec
*spec
= codec
->spec
;
269 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
271 return snd_hda_input_mux_put(codec
, spec
->input_mux
, ucontrol
,
272 spec
->capsrc_nids
[adc_idx
],
273 &spec
->cur_mux
[adc_idx
]);
276 static int conexant_init(struct hda_codec
*codec
)
278 struct conexant_spec
*spec
= codec
->spec
;
281 for (i
= 0; i
< spec
->num_init_verbs
; i
++)
282 snd_hda_sequence_write(codec
, spec
->init_verbs
[i
]);
286 static void conexant_free(struct hda_codec
*codec
)
288 struct conexant_spec
*spec
= codec
->spec
;
291 if (spec
->kctl_alloc
) {
292 for (i
= 0; i
< spec
->num_kctl_used
; i
++)
293 kfree(spec
->kctl_alloc
[i
].name
);
294 kfree(spec
->kctl_alloc
);
301 static int conexant_resume(struct hda_codec
*codec
)
303 struct conexant_spec
*spec
= codec
->spec
;
306 codec
->patch_ops
.init(codec
);
307 for (i
= 0; i
< spec
->num_mixers
; i
++)
308 snd_hda_resume_ctls(codec
, spec
->mixers
[i
]);
309 if (spec
->multiout
.dig_out_nid
)
310 snd_hda_resume_spdif_out(codec
);
311 if (spec
->dig_in_nid
)
312 snd_hda_resume_spdif_in(codec
);
317 static int conexant_build_controls(struct hda_codec
*codec
)
319 struct conexant_spec
*spec
= codec
->spec
;
323 for (i
= 0; i
< spec
->num_mixers
; i
++) {
324 err
= snd_hda_add_new_ctls(codec
, spec
->mixers
[i
]);
328 if (spec
->multiout
.dig_out_nid
) {
329 err
= snd_hda_create_spdif_out_ctls(codec
,
330 spec
->multiout
.dig_out_nid
);
334 if (spec
->dig_in_nid
) {
335 err
= snd_hda_create_spdif_in_ctls(codec
,spec
->dig_in_nid
);
342 static struct hda_codec_ops conexant_patch_ops
= {
343 .build_controls
= conexant_build_controls
,
344 .build_pcms
= conexant_build_pcms
,
345 .init
= conexant_init
,
346 .free
= conexant_free
,
348 .resume
= conexant_resume
,
354 * the private value = nid | (invert << 8)
357 static int conexant_eapd_info(struct snd_kcontrol
*kcontrol
,
358 struct snd_ctl_elem_info
*uinfo
)
360 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
362 uinfo
->value
.integer
.min
= 0;
363 uinfo
->value
.integer
.max
= 1;
367 static int conexant_eapd_get(struct snd_kcontrol
*kcontrol
,
368 struct snd_ctl_elem_value
*ucontrol
)
370 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
371 struct conexant_spec
*spec
= codec
->spec
;
372 int invert
= (kcontrol
->private_value
>> 8) & 1;
374 ucontrol
->value
.integer
.value
[0] = !spec
->cur_eapd
;
376 ucontrol
->value
.integer
.value
[0] = spec
->cur_eapd
;
380 static int conexant_eapd_put(struct snd_kcontrol
*kcontrol
,
381 struct snd_ctl_elem_value
*ucontrol
)
383 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
384 struct conexant_spec
*spec
= codec
->spec
;
385 int invert
= (kcontrol
->private_value
>> 8) & 1;
386 hda_nid_t nid
= kcontrol
->private_value
& 0xff;
388 eapd
= ucontrol
->value
.integer
.value
[0];
391 if (eapd
== spec
->cur_eapd
&& !codec
->in_resume
)
393 spec
->cur_eapd
= eapd
;
394 snd_hda_codec_write(codec
, nid
,
395 0, AC_VERB_SET_EAPD_BTLENABLE
,
400 static int conexant_ch_mode_info(struct snd_kcontrol
*kcontrol
,
401 struct snd_ctl_elem_info
*uinfo
)
403 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
404 struct conexant_spec
*spec
= codec
->spec
;
405 return snd_hda_ch_mode_info(codec
, uinfo
, spec
->channel_mode
,
406 spec
->num_channel_mode
);
409 static int conexant_ch_mode_get(struct snd_kcontrol
*kcontrol
,
410 struct snd_ctl_elem_value
*ucontrol
)
412 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
413 struct conexant_spec
*spec
= codec
->spec
;
414 return snd_hda_ch_mode_get(codec
, ucontrol
, spec
->channel_mode
,
415 spec
->num_channel_mode
,
416 spec
->multiout
.max_channels
);
419 static int conexant_ch_mode_put(struct snd_kcontrol
*kcontrol
,
420 struct snd_ctl_elem_value
*ucontrol
)
422 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
423 struct conexant_spec
*spec
= codec
->spec
;
424 int err
= snd_hda_ch_mode_put(codec
, ucontrol
, spec
->channel_mode
,
425 spec
->num_channel_mode
,
426 &spec
->multiout
.max_channels
);
427 if (err
>= 0 && spec
->need_dac_fix
)
428 spec
->multiout
.num_dacs
= spec
->multiout
.max_channels
/ 2;
432 #define CXT_PIN_MODE(xname, nid, dir) \
433 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
434 .info = conexant_ch_mode_info, \
435 .get = conexant_ch_mode_get, \
436 .put = conexant_ch_mode_put, \
437 .private_value = nid | (dir<<16) }
439 static int cxt_gpio_data_info(struct snd_kcontrol
*kcontrol
,
440 struct snd_ctl_elem_info
*uinfo
)
442 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
444 uinfo
->value
.integer
.min
= 0;
445 uinfo
->value
.integer
.max
= 1;
449 static int cxt_gpio_data_get(struct snd_kcontrol
*kcontrol
,
450 struct snd_ctl_elem_value
*ucontrol
)
452 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
453 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
454 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
455 long *valp
= ucontrol
->value
.integer
.value
;
456 unsigned int val
= snd_hda_codec_read(codec
, nid
, 0,
457 AC_VERB_GET_GPIO_DATA
, 0x00);
459 *valp
= (val
& mask
) != 0;
463 static int cxt_gpio_data_put(struct snd_kcontrol
*kcontrol
,
464 struct snd_ctl_elem_value
*ucontrol
)
466 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
467 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
468 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
469 long val
= *ucontrol
->value
.integer
.value
;
470 unsigned int gpio_data
= snd_hda_codec_read(codec
, nid
, 0,
471 AC_VERB_GET_GPIO_DATA
,
473 unsigned int old_data
= gpio_data
;
475 /* Set/unset the masked GPIO bit(s) as needed */
480 if (gpio_data
== old_data
&& !codec
->in_resume
)
482 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_GPIO_DATA
, gpio_data
);
486 #define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \
487 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
488 .info = cxt_gpio_data_info, \
489 .get = cxt_gpio_data_get, \
490 .put = cxt_gpio_data_put, \
491 .private_value = nid | (mask<<16) }
493 static int cxt_spdif_ctrl_info(struct snd_kcontrol
*kcontrol
,
494 struct snd_ctl_elem_info
*uinfo
)
496 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
498 uinfo
->value
.integer
.min
= 0;
499 uinfo
->value
.integer
.max
= 1;
503 static int cxt_spdif_ctrl_get(struct snd_kcontrol
*kcontrol
,
504 struct snd_ctl_elem_value
*ucontrol
)
506 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
507 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
508 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
509 long *valp
= ucontrol
->value
.integer
.value
;
510 unsigned int val
= snd_hda_codec_read(codec
, nid
, 0,
511 AC_VERB_GET_DIGI_CONVERT
, 0x00);
513 *valp
= (val
& mask
) != 0;
517 static int cxt_spdif_ctrl_put(struct snd_kcontrol
*kcontrol
,
518 struct snd_ctl_elem_value
*ucontrol
)
520 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
521 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
522 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
523 long val
= *ucontrol
->value
.integer
.value
;
524 unsigned int ctrl_data
= snd_hda_codec_read(codec
, nid
, 0,
525 AC_VERB_GET_DIGI_CONVERT
,
527 unsigned int old_data
= ctrl_data
;
529 /* Set/unset the masked control bit(s) as needed */
534 if (ctrl_data
== old_data
&& !codec
->in_resume
)
536 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_DIGI_CONVERT_1
,
541 #define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \
542 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
543 .info = cxt_spdif_ctrl_info, \
544 .get = cxt_spdif_ctrl_get, \
545 .put = cxt_spdif_ctrl_put, \
546 .private_value = nid | (mask<<16) }
548 /* Conexant 5045 specific */
550 static hda_nid_t cxt5045_dac_nids
[1] = { 0x19 };
551 static hda_nid_t cxt5045_adc_nids
[1] = { 0x1a };
552 static hda_nid_t cxt5045_capsrc_nids
[1] = { 0x1a };
553 #define CXT5045_SPDIF_OUT 0x13
555 static struct hda_channel_mode cxt5045_modes
[1] = {
559 static struct hda_input_mux cxt5045_capture_source
= {
567 /* turn on/off EAPD (+ mute HP) as a master switch */
568 static int cxt5045_hp_master_sw_put(struct snd_kcontrol
*kcontrol
,
569 struct snd_ctl_elem_value
*ucontrol
)
571 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
572 struct conexant_spec
*spec
= codec
->spec
;
574 if (!conexant_eapd_put(kcontrol
, ucontrol
))
577 /* toggle HP mute appropriately */
578 snd_hda_codec_amp_update(codec
, 0x11, 0, HDA_OUTPUT
, 0,
579 0x80, spec
->cur_eapd
? 0 : 0x80);
580 snd_hda_codec_amp_update(codec
, 0x11, 1, HDA_OUTPUT
, 0,
581 0x80, spec
->cur_eapd
? 0 : 0x80);
585 /* bind volumes of both NID 0x10 and 0x11 */
586 static int cxt5045_hp_master_vol_put(struct snd_kcontrol
*kcontrol
,
587 struct snd_ctl_elem_value
*ucontrol
)
589 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
590 long *valp
= ucontrol
->value
.integer
.value
;
593 change
= snd_hda_codec_amp_update(codec
, 0x10, 0, HDA_OUTPUT
, 0,
594 0x7f, valp
[0] & 0x7f);
595 change
|= snd_hda_codec_amp_update(codec
, 0x10, 1, HDA_OUTPUT
, 0,
596 0x7f, valp
[1] & 0x7f);
597 snd_hda_codec_amp_update(codec
, 0x11, 0, HDA_OUTPUT
, 0,
598 0x7f, valp
[0] & 0x7f);
599 snd_hda_codec_amp_update(codec
, 0x11, 1, HDA_OUTPUT
, 0,
600 0x7f, valp
[1] & 0x7f);
605 /* mute internal speaker if HP is plugged */
606 static void cxt5045_hp_automute(struct hda_codec
*codec
)
608 unsigned int present
;
610 present
= snd_hda_codec_read(codec
, 0x11, 0,
611 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
612 snd_hda_codec_amp_update(codec
, 0x10, 0, HDA_OUTPUT
, 0,
613 0x80, present
? 0x80 : 0);
614 snd_hda_codec_amp_update(codec
, 0x10, 1, HDA_OUTPUT
, 0,
615 0x80, present
? 0x80 : 0);
618 /* unsolicited event for HP jack sensing */
619 static void cxt5045_hp_unsol_event(struct hda_codec
*codec
,
624 case CONEXANT_HP_EVENT
:
625 cxt5045_hp_automute(codec
);
630 static struct snd_kcontrol_new cxt5045_mixers
[] = {
632 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
633 .name
= "Capture Source",
634 .info
= conexant_mux_enum_info
,
635 .get
= conexant_mux_enum_get
,
636 .put
= conexant_mux_enum_put
638 HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x17, 0x02, HDA_INPUT
),
639 HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x17, 0x02, HDA_INPUT
),
640 HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x02, HDA_INPUT
),
641 HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x02, HDA_INPUT
),
643 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
644 .name
= "Master Playback Volume",
645 .info
= snd_hda_mixer_amp_volume_info
,
646 .get
= snd_hda_mixer_amp_volume_get
,
647 .put
= cxt5045_hp_master_vol_put
,
648 .private_value
= HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT
),
651 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
652 .name
= "Master Playback Switch",
653 .info
= conexant_eapd_info
,
654 .get
= conexant_eapd_get
,
655 .put
= cxt5045_hp_master_sw_put
,
656 .private_value
= 0x11,
662 static struct hda_verb cxt5045_init_verbs
[] = {
664 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
665 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
|AC_PINCTL_VREF_50
},
667 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
668 {0x1A, AC_VERB_SET_CONNECT_SEL
,0x01},
669 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE
,
670 AC_AMP_SET_OUTPUT
|AC_AMP_SET_RIGHT
|AC_AMP_SET_LEFT
|0x00},
671 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE
,
672 AC_AMP_SET_OUTPUT
|AC_AMP_SET_RIGHT
|AC_AMP_SET_LEFT
|0x03},
673 /* Record selector: Front mic */
674 {0x14, AC_VERB_SET_CONNECT_SEL
,0x03},
675 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
,
676 AC_AMP_SET_INPUT
|AC_AMP_SET_RIGHT
|AC_AMP_SET_LEFT
|0x17},
677 /* SPDIF route: PCM */
678 { 0x13, AC_VERB_SET_CONNECT_SEL
, 0x0 },
679 /* pin sensing on HP and Mic jacks */
680 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| CONEXANT_HP_EVENT
},
682 {0x10, AC_VERB_SET_EAPD_BTLENABLE
, 0x0 }, /* default on */
686 #ifdef CONFIG_SND_DEBUG
687 /* Test configuration for debugging, modelled after the ALC260 test
690 static struct hda_input_mux cxt5045_test_capture_source
= {
695 { "LINE1 pin", 0x2 },
696 { "HP-OUT pin", 0x3 },
701 static struct snd_kcontrol_new cxt5045_test_mixer
[] = {
703 /* Output controls */
704 HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x19, 0x00, HDA_OUTPUT
),
705 HDA_CODEC_MUTE("OutAmp-1 Switch", 0x19,0x00, HDA_OUTPUT
),
706 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT
),
707 HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT
),
709 /* Modes for retasking pin widgets */
710 CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT
),
711 CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT
),
713 /* Loopback mixer controls */
714 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT
),
715 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT
),
716 HDA_CODEC_VOLUME("LINE loopback Playback Volume", 0x17, 0x02, HDA_INPUT
),
717 HDA_CODEC_MUTE("LINE loopback Playback Switch", 0x17, 0x02, HDA_INPUT
),
718 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x17, 0x03, HDA_INPUT
),
719 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x17, 0x03, HDA_INPUT
),
720 HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT
),
721 HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT
),
723 /* Controls for GPIO pins, assuming they exist and are configured as outputs */
724 CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
725 #if 0 /* limit this to one GPIO pin for now */
726 CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
727 CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
728 CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
730 CXT_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x13, 0x01),
732 HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_OUTPUT
),
733 HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_OUTPUT
),
735 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
736 .name
= "Input Source",
737 .info
= conexant_mux_enum_info
,
738 .get
= conexant_mux_enum_get
,
739 .put
= conexant_mux_enum_put
,
745 static struct hda_verb cxt5045_test_init_verbs
[] = {
746 /* Enable all GPIOs as outputs with an initial value of 0 */
747 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x0f},
748 {0x01, AC_VERB_SET_GPIO_DATA
, 0x00},
749 {0x01, AC_VERB_SET_GPIO_MASK
, 0x0f},
751 /* Enable retasking pins as output, initially without power amp */
752 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
753 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
755 /* Disable digital (SPDIF) pins initially, but users can enable
756 * them via a mixer switch. In the case of SPDIF-out, this initverb
757 * payload also sets the generation to 0, output to be in "consumer"
758 * PCM format, copyright asserted, no pre-emphasis and no validity
761 {0x13, AC_VERB_SET_DIGI_CONVERT_1
, 0},
763 /* Start with output sum widgets muted and their output gains at min */
764 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
765 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
767 /* Unmute retasking pin widget output buffers since the default
768 * state appears to be output. As the pin mode is changed by the
769 * user the pin mode control will take care of enabling the pin's
770 * input/output buffers as needed.
772 {0x12, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
773 {0x11, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
775 /* Mute capture amp left and right */
776 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
778 /* Set ADC connection select to match default mixer setting (mic1
781 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x00},
783 /* Mute all inputs to mixer widget (even unconnected ones) */
784 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* Mixer pin */
785 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)}, /* Mic1 pin */
786 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)}, /* Line pin */
787 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)}, /* HP pin */
788 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)}, /* CD pin */
795 /* initialize jack-sensing, too */
796 static int cxt5045_init(struct hda_codec
*codec
)
798 conexant_init(codec
);
799 cxt5045_hp_automute(codec
);
805 CXT5045_LAPTOP
, /* Laptops w/ EAPD support */
806 #ifdef CONFIG_SND_DEBUG
812 static const char *cxt5045_models
[CXT5045_MODELS
] = {
813 [CXT5045_LAPTOP
] = "laptop",
814 #ifdef CONFIG_SND_DEBUG
815 [CXT5045_TEST
] = "test",
819 static struct snd_pci_quirk cxt5045_cfg_tbl
[] = {
820 SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP
),
824 static int patch_cxt5045(struct hda_codec
*codec
)
826 struct conexant_spec
*spec
;
829 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
832 mutex_init(&spec
->amp_mutex
);
835 spec
->multiout
.max_channels
= 2;
836 spec
->multiout
.num_dacs
= ARRAY_SIZE(cxt5045_dac_nids
);
837 spec
->multiout
.dac_nids
= cxt5045_dac_nids
;
838 spec
->multiout
.dig_out_nid
= CXT5045_SPDIF_OUT
;
839 spec
->num_adc_nids
= 1;
840 spec
->adc_nids
= cxt5045_adc_nids
;
841 spec
->capsrc_nids
= cxt5045_capsrc_nids
;
842 spec
->input_mux
= &cxt5045_capture_source
;
843 spec
->num_mixers
= 1;
844 spec
->mixers
[0] = cxt5045_mixers
;
845 spec
->num_init_verbs
= 1;
846 spec
->init_verbs
[0] = cxt5045_init_verbs
;
847 spec
->spdif_route
= 0;
848 spec
->num_channel_mode
= ARRAY_SIZE(cxt5045_modes
),
849 spec
->channel_mode
= cxt5045_modes
,
852 codec
->patch_ops
= conexant_patch_ops
;
853 codec
->patch_ops
.unsol_event
= cxt5045_hp_unsol_event
;
855 board_config
= snd_hda_check_board_config(codec
, CXT5045_MODELS
,
858 switch (board_config
) {
860 spec
->input_mux
= &cxt5045_capture_source
;
861 spec
->num_init_verbs
= 2;
862 spec
->init_verbs
[1] = cxt5045_init_verbs
;
863 spec
->mixers
[0] = cxt5045_mixers
;
864 codec
->patch_ops
.init
= cxt5045_init
;
866 #ifdef CONFIG_SND_DEBUG
868 spec
->input_mux
= &cxt5045_test_capture_source
;
869 spec
->mixers
[0] = cxt5045_test_mixer
;
870 spec
->init_verbs
[0] = cxt5045_test_init_verbs
;
877 /* Conexant 5047 specific */
879 static hda_nid_t cxt5047_dac_nids
[1] = { 0x10 };
880 static hda_nid_t cxt5047_adc_nids
[1] = { 0x12 };
881 static hda_nid_t cxt5047_capsrc_nids
[1] = { 0x1a };
882 #define CXT5047_SPDIF_OUT 0x11
884 static struct hda_channel_mode cxt5047_modes
[1] = {
888 static struct hda_input_mux cxt5047_capture_source
= {
896 static struct hda_input_mux cxt5047_hp_capture_source
= {
903 /* turn on/off EAPD (+ mute HP) as a master switch */
904 static int cxt5047_hp_master_sw_put(struct snd_kcontrol
*kcontrol
,
905 struct snd_ctl_elem_value
*ucontrol
)
907 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
908 struct conexant_spec
*spec
= codec
->spec
;
910 if (!conexant_eapd_put(kcontrol
, ucontrol
))
913 /* toggle HP mute appropriately */
914 snd_hda_codec_amp_update(codec
, 0x13, 0, HDA_OUTPUT
, 0,
915 0x80, spec
->cur_eapd
? 0 : 0x80);
916 snd_hda_codec_amp_update(codec
, 0x13, 1, HDA_OUTPUT
, 0,
917 0x80, spec
->cur_eapd
? 0 : 0x80);
922 /* bind volumes of both NID 0x13 and 0x1d */
923 static int cxt5047_hp_master_vol_put(struct snd_kcontrol
*kcontrol
,
924 struct snd_ctl_elem_value
*ucontrol
)
926 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
927 long *valp
= ucontrol
->value
.integer
.value
;
930 change
= snd_hda_codec_amp_update(codec
, 0x1c, 0, HDA_OUTPUT
, 0,
931 0x7f, valp
[0] & 0x7f);
932 change
|= snd_hda_codec_amp_update(codec
, 0x1c, 1, HDA_OUTPUT
, 0,
933 0x7f, valp
[1] & 0x7f);
934 snd_hda_codec_amp_update(codec
, 0x13, 0, HDA_OUTPUT
, 0,
935 0x7f, valp
[0] & 0x7f);
936 snd_hda_codec_amp_update(codec
, 0x13, 1, HDA_OUTPUT
, 0,
937 0x7f, valp
[1] & 0x7f);
942 /* mute internal speaker if HP is plugged */
943 static void cxt5047_hp_automute(struct hda_codec
*codec
)
945 unsigned int present
;
947 present
= snd_hda_codec_read(codec
, 0x13, 0,
948 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
949 snd_hda_codec_amp_update(codec
, 0x1c, 0, HDA_OUTPUT
, 0,
950 0x80, present
? 0x80 : 0);
951 snd_hda_codec_amp_update(codec
, 0x1c, 1, HDA_OUTPUT
, 0,
952 0x80, present
? 0x80 : 0);
955 /* toggle input of built-in and mic jack appropriately */
956 static void cxt5047_hp_automic(struct hda_codec
*codec
)
958 static struct hda_verb mic_jack_on
[] = {
959 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb080},
960 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
963 static struct hda_verb mic_jack_off
[] = {
964 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb080},
965 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
968 unsigned int present
;
970 present
= snd_hda_codec_read(codec
, 0x08, 0,
971 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
973 snd_hda_sequence_write(codec
, mic_jack_on
);
975 snd_hda_sequence_write(codec
, mic_jack_off
);
978 /* unsolicited event for HP jack sensing */
979 static void cxt5047_hp_unsol_event(struct hda_codec
*codec
,
984 case CONEXANT_HP_EVENT
:
985 cxt5047_hp_automute(codec
);
987 case CONEXANT_MIC_EVENT
:
988 cxt5047_hp_automic(codec
);
993 static struct snd_kcontrol_new cxt5047_mixers
[] = {
995 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
996 .name
= "Capture Source",
997 .info
= conexant_mux_enum_info
,
998 .get
= conexant_mux_enum_get
,
999 .put
= conexant_mux_enum_put
1001 HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT
),
1002 HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT
),
1003 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT
),
1004 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT
),
1005 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT
),
1006 HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT
),
1007 HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT
),
1009 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1010 .name
= "Master Playback Switch",
1011 .info
= conexant_eapd_info
,
1012 .get
= conexant_eapd_get
,
1013 .put
= cxt5047_hp_master_sw_put
,
1014 .private_value
= 0x13,
1020 static struct snd_kcontrol_new cxt5047_hp_mixers
[] = {
1022 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1023 .name
= "Capture Source",
1024 .info
= conexant_mux_enum_info
,
1025 .get
= conexant_mux_enum_get
,
1026 .put
= conexant_mux_enum_put
1028 HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT
),
1029 HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19,0x02,HDA_INPUT
),
1030 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT
),
1031 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT
),
1032 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT
),
1033 HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT
),
1034 HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT
),
1036 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1037 .name
= "Master Playback Switch",
1038 .info
= conexant_eapd_info
,
1039 .get
= conexant_eapd_get
,
1040 .put
= cxt5047_hp_master_sw_put
,
1041 .private_value
= 0x13,
1046 static struct hda_verb cxt5047_init_verbs
[] = {
1047 /* Line in, Mic, Built-in Mic */
1048 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1049 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
|AC_PINCTL_VREF_50
},
1050 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
|AC_PINCTL_VREF_50
},
1052 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1053 {0x1A, AC_VERB_SET_CONNECT_SEL
,0x03},
1054 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE
,
1055 AC_AMP_SET_OUTPUT
|AC_AMP_SET_RIGHT
|AC_AMP_SET_LEFT
|0x00},
1056 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE
,
1057 AC_AMP_SET_OUTPUT
|AC_AMP_SET_RIGHT
|AC_AMP_SET_LEFT
|0x03},
1058 /* Record selector: Front mic */
1059 {0x12, AC_VERB_SET_CONNECT_SEL
,0x03},
1060 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
,
1061 AC_AMP_SET_INPUT
|AC_AMP_SET_RIGHT
|AC_AMP_SET_LEFT
|0x17},
1062 /* SPDIF route: PCM */
1063 { 0x18, AC_VERB_SET_CONNECT_SEL
, 0x0 },
1067 /* configuration for Toshiba Laptops */
1068 static struct hda_verb cxt5047_toshiba_init_verbs
[] = {
1069 {0x13, AC_VERB_SET_EAPD_BTLENABLE
, 0x0 }, /* default on */
1070 /* pin sensing on HP and Mic jacks */
1071 {0x13, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| CONEXANT_HP_EVENT
},
1072 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| CONEXANT_MIC_EVENT
},
1076 /* configuration for HP Laptops */
1077 static struct hda_verb cxt5047_hp_init_verbs
[] = {
1078 /* pin sensing on HP and Mic jacks */
1079 {0x13, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| CONEXANT_HP_EVENT
},
1080 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| CONEXANT_MIC_EVENT
},
1084 /* Test configuration for debugging, modelled after the ALC260 test
1087 #ifdef CONFIG_SND_DEBUG
1088 static struct hda_input_mux cxt5047_test_capture_source
= {
1092 { "LINE1 pin", 0x1 },
1093 { "MIC1 pin", 0x2 },
1094 { "MIC2 pin", 0x3 },
1099 static struct snd_kcontrol_new cxt5047_test_mixer
[] = {
1101 /* Output only controls */
1102 HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x00, HDA_OUTPUT
),
1103 HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x00, HDA_OUTPUT
),
1104 HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x00, HDA_OUTPUT
),
1105 HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x00, HDA_OUTPUT
),
1106 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT
),
1107 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT
),
1108 HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT
),
1109 HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT
),
1111 /* Modes for retasking pin widgets */
1112 CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT
),
1113 CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT
),
1115 /* Loopback mixer controls */
1116 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x19, 0x02, HDA_INPUT
),
1117 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x19, 0x02, HDA_INPUT
),
1118 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x19, 0x03, HDA_INPUT
),
1119 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x19, 0x03, HDA_INPUT
),
1120 HDA_CODEC_VOLUME("LINE Playback Volume", 0x19, 0x01, HDA_INPUT
),
1121 HDA_CODEC_MUTE("LINE Playback Switch", 0x19, 0x01, HDA_INPUT
),
1122 HDA_CODEC_VOLUME("CD Playback Volume", 0x19, 0x04, HDA_INPUT
),
1123 HDA_CODEC_MUTE("CD Playback Switch", 0x19, 0x04, HDA_INPUT
),
1126 /* Controls for GPIO pins, assuming they exist and are configured as outputs */
1127 CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
1128 CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
1129 CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
1130 CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
1132 CXT_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x18, 0x01),
1134 HDA_CODEC_VOLUME("Capture Volume", 0x19, 0x0, HDA_OUTPUT
),
1135 HDA_CODEC_MUTE("Capture Switch", 0x19, 0x0, HDA_OUTPUT
),
1137 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1138 .name
= "Input Source",
1139 .info
= conexant_mux_enum_info
,
1140 .get
= conexant_mux_enum_get
,
1141 .put
= conexant_mux_enum_put
,
1147 static struct hda_verb cxt5047_test_init_verbs
[] = {
1148 /* Enable all GPIOs as outputs with an initial value of 0 */
1149 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x0f},
1150 {0x01, AC_VERB_SET_GPIO_DATA
, 0x00},
1151 {0x01, AC_VERB_SET_GPIO_MASK
, 0x0f},
1153 /* Enable retasking pins as output, initially without power amp */
1154 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1155 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1156 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1158 /* Disable digital (SPDIF) pins initially, but users can enable
1159 * them via a mixer switch. In the case of SPDIF-out, this initverb
1160 * payload also sets the generation to 0, output to be in "consumer"
1161 * PCM format, copyright asserted, no pre-emphasis and no validity
1164 {0x18, AC_VERB_SET_DIGI_CONVERT_1
, 0},
1166 /* Ensure mic1, mic2, line1 pin widgets take input from the
1167 * OUT1 sum bus when acting as an output.
1169 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0},
1170 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0},
1172 /* Start with output sum widgets muted and their output gains at min */
1173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
1174 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
1176 /* Unmute retasking pin widget output buffers since the default
1177 * state appears to be output. As the pin mode is changed by the
1178 * user the pin mode control will take care of enabling the pin's
1179 * input/output buffers as needed.
1181 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1182 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1183 {0x13, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1185 /* Mute capture amp left and right */
1186 {0x12, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
1188 /* Set ADC connection select to match default mixer setting (mic1
1191 {0x12, AC_VERB_SET_CONNECT_SEL
, 0x00},
1193 /* Mute all inputs to mixer widget (even unconnected ones) */
1194 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* mic1 pin */
1195 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)}, /* mic2 pin */
1196 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)}, /* line1 pin */
1197 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)}, /* line2 pin */
1198 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)}, /* CD pin */
1199 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1200 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)}, /* Line-out pin */
1201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)}, /* HP-pin pin */
1208 /* initialize jack-sensing, too */
1209 static int cxt5047_hp_init(struct hda_codec
*codec
)
1211 conexant_init(codec
);
1212 cxt5047_hp_automute(codec
);
1213 cxt5047_hp_automic(codec
);
1219 CXT5047_LAPTOP
, /* Laptops w/o EAPD support */
1220 CXT5047_LAPTOP_HP
, /* Some HP laptops */
1221 CXT5047_LAPTOP_EAPD
, /* Laptops with EAPD support */
1222 #ifdef CONFIG_SND_DEBUG
1228 static const char *cxt5047_models
[CXT5047_MODELS
] = {
1229 [CXT5047_LAPTOP
] = "laptop",
1230 [CXT5047_LAPTOP_HP
] = "laptop-hp",
1231 [CXT5047_LAPTOP_EAPD
] = "laptop-eapd",
1232 #ifdef CONFIG_SND_DEBUG
1233 [CXT5047_TEST
] = "test",
1237 static struct snd_pci_quirk cxt5047_cfg_tbl
[] = {
1238 SND_PCI_QUIRK(0x103c, 0x30a0, "HP DV1000", CXT5047_LAPTOP
),
1239 SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV2000T/DV3000T", CXT5047_LAPTOP
),
1240 SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP
),
1241 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD
),
1245 static int patch_cxt5047(struct hda_codec
*codec
)
1247 struct conexant_spec
*spec
;
1250 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1253 mutex_init(&spec
->amp_mutex
);
1256 spec
->multiout
.max_channels
= 2;
1257 spec
->multiout
.num_dacs
= ARRAY_SIZE(cxt5047_dac_nids
);
1258 spec
->multiout
.dac_nids
= cxt5047_dac_nids
;
1259 spec
->multiout
.dig_out_nid
= CXT5047_SPDIF_OUT
;
1260 spec
->num_adc_nids
= 1;
1261 spec
->adc_nids
= cxt5047_adc_nids
;
1262 spec
->capsrc_nids
= cxt5047_capsrc_nids
;
1263 spec
->input_mux
= &cxt5047_capture_source
;
1264 spec
->num_mixers
= 1;
1265 spec
->mixers
[0] = cxt5047_mixers
;
1266 spec
->num_init_verbs
= 1;
1267 spec
->init_verbs
[0] = cxt5047_init_verbs
;
1268 spec
->spdif_route
= 0;
1269 spec
->num_channel_mode
= ARRAY_SIZE(cxt5047_modes
),
1270 spec
->channel_mode
= cxt5047_modes
,
1272 codec
->patch_ops
= conexant_patch_ops
;
1273 codec
->patch_ops
.unsol_event
= cxt5047_hp_unsol_event
;
1275 board_config
= snd_hda_check_board_config(codec
, CXT5047_MODELS
,
1278 switch (board_config
) {
1279 case CXT5047_LAPTOP
:
1281 case CXT5047_LAPTOP_HP
:
1282 spec
->input_mux
= &cxt5047_hp_capture_source
;
1283 spec
->num_init_verbs
= 2;
1284 spec
->init_verbs
[1] = cxt5047_hp_init_verbs
;
1285 spec
->mixers
[0] = cxt5047_hp_mixers
;
1286 codec
->patch_ops
.init
= cxt5047_hp_init
;
1288 case CXT5047_LAPTOP_EAPD
:
1289 spec
->num_init_verbs
= 2;
1290 spec
->init_verbs
[1] = cxt5047_toshiba_init_verbs
;
1292 #ifdef CONFIG_SND_DEBUG
1294 spec
->input_mux
= &cxt5047_test_capture_source
;
1295 spec
->mixers
[0] = cxt5047_test_mixer
;
1296 spec
->init_verbs
[0] = cxt5047_test_init_verbs
;
1302 struct hda_codec_preset snd_hda_preset_conexant
[] = {
1303 { .id
= 0x14f15045, .name
= "CXT5045", .patch
= patch_cxt5045
},
1304 { .id
= 0x14f15047, .name
= "CXT5047", .patch
= patch_cxt5047
},