2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for C-Media CMI9880
6 * Copyright (c) 2004 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 #include <sound/driver.h>
25 #include <linux/init.h>
26 #include <linux/delay.h>
27 #include <linux/slab.h>
28 #include <linux/pci.h>
29 #include <sound/core.h>
30 #include "hda_codec.h"
31 #include "hda_local.h"
34 /* board config type */
36 CMI_MINIMAL
, /* back 3-jack */
37 CMI_MIN_FP
, /* back 3-jack + front-panel 2-jack */
38 CMI_FULL
, /* back 6-jack + front-panel 2-jack */
39 CMI_FULL_DIG
, /* back 6-jack + front-panel 2-jack + digital I/O */
40 CMI_ALLOUT
, /* back 5-jack + front-panel 2-jack + digital out */
45 unsigned int surr_switch
: 1; /* switchable line,mic */
46 unsigned int no_line_in
: 1; /* no line-in (5-jack) */
47 unsigned int front_panel
: 1; /* has front-panel 2-jack */
50 struct hda_multi_out multiout
;
57 const struct hda_input_mux
*input_mux
;
58 unsigned int cur_mux
[2];
61 unsigned int num_ch_modes
;
62 unsigned int cur_ch_mode
;
63 const struct cmi_channel_mode
*channel_modes
;
65 struct hda_pcm pcm_rec
[2]; /* PCM information */
71 static int cmi_mux_enum_info(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_info_t
*uinfo
)
73 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
74 struct cmi_spec
*spec
= codec
->spec
;
75 return snd_hda_input_mux_info(spec
->input_mux
, uinfo
);
78 static int cmi_mux_enum_get(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_value_t
*ucontrol
)
80 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
81 struct cmi_spec
*spec
= codec
->spec
;
82 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
84 ucontrol
->value
.enumerated
.item
[0] = spec
->cur_mux
[adc_idx
];
88 static int cmi_mux_enum_put(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_value_t
*ucontrol
)
90 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
91 struct cmi_spec
*spec
= codec
->spec
;
92 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
94 return snd_hda_input_mux_put(codec
, spec
->input_mux
, ucontrol
,
95 spec
->adc_nids
[adc_idx
], &spec
->cur_mux
[adc_idx
]);
99 * shared line-in, mic for surrounds
102 /* 3-stack / 2 channel */
103 static struct hda_verb cmi9880_ch2_init
[] = {
104 /* set line-in PIN for input */
105 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
106 /* set mic PIN for input, also enable vref */
107 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
108 /* route front PCM (DAC1) to HP */
109 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
113 /* 3-stack / 6 channel */
114 static struct hda_verb cmi9880_ch6_init
[] = {
115 /* set line-in PIN for output */
116 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
117 /* set mic PIN for output */
118 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
119 /* route front PCM (DAC1) to HP */
120 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
124 /* 3-stack+front / 8 channel */
125 static struct hda_verb cmi9880_ch8_init
[] = {
126 /* set line-in PIN for output */
127 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
128 /* set mic PIN for output */
129 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
130 /* route rear-surround PCM (DAC4) to HP */
131 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x03 },
135 struct cmi_channel_mode
{
136 unsigned int channels
;
137 const struct hda_verb
*sequence
;
140 static struct cmi_channel_mode cmi9880_channel_modes
[3] = {
141 { 2, cmi9880_ch2_init
},
142 { 6, cmi9880_ch6_init
},
143 { 8, cmi9880_ch8_init
},
146 static int cmi_ch_mode_info(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_info_t
*uinfo
)
148 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
149 struct cmi_spec
*spec
= codec
->spec
;
151 snd_assert(spec
->channel_modes
, return -EINVAL
);
152 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
154 uinfo
->value
.enumerated
.items
= spec
->num_ch_modes
;
155 if (uinfo
->value
.enumerated
.item
>= uinfo
->value
.enumerated
.items
)
156 uinfo
->value
.enumerated
.item
= uinfo
->value
.enumerated
.items
- 1;
157 sprintf(uinfo
->value
.enumerated
.name
, "%dch",
158 spec
->channel_modes
[uinfo
->value
.enumerated
.item
].channels
);
162 static int cmi_ch_mode_get(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_value_t
*ucontrol
)
164 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
165 struct cmi_spec
*spec
= codec
->spec
;
167 ucontrol
->value
.enumerated
.item
[0] = spec
->cur_ch_mode
;
171 static int cmi_ch_mode_put(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_value_t
*ucontrol
)
173 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
174 struct cmi_spec
*spec
= codec
->spec
;
176 snd_assert(spec
->channel_modes
, return -EINVAL
);
177 if (ucontrol
->value
.enumerated
.item
[0] >= spec
->num_ch_modes
)
178 ucontrol
->value
.enumerated
.item
[0] = spec
->num_ch_modes
;
179 if (ucontrol
->value
.enumerated
.item
[0] == spec
->cur_ch_mode
&&
183 spec
->cur_ch_mode
= ucontrol
->value
.enumerated
.item
[0];
184 snd_hda_sequence_write(codec
, spec
->channel_modes
[spec
->cur_ch_mode
].sequence
);
185 spec
->multiout
.max_channels
= spec
->channel_modes
[spec
->cur_ch_mode
].channels
;
191 static snd_kcontrol_new_t cmi9880_basic_mixer
[] = {
192 /* CMI9880 has no playback volumes! */
193 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT
), /* front */
194 HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT
),
195 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT
),
196 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT
),
197 HDA_CODEC_MUTE("Side Playback Switch", 0x06, 0x0, HDA_OUTPUT
),
199 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
200 /* The multiple "Capture Source" controls confuse alsamixer
201 * So call somewhat different..
202 * FIXME: the controls appear in the "playback" view!
204 /* .name = "Capture Source", */
205 .name
= "Input Source",
207 .info
= cmi_mux_enum_info
,
208 .get
= cmi_mux_enum_get
,
209 .put
= cmi_mux_enum_put
,
211 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0, HDA_INPUT
),
212 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0, HDA_INPUT
),
213 HDA_CODEC_MUTE("Capture Switch", 0x08, 0, HDA_INPUT
),
214 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0, HDA_INPUT
),
215 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x23, 0, HDA_OUTPUT
),
216 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x23, 0, HDA_OUTPUT
),
223 static snd_kcontrol_new_t cmi9880_ch_mode_mixer
[] = {
225 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
226 .name
= "Channel Mode",
227 .info
= cmi_ch_mode_info
,
228 .get
= cmi_ch_mode_get
,
229 .put
= cmi_ch_mode_put
,
234 /* AUD-in selections:
235 * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20
237 static struct hda_input_mux cmi9880_basic_mux
= {
240 { "Front Mic", 0x5 },
247 static struct hda_input_mux cmi9880_no_line_mux
= {
250 { "Front Mic", 0x5 },
256 /* front, rear, clfe, rear_surr */
257 static hda_nid_t cmi9880_dac_nids
[4] = {
258 0x03, 0x04, 0x05, 0x06
261 static hda_nid_t cmi9880_adc_nids
[2] = {
265 #define CMI_DIG_OUT_NID 0x07
266 #define CMI_DIG_IN_NID 0x0a
270 static struct hda_verb cmi9880_basic_init
[] = {
271 /* port-D for line out (rear panel) */
272 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
273 /* port-E for HP out (front panel) */
274 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
275 /* route front PCM to HP */
276 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
277 /* port-A for surround (rear panel) */
278 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
279 /* port-G for CLFE (rear panel) */
280 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
281 /* port-H for side (rear panel) */
282 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
283 /* port-C for line-in (rear panel) */
284 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
285 /* port-B for mic-in (rear panel) with vref */
286 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
287 /* port-F for mic-in (front panel) with vref */
288 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
290 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
291 /* route front mic to ADC1/2 */
292 { 0x08, AC_VERB_SET_CONNECT_SEL
, 0x05 },
293 { 0x09, AC_VERB_SET_CONNECT_SEL
, 0x05 },
297 static struct hda_verb cmi9880_allout_init
[] = {
298 /* port-D for line out (rear panel) */
299 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
300 /* port-E for HP out (front panel) */
301 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
302 /* route front PCM to HP */
303 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
304 /* port-A for side (rear panel) */
305 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
306 /* port-G for CLFE (rear panel) */
307 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
308 /* port-C for surround (rear panel) */
309 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
310 /* port-B for mic-in (rear panel) with vref */
311 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
312 /* port-F for mic-in (front panel) with vref */
313 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
315 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
316 /* route front mic to ADC1/2 */
317 { 0x08, AC_VERB_SET_CONNECT_SEL
, 0x05 },
318 { 0x09, AC_VERB_SET_CONNECT_SEL
, 0x05 },
324 static int cmi9880_build_controls(struct hda_codec
*codec
)
326 struct cmi_spec
*spec
= codec
->spec
;
329 err
= snd_hda_add_new_ctls(codec
, cmi9880_basic_mixer
);
332 if (spec
->surr_switch
) {
333 err
= snd_hda_add_new_ctls(codec
, cmi9880_ch_mode_mixer
);
337 if (spec
->multiout
.dig_out_nid
) {
338 err
= snd_hda_create_spdif_out_ctls(codec
, spec
->multiout
.dig_out_nid
);
342 if (spec
->dig_in_nid
) {
343 err
= snd_hda_create_spdif_in_ctls(codec
, spec
->dig_in_nid
);
350 static int cmi9880_init(struct hda_codec
*codec
)
352 struct cmi_spec
*spec
= codec
->spec
;
353 if (spec
->board_config
== CMI_ALLOUT
)
354 snd_hda_sequence_write(codec
, cmi9880_allout_init
);
356 snd_hda_sequence_write(codec
, cmi9880_basic_init
);
364 static int cmi9880_resume(struct hda_codec
*codec
)
366 struct cmi_spec
*spec
= codec
->spec
;
369 snd_hda_resume_ctls(codec
, cmi9880_basic_mixer
);
370 if (spec
->surr_switch
)
371 snd_hda_resume_ctls(codec
, cmi9880_ch_mode_mixer
);
372 if (spec
->multiout
.dig_out_nid
)
373 snd_hda_resume_spdif_out(codec
);
374 if (spec
->dig_in_nid
)
375 snd_hda_resume_spdif_in(codec
);
382 * Analog playback callbacks
384 static int cmi9880_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
385 struct hda_codec
*codec
,
386 snd_pcm_substream_t
*substream
)
388 struct cmi_spec
*spec
= codec
->spec
;
389 return snd_hda_multi_out_analog_open(codec
, &spec
->multiout
, substream
);
392 static int cmi9880_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
393 struct hda_codec
*codec
,
394 unsigned int stream_tag
,
396 snd_pcm_substream_t
*substream
)
398 struct cmi_spec
*spec
= codec
->spec
;
399 return snd_hda_multi_out_analog_prepare(codec
, &spec
->multiout
, stream_tag
,
403 static int cmi9880_playback_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
404 struct hda_codec
*codec
,
405 snd_pcm_substream_t
*substream
)
407 struct cmi_spec
*spec
= codec
->spec
;
408 return snd_hda_multi_out_analog_cleanup(codec
, &spec
->multiout
);
414 static int cmi9880_dig_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
415 struct hda_codec
*codec
,
416 snd_pcm_substream_t
*substream
)
418 struct cmi_spec
*spec
= codec
->spec
;
419 return snd_hda_multi_out_dig_open(codec
, &spec
->multiout
);
422 static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream
*hinfo
,
423 struct hda_codec
*codec
,
424 snd_pcm_substream_t
*substream
)
426 struct cmi_spec
*spec
= codec
->spec
;
427 return snd_hda_multi_out_dig_close(codec
, &spec
->multiout
);
433 static int cmi9880_capture_pcm_prepare(struct hda_pcm_stream
*hinfo
,
434 struct hda_codec
*codec
,
435 unsigned int stream_tag
,
437 snd_pcm_substream_t
*substream
)
439 struct cmi_spec
*spec
= codec
->spec
;
441 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
442 stream_tag
, 0, format
);
446 static int cmi9880_capture_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
447 struct hda_codec
*codec
,
448 snd_pcm_substream_t
*substream
)
450 struct cmi_spec
*spec
= codec
->spec
;
452 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
], 0, 0, 0);
459 static struct hda_pcm_stream cmi9880_pcm_analog_playback
= {
463 .nid
= 0x03, /* NID to query formats and rates */
465 .open
= cmi9880_playback_pcm_open
,
466 .prepare
= cmi9880_playback_pcm_prepare
,
467 .cleanup
= cmi9880_playback_pcm_cleanup
471 static struct hda_pcm_stream cmi9880_pcm_analog_capture
= {
475 .nid
= 0x08, /* NID to query formats and rates */
477 .prepare
= cmi9880_capture_pcm_prepare
,
478 .cleanup
= cmi9880_capture_pcm_cleanup
482 static struct hda_pcm_stream cmi9880_pcm_digital_playback
= {
486 /* NID is set in cmi9880_build_pcms */
488 .open
= cmi9880_dig_playback_pcm_open
,
489 .close
= cmi9880_dig_playback_pcm_close
493 static struct hda_pcm_stream cmi9880_pcm_digital_capture
= {
497 /* NID is set in cmi9880_build_pcms */
500 static int cmi9880_build_pcms(struct hda_codec
*codec
)
502 struct cmi_spec
*spec
= codec
->spec
;
503 struct hda_pcm
*info
= spec
->pcm_rec
;
506 codec
->pcm_info
= info
;
508 info
->name
= "CMI9880";
509 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = cmi9880_pcm_analog_playback
;
510 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = cmi9880_pcm_analog_capture
;
512 if (spec
->multiout
.dig_out_nid
|| spec
->dig_in_nid
) {
515 info
->name
= "CMI9880 Digital";
516 if (spec
->multiout
.dig_out_nid
) {
517 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = cmi9880_pcm_digital_playback
;
518 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= spec
->multiout
.dig_out_nid
;
520 if (spec
->dig_in_nid
) {
521 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = cmi9880_pcm_digital_capture
;
522 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->dig_in_nid
;
529 static void cmi9880_free(struct hda_codec
*codec
)
537 static struct hda_board_config cmi9880_cfg_tbl
[] = {
538 { .modelname
= "minimal", .config
= CMI_MINIMAL
},
539 { .modelname
= "min_fp", .config
= CMI_MIN_FP
},
540 { .modelname
= "full", .config
= CMI_FULL
},
541 { .modelname
= "full_dig", .config
= CMI_FULL_DIG
},
542 { .modelname
= "allout", .config
= CMI_ALLOUT
},
546 static struct hda_codec_ops cmi9880_patch_ops
= {
547 .build_controls
= cmi9880_build_controls
,
548 .build_pcms
= cmi9880_build_pcms
,
549 .init
= cmi9880_init
,
550 .free
= cmi9880_free
,
552 .resume
= cmi9880_resume
,
556 static int patch_cmi9880(struct hda_codec
*codec
)
558 struct cmi_spec
*spec
;
560 spec
= kcalloc(1, sizeof(*spec
), GFP_KERNEL
);
565 spec
->board_config
= snd_hda_check_board_config(codec
, cmi9880_cfg_tbl
);
566 if (spec
->board_config
< 0) {
567 snd_printd(KERN_INFO
"hda_codec: Unknown model for CMI9880\n");
568 spec
->board_config
= CMI_FULL_DIG
; /* try everything */
571 switch (spec
->board_config
) {
574 spec
->surr_switch
= 1;
575 if (spec
->board_config
== CMI_MINIMAL
)
576 spec
->num_ch_modes
= 2;
578 spec
->front_panel
= 1;
579 spec
->num_ch_modes
= 3;
581 spec
->channel_modes
= cmi9880_channel_modes
;
582 spec
->multiout
.max_channels
= cmi9880_channel_modes
[0].channels
;
583 spec
->input_mux
= &cmi9880_basic_mux
;
587 spec
->front_panel
= 1;
588 spec
->multiout
.max_channels
= 8;
589 spec
->input_mux
= &cmi9880_basic_mux
;
590 if (spec
->board_config
== CMI_FULL_DIG
) {
591 spec
->multiout
.dig_out_nid
= CMI_DIG_OUT_NID
;
592 spec
->dig_in_nid
= CMI_DIG_IN_NID
;
596 spec
->front_panel
= 1;
597 spec
->multiout
.max_channels
= 8;
598 spec
->no_line_in
= 1;
599 spec
->input_mux
= &cmi9880_no_line_mux
;
600 spec
->multiout
.dig_out_nid
= CMI_DIG_OUT_NID
;
604 spec
->multiout
.num_dacs
= 4;
605 spec
->multiout
.dac_nids
= cmi9880_dac_nids
;
607 spec
->adc_nids
= cmi9880_adc_nids
;
609 codec
->patch_ops
= cmi9880_patch_ops
;
617 struct hda_codec_preset snd_hda_preset_cmedia
[] = {
618 { .id
= 0x13f69880, .name
= "CMI9880", .patch
= patch_cmi9880
},
619 { .id
= 0x434d4980, .name
= "CMI9880", .patch
= patch_cmi9880
},