1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * HD audio interface patch for Cirrus Logic CS8409 HDA bridge chip
5 * Copyright (C) 2021 Cirrus Logic, Inc. and
6 * Cirrus Logic International Semiconductor Ltd.
9 #include <linux/init.h>
10 #include <linux/slab.h>
11 #include <linux/module.h>
12 #include <sound/core.h>
13 #include <linux/mutex.h>
14 #include <linux/iopoll.h>
16 #include "patch_cs8409.h"
18 /******************************************************************************
19 * CS8409 Specific Functions
20 ******************************************************************************/
22 static int cs8409_parse_auto_config(struct hda_codec
*codec
)
24 struct cs8409_spec
*spec
= codec
->spec
;
28 err
= snd_hda_parse_pin_defcfg(codec
, &spec
->gen
.autocfg
, NULL
, 0);
32 err
= snd_hda_gen_parse_auto_config(codec
, &spec
->gen
.autocfg
);
36 /* keep the ADCs powered up when it's dynamically switchable */
37 if (spec
->gen
.dyn_adc_switch
) {
38 unsigned int done
= 0;
40 for (i
= 0; i
< spec
->gen
.input_mux
.num_items
; i
++) {
41 int idx
= spec
->gen
.dyn_adc_idx
[i
];
43 if (done
& (1 << idx
))
45 snd_hda_gen_fix_pin_power(codec
, spec
->gen
.adc_nids
[idx
]);
53 static void cs8409_disable_i2c_clock_worker(struct work_struct
*work
);
55 static struct cs8409_spec
*cs8409_alloc_spec(struct hda_codec
*codec
)
57 struct cs8409_spec
*spec
;
59 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
64 codec
->power_save_node
= 1;
65 mutex_init(&spec
->i2c_mux
);
66 INIT_DELAYED_WORK(&spec
->i2c_clk_work
, cs8409_disable_i2c_clock_worker
);
67 snd_hda_gen_spec_init(&spec
->gen
);
72 static inline int cs8409_vendor_coef_get(struct hda_codec
*codec
, unsigned int idx
)
74 snd_hda_codec_write(codec
, CS8409_PIN_VENDOR_WIDGET
, 0, AC_VERB_SET_COEF_INDEX
, idx
);
75 return snd_hda_codec_read(codec
, CS8409_PIN_VENDOR_WIDGET
, 0, AC_VERB_GET_PROC_COEF
, 0);
78 static inline void cs8409_vendor_coef_set(struct hda_codec
*codec
, unsigned int idx
,
81 snd_hda_codec_write(codec
, CS8409_PIN_VENDOR_WIDGET
, 0, AC_VERB_SET_COEF_INDEX
, idx
);
82 snd_hda_codec_write(codec
, CS8409_PIN_VENDOR_WIDGET
, 0, AC_VERB_SET_PROC_COEF
, coef
);
86 * cs8409_enable_i2c_clock - Disable I2C clocks
87 * @codec: the codec instance
89 * This must be called when the i2c mutex is unlocked.
91 static void cs8409_disable_i2c_clock(struct hda_codec
*codec
)
93 struct cs8409_spec
*spec
= codec
->spec
;
95 mutex_lock(&spec
->i2c_mux
);
96 if (spec
->i2c_clck_enabled
) {
97 cs8409_vendor_coef_set(spec
->codec
, 0x0,
98 cs8409_vendor_coef_get(spec
->codec
, 0x0) & 0xfffffff7);
99 spec
->i2c_clck_enabled
= 0;
101 mutex_unlock(&spec
->i2c_mux
);
105 * cs8409_disable_i2c_clock_worker - Worker that disable the I2C Clock after 25ms without use
107 static void cs8409_disable_i2c_clock_worker(struct work_struct
*work
)
109 struct cs8409_spec
*spec
= container_of(work
, struct cs8409_spec
, i2c_clk_work
.work
);
111 cs8409_disable_i2c_clock(spec
->codec
);
115 * cs8409_enable_i2c_clock - Enable I2C clocks
116 * @codec: the codec instance
118 * This must be called when the i2c mutex is locked.
120 static void cs8409_enable_i2c_clock(struct hda_codec
*codec
)
122 struct cs8409_spec
*spec
= codec
->spec
;
124 /* Cancel the disable timer, but do not wait for any running disable functions to finish.
125 * If the disable timer runs out before cancel, the delayed work thread will be blocked,
126 * waiting for the mutex to become unlocked. This mutex will be locked for the duration of
127 * any i2c transaction, so the disable function will run to completion immediately
128 * afterwards in the scenario. The next enable call will re-enable the clock, regardless.
130 cancel_delayed_work(&spec
->i2c_clk_work
);
132 if (!spec
->i2c_clck_enabled
) {
133 cs8409_vendor_coef_set(codec
, 0x0, cs8409_vendor_coef_get(codec
, 0x0) | 0x8);
134 spec
->i2c_clck_enabled
= 1;
136 queue_delayed_work(system_power_efficient_wq
, &spec
->i2c_clk_work
, msecs_to_jiffies(25));
140 * cs8409_i2c_wait_complete - Wait for I2C transaction
141 * @codec: the codec instance
143 * Wait for I2C transaction to complete.
144 * Return -ETIMEDOUT if transaction wait times out.
146 static int cs8409_i2c_wait_complete(struct hda_codec
*codec
)
150 return read_poll_timeout(cs8409_vendor_coef_get
, retval
, retval
& 0x18,
151 CS42L42_I2C_SLEEP_US
, CS42L42_I2C_TIMEOUT_US
, false, codec
, CS8409_I2C_STS
);
155 * cs8409_set_i2c_dev_addr - Set i2c address for transaction
156 * @codec: the codec instance
159 static void cs8409_set_i2c_dev_addr(struct hda_codec
*codec
, unsigned int addr
)
161 struct cs8409_spec
*spec
= codec
->spec
;
163 if (spec
->dev_addr
!= addr
) {
164 cs8409_vendor_coef_set(codec
, CS8409_I2C_ADDR
, addr
);
165 spec
->dev_addr
= addr
;
170 * cs8409_i2c_set_page - CS8409 I2C set page register.
171 * @scodec: the codec instance
172 * @i2c_reg: Page register
174 * Returns negative on error.
176 static int cs8409_i2c_set_page(struct sub_codec
*scodec
, unsigned int i2c_reg
)
178 struct hda_codec
*codec
= scodec
->codec
;
180 if (scodec
->paged
&& (scodec
->last_page
!= (i2c_reg
>> 8))) {
181 cs8409_vendor_coef_set(codec
, CS8409_I2C_QWRITE
, i2c_reg
>> 8);
182 if (cs8409_i2c_wait_complete(codec
) < 0)
184 scodec
->last_page
= i2c_reg
>> 8;
191 * cs8409_i2c_read - CS8409 I2C Read.
192 * @scodec: the codec instance
193 * @addr: Register to read
195 * Returns negative on error, otherwise returns read value in bits 0-7.
197 static int cs8409_i2c_read(struct sub_codec
*scodec
, unsigned int addr
)
199 struct hda_codec
*codec
= scodec
->codec
;
200 struct cs8409_spec
*spec
= codec
->spec
;
201 unsigned int i2c_reg_data
;
202 unsigned int read_data
;
204 if (scodec
->suspended
)
207 mutex_lock(&spec
->i2c_mux
);
208 cs8409_enable_i2c_clock(codec
);
209 cs8409_set_i2c_dev_addr(codec
, scodec
->addr
);
211 if (cs8409_i2c_set_page(scodec
, addr
))
214 i2c_reg_data
= (addr
<< 8) & 0x0ffff;
215 cs8409_vendor_coef_set(codec
, CS8409_I2C_QREAD
, i2c_reg_data
);
216 if (cs8409_i2c_wait_complete(codec
) < 0)
219 /* Register in bits 15-8 and the data in 7-0 */
220 read_data
= cs8409_vendor_coef_get(codec
, CS8409_I2C_QREAD
);
222 mutex_unlock(&spec
->i2c_mux
);
224 return read_data
& 0x0ff;
227 mutex_unlock(&spec
->i2c_mux
);
228 codec_err(codec
, "%s() Failed 0x%02x : 0x%04x\n", __func__
, scodec
->addr
, addr
);
233 * cs8409_i2c_bulk_read - CS8409 I2C Read Sequence.
234 * @scodec: the codec instance
235 * @seq: Register Sequence to read
236 * @count: Number of registeres to read
238 * Returns negative on error, values are read into value element of cs8409_i2c_param sequence.
240 static int cs8409_i2c_bulk_read(struct sub_codec
*scodec
, struct cs8409_i2c_param
*seq
, int count
)
242 struct hda_codec
*codec
= scodec
->codec
;
243 struct cs8409_spec
*spec
= codec
->spec
;
244 unsigned int i2c_reg_data
;
247 if (scodec
->suspended
)
250 mutex_lock(&spec
->i2c_mux
);
251 cs8409_set_i2c_dev_addr(codec
, scodec
->addr
);
253 for (i
= 0; i
< count
; i
++) {
254 cs8409_enable_i2c_clock(codec
);
255 if (cs8409_i2c_set_page(scodec
, seq
[i
].addr
))
258 i2c_reg_data
= (seq
[i
].addr
<< 8) & 0x0ffff;
259 cs8409_vendor_coef_set(codec
, CS8409_I2C_QREAD
, i2c_reg_data
);
261 if (cs8409_i2c_wait_complete(codec
) < 0)
264 seq
[i
].value
= cs8409_vendor_coef_get(codec
, CS8409_I2C_QREAD
) & 0xff;
267 mutex_unlock(&spec
->i2c_mux
);
272 mutex_unlock(&spec
->i2c_mux
);
273 codec_err(codec
, "I2C Bulk Write Failed 0x%02x\n", scodec
->addr
);
278 * cs8409_i2c_write - CS8409 I2C Write.
279 * @scodec: the codec instance
280 * @addr: Register to write to
281 * @value: Data to write
283 * Returns negative on error, otherwise returns 0.
285 static int cs8409_i2c_write(struct sub_codec
*scodec
, unsigned int addr
, unsigned int value
)
287 struct hda_codec
*codec
= scodec
->codec
;
288 struct cs8409_spec
*spec
= codec
->spec
;
289 unsigned int i2c_reg_data
;
291 if (scodec
->suspended
)
294 mutex_lock(&spec
->i2c_mux
);
296 cs8409_enable_i2c_clock(codec
);
297 cs8409_set_i2c_dev_addr(codec
, scodec
->addr
);
299 if (cs8409_i2c_set_page(scodec
, addr
))
302 i2c_reg_data
= ((addr
<< 8) & 0x0ff00) | (value
& 0x0ff);
303 cs8409_vendor_coef_set(codec
, CS8409_I2C_QWRITE
, i2c_reg_data
);
305 if (cs8409_i2c_wait_complete(codec
) < 0)
308 mutex_unlock(&spec
->i2c_mux
);
312 mutex_unlock(&spec
->i2c_mux
);
313 codec_err(codec
, "%s() Failed 0x%02x : 0x%04x\n", __func__
, scodec
->addr
, addr
);
318 * cs8409_i2c_bulk_write - CS8409 I2C Write Sequence.
319 * @scodec: the codec instance
320 * @seq: Register Sequence to write
321 * @count: Number of registeres to write
323 * Returns negative on error.
325 static int cs8409_i2c_bulk_write(struct sub_codec
*scodec
, const struct cs8409_i2c_param
*seq
,
328 struct hda_codec
*codec
= scodec
->codec
;
329 struct cs8409_spec
*spec
= codec
->spec
;
330 unsigned int i2c_reg_data
;
333 if (scodec
->suspended
)
336 mutex_lock(&spec
->i2c_mux
);
337 cs8409_set_i2c_dev_addr(codec
, scodec
->addr
);
339 for (i
= 0; i
< count
; i
++) {
340 cs8409_enable_i2c_clock(codec
);
341 if (cs8409_i2c_set_page(scodec
, seq
[i
].addr
))
344 i2c_reg_data
= ((seq
[i
].addr
<< 8) & 0x0ff00) | (seq
[i
].value
& 0x0ff);
345 cs8409_vendor_coef_set(codec
, CS8409_I2C_QWRITE
, i2c_reg_data
);
347 if (cs8409_i2c_wait_complete(codec
) < 0)
351 mutex_unlock(&spec
->i2c_mux
);
356 mutex_unlock(&spec
->i2c_mux
);
357 codec_err(codec
, "I2C Bulk Write Failed 0x%02x\n", scodec
->addr
);
361 static int cs8409_init(struct hda_codec
*codec
)
363 int ret
= snd_hda_gen_init(codec
);
366 snd_hda_apply_fixup(codec
, HDA_FIXUP_ACT_INIT
);
371 static int cs8409_build_controls(struct hda_codec
*codec
)
375 err
= snd_hda_gen_build_controls(codec
);
378 snd_hda_apply_fixup(codec
, HDA_FIXUP_ACT_BUILD
);
383 /* Enable/Disable Unsolicited Response */
384 static void cs8409_enable_ur(struct hda_codec
*codec
, int flag
)
386 struct cs8409_spec
*spec
= codec
->spec
;
387 unsigned int ur_gpios
= 0;
390 for (i
= 0; i
< spec
->num_scodecs
; i
++)
391 ur_gpios
|= spec
->scodecs
[i
]->irq_mask
;
393 snd_hda_codec_write(codec
, CS8409_PIN_AFG
, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK
,
394 flag
? ur_gpios
: 0);
396 snd_hda_codec_write(codec
, CS8409_PIN_AFG
, 0, AC_VERB_SET_UNSOLICITED_ENABLE
,
397 flag
? AC_UNSOL_ENABLED
: 0);
400 static void cs8409_fix_caps(struct hda_codec
*codec
, unsigned int nid
)
404 /* CS8409 is simple HDA bridge and intended to be used with a remote
405 * companion codec. Most of input/output PIN(s) have only basic
406 * capabilities. Receive and Transmit NID(s) have only OUTC and INC
407 * capabilities and no presence detect capable (PDC) and call to
408 * snd_hda_gen_build_controls() will mark them as non detectable
409 * phantom jacks. However, a companion codec may be
410 * connected to these pins which supports jack detect
411 * capabilities. We have to override pin capabilities,
412 * otherwise they will not be created as input devices.
414 caps
= snd_hdac_read_parm(&codec
->core
, nid
, AC_PAR_PIN_CAP
);
416 snd_hdac_override_parm(&codec
->core
, nid
, AC_PAR_PIN_CAP
,
417 (caps
| (AC_PINCAP_IMP_SENSE
| AC_PINCAP_PRES_DETECT
)));
419 snd_hda_override_wcaps(codec
, nid
, (get_wcaps(codec
, nid
) | AC_WCAP_UNSOL_CAP
));
422 static int cs8409_spk_sw_gpio_get(struct snd_kcontrol
*kcontrol
,
423 struct snd_ctl_elem_value
*ucontrol
)
425 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
426 struct cs8409_spec
*spec
= codec
->spec
;
428 ucontrol
->value
.integer
.value
[0] = !!(spec
->gpio_data
& spec
->speaker_pdn_gpio
);
432 static int cs8409_spk_sw_gpio_put(struct snd_kcontrol
*kcontrol
,
433 struct snd_ctl_elem_value
*ucontrol
)
435 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
436 struct cs8409_spec
*spec
= codec
->spec
;
437 unsigned int gpio_data
;
439 gpio_data
= (spec
->gpio_data
& ~spec
->speaker_pdn_gpio
) |
440 (ucontrol
->value
.integer
.value
[0] ? spec
->speaker_pdn_gpio
: 0);
441 if (gpio_data
== spec
->gpio_data
)
443 spec
->gpio_data
= gpio_data
;
444 snd_hda_codec_write(codec
, CS8409_PIN_AFG
, 0, AC_VERB_SET_GPIO_DATA
, spec
->gpio_data
);
448 static const struct snd_kcontrol_new cs8409_spk_sw_ctrl
= {
449 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
450 .info
= snd_ctl_boolean_mono_info
,
451 .get
= cs8409_spk_sw_gpio_get
,
452 .put
= cs8409_spk_sw_gpio_put
,
455 /******************************************************************************
456 * CS42L42 Specific Functions
457 ******************************************************************************/
459 int cs42l42_volume_info(struct snd_kcontrol
*kctrl
, struct snd_ctl_elem_info
*uinfo
)
461 unsigned int ofs
= get_amp_offset(kctrl
);
462 u8 chs
= get_amp_channels(kctrl
);
464 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
465 uinfo
->value
.integer
.step
= 1;
466 uinfo
->count
= chs
== 3 ? 2 : 1;
469 case CS42L42_VOL_DAC
:
470 uinfo
->value
.integer
.min
= CS42L42_HP_VOL_REAL_MIN
;
471 uinfo
->value
.integer
.max
= CS42L42_HP_VOL_REAL_MAX
;
473 case CS42L42_VOL_ADC
:
474 uinfo
->value
.integer
.min
= CS42L42_AMIC_VOL_REAL_MIN
;
475 uinfo
->value
.integer
.max
= CS42L42_AMIC_VOL_REAL_MAX
;
484 int cs42l42_volume_get(struct snd_kcontrol
*kctrl
, struct snd_ctl_elem_value
*uctrl
)
486 struct hda_codec
*codec
= snd_kcontrol_chip(kctrl
);
487 struct cs8409_spec
*spec
= codec
->spec
;
488 struct sub_codec
*cs42l42
= spec
->scodecs
[get_amp_index(kctrl
)];
489 int chs
= get_amp_channels(kctrl
);
490 unsigned int ofs
= get_amp_offset(kctrl
);
491 long *valp
= uctrl
->value
.integer
.value
;
494 case CS42L42_VOL_DAC
:
496 *valp
++ = cs42l42
->vol
[ofs
];
498 *valp
= cs42l42
->vol
[ofs
+1];
500 case CS42L42_VOL_ADC
:
502 *valp
= cs42l42
->vol
[ofs
];
511 static void cs42l42_mute(struct sub_codec
*cs42l42
, int vol_type
,
512 unsigned int chs
, bool mute
)
515 if (vol_type
== CS42L42_VOL_DAC
) {
517 cs8409_i2c_write(cs42l42
, CS42L42_MIXER_CHA_VOL
, 0x3f);
519 cs8409_i2c_write(cs42l42
, CS42L42_MIXER_CHB_VOL
, 0x3f);
520 } else if (vol_type
== CS42L42_VOL_ADC
) {
522 cs8409_i2c_write(cs42l42
, CS42L42_ADC_VOLUME
, 0x9f);
525 if (vol_type
== CS42L42_VOL_DAC
) {
527 cs8409_i2c_write(cs42l42
, CS42L42_MIXER_CHA_VOL
,
528 -(cs42l42
->vol
[CS42L42_DAC_CH0_VOL_OFFSET
])
529 & CS42L42_MIXER_CH_VOL_MASK
);
531 cs8409_i2c_write(cs42l42
, CS42L42_MIXER_CHB_VOL
,
532 -(cs42l42
->vol
[CS42L42_DAC_CH1_VOL_OFFSET
])
533 & CS42L42_MIXER_CH_VOL_MASK
);
534 } else if (vol_type
== CS42L42_VOL_ADC
) {
536 cs8409_i2c_write(cs42l42
, CS42L42_ADC_VOLUME
,
537 cs42l42
->vol
[CS42L42_ADC_VOL_OFFSET
]
538 & CS42L42_REG_AMIC_VOL_MASK
);
543 int cs42l42_volume_put(struct snd_kcontrol
*kctrl
, struct snd_ctl_elem_value
*uctrl
)
545 struct hda_codec
*codec
= snd_kcontrol_chip(kctrl
);
546 struct cs8409_spec
*spec
= codec
->spec
;
547 struct sub_codec
*cs42l42
= spec
->scodecs
[get_amp_index(kctrl
)];
548 int chs
= get_amp_channels(kctrl
);
549 unsigned int ofs
= get_amp_offset(kctrl
);
550 long *valp
= uctrl
->value
.integer
.value
;
553 case CS42L42_VOL_DAC
:
555 cs42l42
->vol
[ofs
] = *valp
;
558 cs42l42
->vol
[ofs
+ 1] = *valp
;
560 if (spec
->playback_started
)
561 cs42l42_mute(cs42l42
, CS42L42_VOL_DAC
, chs
, false);
563 case CS42L42_VOL_ADC
:
565 cs42l42
->vol
[ofs
] = *valp
;
566 if (spec
->capture_started
)
567 cs42l42_mute(cs42l42
, CS42L42_VOL_ADC
, chs
, false);
576 static void cs42l42_playback_pcm_hook(struct hda_pcm_stream
*hinfo
,
577 struct hda_codec
*codec
,
578 struct snd_pcm_substream
*substream
,
581 struct cs8409_spec
*spec
= codec
->spec
;
582 struct sub_codec
*cs42l42
;
587 case HDA_GEN_PCM_ACT_PREPARE
:
589 spec
->playback_started
= 1;
591 case HDA_GEN_PCM_ACT_CLEANUP
:
593 spec
->playback_started
= 0;
599 for (i
= 0; i
< spec
->num_scodecs
; i
++) {
600 cs42l42
= spec
->scodecs
[i
];
601 cs42l42_mute(cs42l42
, CS42L42_VOL_DAC
, 0x3, mute
);
605 static void cs42l42_capture_pcm_hook(struct hda_pcm_stream
*hinfo
,
606 struct hda_codec
*codec
,
607 struct snd_pcm_substream
*substream
,
610 struct cs8409_spec
*spec
= codec
->spec
;
611 struct sub_codec
*cs42l42
;
616 case HDA_GEN_PCM_ACT_PREPARE
:
618 spec
->capture_started
= 1;
620 case HDA_GEN_PCM_ACT_CLEANUP
:
622 spec
->capture_started
= 0;
628 for (i
= 0; i
< spec
->num_scodecs
; i
++) {
629 cs42l42
= spec
->scodecs
[i
];
630 cs42l42_mute(cs42l42
, CS42L42_VOL_ADC
, 0x3, mute
);
634 /* Configure CS42L42 slave codec for jack autodetect */
635 static void cs42l42_enable_jack_detect(struct sub_codec
*cs42l42
)
637 cs8409_i2c_write(cs42l42
, CS42L42_HSBIAS_SC_AUTOCTL
, cs42l42
->hsbias_hiz
);
639 cs8409_i2c_write(cs42l42
, CS42L42_WAKE_CTL
, 0x00C1);
641 usleep_range(2500, 3000);
642 /* Set mode WAKE# output follows the combination logic directly */
643 cs8409_i2c_write(cs42l42
, CS42L42_WAKE_CTL
, 0x00C0);
644 /* Clear interrupts status */
645 cs8409_i2c_read(cs42l42
, CS42L42_TSRS_PLUG_STATUS
);
646 /* Enable interrupt */
647 cs8409_i2c_write(cs42l42
, CS42L42_TSRS_PLUG_INT_MASK
, 0xF3);
650 /* Enable and run CS42L42 slave codec jack auto detect */
651 static void cs42l42_run_jack_detect(struct sub_codec
*cs42l42
)
653 /* Clear interrupts */
654 cs8409_i2c_read(cs42l42
, CS42L42_CODEC_STATUS
);
655 cs8409_i2c_read(cs42l42
, CS42L42_DET_STATUS1
);
656 cs8409_i2c_write(cs42l42
, CS42L42_TSRS_PLUG_INT_MASK
, 0xFF);
657 cs8409_i2c_read(cs42l42
, CS42L42_TSRS_PLUG_STATUS
);
659 cs8409_i2c_write(cs42l42
, CS42L42_PWR_CTL2
, 0x87);
660 cs8409_i2c_write(cs42l42
, CS42L42_DAC_CTL2
, 0x86);
661 cs8409_i2c_write(cs42l42
, CS42L42_MISC_DET_CTL
, 0x07);
662 cs8409_i2c_write(cs42l42
, CS42L42_CODEC_INT_MASK
, 0xFD);
663 cs8409_i2c_write(cs42l42
, CS42L42_HSDET_CTL2
, 0x80);
665 usleep_range(20000, 25000);
666 cs8409_i2c_write(cs42l42
, CS42L42_HSDET_CTL1
, 0x77);
667 cs8409_i2c_write(cs42l42
, CS42L42_HSDET_CTL2
, 0xc0);
670 static int cs42l42_manual_hs_det(struct sub_codec
*cs42l42
)
672 unsigned int hs_det_status
;
673 unsigned int hs_det_comp1
;
674 unsigned int hs_det_comp2
;
675 unsigned int hs_det_sw
;
676 unsigned int hs_type
;
678 /* Set hs detect to manual, active mode */
679 cs8409_i2c_write(cs42l42
, CS42L42_HSDET_CTL2
,
680 (1 << CS42L42_HSDET_CTRL_SHIFT
) |
681 (0 << CS42L42_HSDET_SET_SHIFT
) |
682 (0 << CS42L42_HSBIAS_REF_SHIFT
) |
683 (0 << CS42L42_HSDET_AUTO_TIME_SHIFT
));
685 /* Configure HS DET comparator reference levels. */
686 cs8409_i2c_write(cs42l42
, CS42L42_HSDET_CTL1
,
687 (CS42L42_HSDET_COMP1_LVL_VAL
<< CS42L42_HSDET_COMP1_LVL_SHIFT
) |
688 (CS42L42_HSDET_COMP2_LVL_VAL
<< CS42L42_HSDET_COMP2_LVL_SHIFT
));
690 /* Open the SW_HSB_HS3 switch and close SW_HSB_HS4 for a Type 1 headset. */
691 cs8409_i2c_write(cs42l42
, CS42L42_HS_SWITCH_CTL
, CS42L42_HSDET_SW_COMP1
);
695 hs_det_status
= cs8409_i2c_read(cs42l42
, CS42L42_HS_DET_STATUS
);
697 hs_det_comp1
= (hs_det_status
& CS42L42_HSDET_COMP1_OUT_MASK
) >>
698 CS42L42_HSDET_COMP1_OUT_SHIFT
;
699 hs_det_comp2
= (hs_det_status
& CS42L42_HSDET_COMP2_OUT_MASK
) >>
700 CS42L42_HSDET_COMP2_OUT_SHIFT
;
702 /* Close the SW_HSB_HS3 switch for a Type 2 headset. */
703 cs8409_i2c_write(cs42l42
, CS42L42_HS_SWITCH_CTL
, CS42L42_HSDET_SW_COMP2
);
707 hs_det_status
= cs8409_i2c_read(cs42l42
, CS42L42_HS_DET_STATUS
);
709 hs_det_comp1
|= ((hs_det_status
& CS42L42_HSDET_COMP1_OUT_MASK
) >>
710 CS42L42_HSDET_COMP1_OUT_SHIFT
) << 1;
711 hs_det_comp2
|= ((hs_det_status
& CS42L42_HSDET_COMP2_OUT_MASK
) >>
712 CS42L42_HSDET_COMP2_OUT_SHIFT
) << 1;
714 /* Use Comparator 1 with 1.25V Threshold. */
715 switch (hs_det_comp1
) {
716 case CS42L42_HSDET_COMP_TYPE1
:
717 hs_type
= CS42L42_PLUG_CTIA
;
718 hs_det_sw
= CS42L42_HSDET_SW_TYPE1
;
720 case CS42L42_HSDET_COMP_TYPE2
:
721 hs_type
= CS42L42_PLUG_OMTP
;
722 hs_det_sw
= CS42L42_HSDET_SW_TYPE2
;
725 /* Fallback to Comparator 2 with 1.75V Threshold. */
726 switch (hs_det_comp2
) {
727 case CS42L42_HSDET_COMP_TYPE1
:
728 hs_type
= CS42L42_PLUG_CTIA
;
729 hs_det_sw
= CS42L42_HSDET_SW_TYPE1
;
731 case CS42L42_HSDET_COMP_TYPE2
:
732 hs_type
= CS42L42_PLUG_OMTP
;
733 hs_det_sw
= CS42L42_HSDET_SW_TYPE2
;
735 case CS42L42_HSDET_COMP_TYPE3
:
736 hs_type
= CS42L42_PLUG_HEADPHONE
;
737 hs_det_sw
= CS42L42_HSDET_SW_TYPE3
;
740 hs_type
= CS42L42_PLUG_INVALID
;
741 hs_det_sw
= CS42L42_HSDET_SW_TYPE4
;
747 cs8409_i2c_write(cs42l42
, CS42L42_HS_SWITCH_CTL
, hs_det_sw
);
749 /* Set HSDET mode to Manual—Disabled */
750 cs8409_i2c_write(cs42l42
, CS42L42_HSDET_CTL2
,
751 (0 << CS42L42_HSDET_CTRL_SHIFT
) |
752 (0 << CS42L42_HSDET_SET_SHIFT
) |
753 (0 << CS42L42_HSBIAS_REF_SHIFT
) |
754 (0 << CS42L42_HSDET_AUTO_TIME_SHIFT
));
756 /* Configure HS DET comparator reference levels. */
757 cs8409_i2c_write(cs42l42
, CS42L42_HSDET_CTL1
,
758 (CS42L42_HSDET_COMP1_LVL_DEFAULT
<< CS42L42_HSDET_COMP1_LVL_SHIFT
) |
759 (CS42L42_HSDET_COMP2_LVL_DEFAULT
<< CS42L42_HSDET_COMP2_LVL_SHIFT
));
764 static int cs42l42_handle_tip_sense(struct sub_codec
*cs42l42
, unsigned int reg_ts_status
)
766 int status_changed
= 0;
768 /* TIP_SENSE INSERT/REMOVE */
769 switch (reg_ts_status
) {
770 case CS42L42_TS_PLUG
:
771 if (cs42l42
->no_type_dect
) {
773 cs42l42
->hp_jack_in
= 1;
774 cs42l42
->mic_jack_in
= 0;
776 cs42l42_run_jack_detect(cs42l42
);
780 case CS42L42_TS_UNPLUG
:
782 cs42l42
->hp_jack_in
= 0;
783 cs42l42
->mic_jack_in
= 0;
786 /* jack in transition */
790 codec_dbg(cs42l42
->codec
, "Tip Sense Detection: (%d)\n", reg_ts_status
);
792 return status_changed
;
795 static int cs42l42_jack_unsol_event(struct sub_codec
*cs42l42
)
797 int current_plug_status
;
798 int status_changed
= 0;
804 /* Read jack detect status registers */
805 reg_cdc_status
= cs8409_i2c_read(cs42l42
, CS42L42_CODEC_STATUS
);
806 reg_hs_status
= cs8409_i2c_read(cs42l42
, CS42L42_HS_DET_STATUS
);
807 reg_ts_status
= cs8409_i2c_read(cs42l42
, CS42L42_TSRS_PLUG_STATUS
);
809 /* If status values are < 0, read error has occurred. */
810 if (reg_cdc_status
< 0 || reg_hs_status
< 0 || reg_ts_status
< 0)
813 current_plug_status
= (reg_ts_status
& (CS42L42_TS_PLUG_MASK
| CS42L42_TS_UNPLUG_MASK
))
814 >> CS42L42_TS_PLUG_SHIFT
;
816 /* HSDET_AUTO_DONE */
817 if (reg_cdc_status
& CS42L42_HSDET_AUTO_DONE_MASK
) {
819 /* Disable HSDET_AUTO_DONE */
820 cs8409_i2c_write(cs42l42
, CS42L42_CODEC_INT_MASK
, 0xFF);
822 type
= (reg_hs_status
& CS42L42_HSDET_TYPE_MASK
) >> CS42L42_HSDET_TYPE_SHIFT
;
824 /* Configure the HSDET mode. */
825 cs8409_i2c_write(cs42l42
, CS42L42_HSDET_CTL2
, 0x80);
827 if (cs42l42
->no_type_dect
) {
828 status_changed
= cs42l42_handle_tip_sense(cs42l42
, current_plug_status
);
830 if (type
== CS42L42_PLUG_INVALID
|| type
== CS42L42_PLUG_HEADPHONE
) {
831 codec_dbg(cs42l42
->codec
,
832 "Auto detect value not valid (%d), running manual det\n",
834 type
= cs42l42_manual_hs_det(cs42l42
);
838 case CS42L42_PLUG_CTIA
:
839 case CS42L42_PLUG_OMTP
:
841 cs42l42
->hp_jack_in
= 1;
842 cs42l42
->mic_jack_in
= 1;
844 case CS42L42_PLUG_HEADPHONE
:
846 cs42l42
->hp_jack_in
= 1;
847 cs42l42
->mic_jack_in
= 0;
851 cs42l42
->hp_jack_in
= 0;
852 cs42l42
->mic_jack_in
= 0;
855 codec_dbg(cs42l42
->codec
, "Detection done (%d)\n", type
);
858 /* Enable the HPOUT ground clamp and configure the HP pull-down */
859 cs8409_i2c_write(cs42l42
, CS42L42_DAC_CTL2
, 0x02);
860 /* Re-Enable Tip Sense Interrupt */
861 cs8409_i2c_write(cs42l42
, CS42L42_TSRS_PLUG_INT_MASK
, 0xF3);
863 status_changed
= cs42l42_handle_tip_sense(cs42l42
, current_plug_status
);
866 return status_changed
;
869 static void cs42l42_resume(struct sub_codec
*cs42l42
)
871 struct hda_codec
*codec
= cs42l42
->codec
;
872 struct cs8409_spec
*spec
= codec
->spec
;
873 struct cs8409_i2c_param irq_regs
[] = {
874 { CS42L42_CODEC_STATUS
, 0x00 },
875 { CS42L42_DET_INT_STATUS1
, 0x00 },
876 { CS42L42_DET_INT_STATUS2
, 0x00 },
877 { CS42L42_TSRS_PLUG_STATUS
, 0x00 },
879 int fsv_old
, fsv_new
;
881 /* Bring CS42L42 out of Reset */
882 spec
->gpio_data
= snd_hda_codec_read(codec
, CS8409_PIN_AFG
, 0, AC_VERB_GET_GPIO_DATA
, 0);
883 spec
->gpio_data
|= cs42l42
->reset_gpio
;
884 snd_hda_codec_write(codec
, CS8409_PIN_AFG
, 0, AC_VERB_SET_GPIO_DATA
, spec
->gpio_data
);
885 usleep_range(10000, 15000);
887 cs42l42
->suspended
= 0;
889 /* Initialize CS42L42 companion codec */
890 cs8409_i2c_bulk_write(cs42l42
, cs42l42
->init_seq
, cs42l42
->init_seq_num
);
891 msleep(CS42L42_INIT_TIMEOUT_MS
);
893 /* Clear interrupts, by reading interrupt status registers */
894 cs8409_i2c_bulk_read(cs42l42
, irq_regs
, ARRAY_SIZE(irq_regs
));
896 fsv_old
= cs8409_i2c_read(cs42l42
, CS42L42_HP_CTL
);
897 if (cs42l42
->full_scale_vol
== CS42L42_FULL_SCALE_VOL_0DB
)
898 fsv_new
= fsv_old
& ~CS42L42_FULL_SCALE_VOL_MASK
;
900 fsv_new
= fsv_old
& CS42L42_FULL_SCALE_VOL_MASK
;
901 if (fsv_new
!= fsv_old
)
902 cs8409_i2c_write(cs42l42
, CS42L42_HP_CTL
, fsv_new
);
904 /* we have to explicitly allow unsol event handling even during the
905 * resume phase so that the jack event is processed properly
907 snd_hda_codec_allow_unsol_events(cs42l42
->codec
);
909 cs42l42_enable_jack_detect(cs42l42
);
912 static void cs42l42_suspend(struct sub_codec
*cs42l42
)
914 struct hda_codec
*codec
= cs42l42
->codec
;
915 struct cs8409_spec
*spec
= codec
->spec
;
916 int reg_cdc_status
= 0;
917 const struct cs8409_i2c_param cs42l42_pwr_down_seq
[] = {
918 { CS42L42_DAC_CTL2
, 0x02 },
919 { CS42L42_HS_CLAMP_DISABLE
, 0x00 },
920 { CS42L42_MIXER_CHA_VOL
, 0x3F },
921 { CS42L42_MIXER_ADC_VOL
, 0x3F },
922 { CS42L42_MIXER_CHB_VOL
, 0x3F },
923 { CS42L42_HP_CTL
, 0x0F },
924 { CS42L42_ASP_RX_DAI0_EN
, 0x00 },
925 { CS42L42_ASP_CLK_CFG
, 0x00 },
926 { CS42L42_PWR_CTL1
, 0xFE },
927 { CS42L42_PWR_CTL2
, 0x8C },
928 { CS42L42_PWR_CTL1
, 0xFF },
931 cs8409_i2c_bulk_write(cs42l42
, cs42l42_pwr_down_seq
, ARRAY_SIZE(cs42l42_pwr_down_seq
));
933 if (read_poll_timeout(cs8409_i2c_read
, reg_cdc_status
,
934 (reg_cdc_status
& 0x1), CS42L42_PDN_SLEEP_US
, CS42L42_PDN_TIMEOUT_US
,
935 true, cs42l42
, CS42L42_CODEC_STATUS
) < 0)
936 codec_warn(codec
, "Timeout waiting for PDN_DONE for CS42L42\n");
938 /* Power down CS42L42 ASP/EQ/MIX/HP */
939 cs8409_i2c_write(cs42l42
, CS42L42_PWR_CTL2
, 0x9C);
940 cs42l42
->suspended
= 1;
941 cs42l42
->last_page
= 0;
942 cs42l42
->hp_jack_in
= 0;
943 cs42l42
->mic_jack_in
= 0;
945 /* Put CS42L42 into Reset */
946 spec
->gpio_data
= snd_hda_codec_read(codec
, CS8409_PIN_AFG
, 0, AC_VERB_GET_GPIO_DATA
, 0);
947 spec
->gpio_data
&= ~cs42l42
->reset_gpio
;
948 snd_hda_codec_write(codec
, CS8409_PIN_AFG
, 0, AC_VERB_SET_GPIO_DATA
, spec
->gpio_data
);
951 static void cs8409_free(struct hda_codec
*codec
)
953 struct cs8409_spec
*spec
= codec
->spec
;
955 /* Cancel i2c clock disable timer, and disable clock if left enabled */
956 cancel_delayed_work_sync(&spec
->i2c_clk_work
);
957 cs8409_disable_i2c_clock(codec
);
959 snd_hda_gen_free(codec
);
962 /******************************************************************************
963 * BULLSEYE / WARLOCK / CYBORG Specific Functions
965 ******************************************************************************/
968 * In the case of CS8409 we do not have unsolicited events from NID's 0x24
969 * and 0x34 where hs mic and hp are connected. Companion codec CS42L42 will
970 * generate interrupt via gpio 4 to notify jack events. We have to overwrite
971 * generic snd_hda_jack_unsol_event(), read CS42L42 jack detect status registers
972 * and then notify status via generic snd_hda_jack_unsol_event() call.
974 static void cs8409_cs42l42_jack_unsol_event(struct hda_codec
*codec
, unsigned int res
)
976 struct cs8409_spec
*spec
= codec
->spec
;
977 struct sub_codec
*cs42l42
= spec
->scodecs
[CS8409_CODEC0
];
978 struct hda_jack_tbl
*jk
;
980 /* jack_unsol_event() will be called every time gpio line changing state.
981 * In this case gpio4 line goes up as a result of reading interrupt status
982 * registers in previous cs8409_jack_unsol_event() call.
983 * We don't need to handle this event, ignoring...
985 if (res
& cs42l42
->irq_mask
)
988 if (cs42l42_jack_unsol_event(cs42l42
)) {
989 snd_hda_set_pin_ctl(codec
, CS8409_CS42L42_SPK_PIN_NID
,
990 cs42l42
->hp_jack_in
? 0 : PIN_OUT
);
992 jk
= snd_hda_jack_tbl_get_mst(codec
, CS8409_CS42L42_HP_PIN_NID
, 0);
994 snd_hda_jack_unsol_event(codec
, (jk
->tag
<< AC_UNSOL_RES_TAG_SHIFT
) &
997 jk
= snd_hda_jack_tbl_get_mst(codec
, CS8409_CS42L42_AMIC_PIN_NID
, 0);
999 snd_hda_jack_unsol_event(codec
, (jk
->tag
<< AC_UNSOL_RES_TAG_SHIFT
) &
1004 /* Manage PDREF, when transition to D3hot */
1005 static int cs8409_cs42l42_suspend(struct hda_codec
*codec
)
1007 struct cs8409_spec
*spec
= codec
->spec
;
1010 spec
->init_done
= 0;
1012 cs8409_enable_ur(codec
, 0);
1014 for (i
= 0; i
< spec
->num_scodecs
; i
++)
1015 cs42l42_suspend(spec
->scodecs
[i
]);
1017 /* Cancel i2c clock disable timer, and disable clock if left enabled */
1018 cancel_delayed_work_sync(&spec
->i2c_clk_work
);
1019 cs8409_disable_i2c_clock(codec
);
1021 snd_hda_shutup_pins(codec
);
1026 /* Vendor specific HW configuration
1027 * PLL, ASP, I2C, SPI, GPIOs, DMIC etc...
1029 static void cs8409_cs42l42_hw_init(struct hda_codec
*codec
)
1031 const struct cs8409_cir_param
*seq
= cs8409_cs42l42_hw_cfg
;
1032 const struct cs8409_cir_param
*seq_bullseye
= cs8409_cs42l42_bullseye_atn
;
1033 struct cs8409_spec
*spec
= codec
->spec
;
1034 struct sub_codec
*cs42l42
= spec
->scodecs
[CS8409_CODEC0
];
1036 if (spec
->gpio_mask
) {
1037 snd_hda_codec_write(codec
, CS8409_PIN_AFG
, 0, AC_VERB_SET_GPIO_MASK
,
1039 snd_hda_codec_write(codec
, CS8409_PIN_AFG
, 0, AC_VERB_SET_GPIO_DIRECTION
,
1041 snd_hda_codec_write(codec
, CS8409_PIN_AFG
, 0, AC_VERB_SET_GPIO_DATA
,
1045 for (; seq
->nid
; seq
++)
1046 cs8409_vendor_coef_set(codec
, seq
->cir
, seq
->coeff
);
1048 if (codec
->fixup_id
== CS8409_BULLSEYE
) {
1049 for (; seq_bullseye
->nid
; seq_bullseye
++)
1050 cs8409_vendor_coef_set(codec
, seq_bullseye
->cir
, seq_bullseye
->coeff
);
1053 switch (codec
->fixup_id
) {
1055 case CS8409_WARLOCK_MLK_DUAL_MIC
:
1056 /* DMIC1_MO=00b, DMIC1/2_SR=1 */
1057 cs8409_vendor_coef_set(codec
, CS8409_DMIC_CFG
, 0x0003);
1060 /* ASP1/2_xxx_EN=1, ASP1/2_MCLK_EN=0, DMIC1_SCL_EN=0 */
1061 cs8409_vendor_coef_set(codec
, CS8409_PAD_CFG_SLW_RATE_CTRL
, 0xfc00);
1067 cs42l42_resume(cs42l42
);
1069 /* Enable Unsolicited Response */
1070 cs8409_enable_ur(codec
, 1);
1073 static const struct hda_codec_ops cs8409_cs42l42_patch_ops
= {
1074 .build_controls
= cs8409_build_controls
,
1075 .build_pcms
= snd_hda_gen_build_pcms
,
1076 .init
= cs8409_init
,
1077 .free
= cs8409_free
,
1078 .unsol_event
= cs8409_cs42l42_jack_unsol_event
,
1079 .suspend
= cs8409_cs42l42_suspend
,
1082 static int cs8409_cs42l42_exec_verb(struct hdac_device
*dev
, unsigned int cmd
, unsigned int flags
,
1085 struct hda_codec
*codec
= container_of(dev
, struct hda_codec
, core
);
1086 struct cs8409_spec
*spec
= codec
->spec
;
1087 struct sub_codec
*cs42l42
= spec
->scodecs
[CS8409_CODEC0
];
1089 unsigned int nid
= ((cmd
>> 20) & 0x07f);
1090 unsigned int verb
= ((cmd
>> 8) & 0x0fff);
1092 /* CS8409 pins have no AC_PINSENSE_PRESENCE
1093 * capabilities. We have to intercept 2 calls for pins 0x24 and 0x34
1094 * and return correct pin sense values for read_pin_sense() call from
1095 * hda_jack based on CS42L42 jack detect status.
1098 case CS8409_CS42L42_HP_PIN_NID
:
1099 if (verb
== AC_VERB_GET_PIN_SENSE
) {
1100 *res
= (cs42l42
->hp_jack_in
) ? AC_PINSENSE_PRESENCE
: 0;
1104 case CS8409_CS42L42_AMIC_PIN_NID
:
1105 if (verb
== AC_VERB_GET_PIN_SENSE
) {
1106 *res
= (cs42l42
->mic_jack_in
) ? AC_PINSENSE_PRESENCE
: 0;
1114 return spec
->exec_verb(dev
, cmd
, flags
, res
);
1117 void cs8409_cs42l42_fixups(struct hda_codec
*codec
, const struct hda_fixup
*fix
, int action
)
1119 struct cs8409_spec
*spec
= codec
->spec
;
1122 case HDA_FIXUP_ACT_PRE_PROBE
:
1123 snd_hda_add_verbs(codec
, cs8409_cs42l42_init_verbs
);
1124 /* verb exec op override */
1125 spec
->exec_verb
= codec
->core
.exec_verb
;
1126 codec
->core
.exec_verb
= cs8409_cs42l42_exec_verb
;
1128 spec
->scodecs
[CS8409_CODEC0
] = &cs8409_cs42l42_codec
;
1129 spec
->num_scodecs
= 1;
1130 spec
->scodecs
[CS8409_CODEC0
]->codec
= codec
;
1131 codec
->patch_ops
= cs8409_cs42l42_patch_ops
;
1133 spec
->gen
.suppress_auto_mute
= 1;
1134 spec
->gen
.no_primary_hp
= 1;
1135 spec
->gen
.suppress_vmaster
= 1;
1137 spec
->speaker_pdn_gpio
= 0;
1139 /* GPIO 5 out, 3,4 in */
1140 spec
->gpio_dir
= spec
->scodecs
[CS8409_CODEC0
]->reset_gpio
;
1141 spec
->gpio_data
= 0;
1142 spec
->gpio_mask
= 0x03f;
1144 /* Basic initial sequence for specific hw configuration */
1145 snd_hda_sequence_write(codec
, cs8409_cs42l42_init_verbs
);
1147 cs8409_fix_caps(codec
, CS8409_CS42L42_HP_PIN_NID
);
1148 cs8409_fix_caps(codec
, CS8409_CS42L42_AMIC_PIN_NID
);
1150 spec
->scodecs
[CS8409_CODEC0
]->hsbias_hiz
= 0x0020;
1152 switch (codec
->fixup_id
) {
1154 spec
->scodecs
[CS8409_CODEC0
]->full_scale_vol
=
1155 CS42L42_FULL_SCALE_VOL_MINUS6DB
;
1156 spec
->speaker_pdn_gpio
= CS8409_CYBORG_SPEAKER_PDN
;
1159 spec
->scodecs
[CS8409_CODEC0
]->full_scale_vol
= CS42L42_FULL_SCALE_VOL_0DB
;
1160 spec
->speaker_pdn_gpio
= CS8409_CYBORG_SPEAKER_PDN
;
1162 case CS8409_WARLOCK_MLK
:
1163 case CS8409_WARLOCK_MLK_DUAL_MIC
:
1164 spec
->scodecs
[CS8409_CODEC0
]->full_scale_vol
= CS42L42_FULL_SCALE_VOL_0DB
;
1165 spec
->speaker_pdn_gpio
= CS8409_WARLOCK_SPEAKER_PDN
;
1168 spec
->scodecs
[CS8409_CODEC0
]->full_scale_vol
=
1169 CS42L42_FULL_SCALE_VOL_MINUS6DB
;
1170 spec
->speaker_pdn_gpio
= CS8409_WARLOCK_SPEAKER_PDN
;
1174 if (spec
->speaker_pdn_gpio
> 0) {
1175 spec
->gpio_dir
|= spec
->speaker_pdn_gpio
;
1176 spec
->gpio_data
|= spec
->speaker_pdn_gpio
;
1180 case HDA_FIXUP_ACT_PROBE
:
1181 /* Fix Sample Rate to 48kHz */
1182 spec
->gen
.stream_analog_playback
= &cs42l42_48k_pcm_analog_playback
;
1183 spec
->gen
.stream_analog_capture
= &cs42l42_48k_pcm_analog_capture
;
1185 spec
->gen
.pcm_playback_hook
= cs42l42_playback_pcm_hook
;
1186 spec
->gen
.pcm_capture_hook
= cs42l42_capture_pcm_hook
;
1187 if (codec
->fixup_id
!= CS8409_ODIN
)
1188 /* Set initial DMIC volume to -26 dB */
1189 snd_hda_codec_amp_init_stereo(codec
, CS8409_CS42L42_DMIC_ADC_PIN_NID
,
1190 HDA_INPUT
, 0, 0xff, 0x19);
1191 snd_hda_gen_add_kctl(&spec
->gen
, "Headphone Playback Volume",
1192 &cs42l42_dac_volume_mixer
);
1193 snd_hda_gen_add_kctl(&spec
->gen
, "Mic Capture Volume",
1194 &cs42l42_adc_volume_mixer
);
1195 if (spec
->speaker_pdn_gpio
> 0)
1196 snd_hda_gen_add_kctl(&spec
->gen
, "Speaker Playback Switch",
1197 &cs8409_spk_sw_ctrl
);
1198 /* Disable Unsolicited Response during boot */
1199 cs8409_enable_ur(codec
, 0);
1200 snd_hda_codec_set_name(codec
, "CS8409/CS42L42");
1202 case HDA_FIXUP_ACT_INIT
:
1203 cs8409_cs42l42_hw_init(codec
);
1204 spec
->init_done
= 1;
1205 if (spec
->init_done
&& spec
->build_ctrl_done
1206 && !spec
->scodecs
[CS8409_CODEC0
]->hp_jack_in
)
1207 cs42l42_run_jack_detect(spec
->scodecs
[CS8409_CODEC0
]);
1209 case HDA_FIXUP_ACT_BUILD
:
1210 spec
->build_ctrl_done
= 1;
1211 /* Run jack auto detect first time on boot
1212 * after controls have been added, to check if jack has
1213 * been already plugged in.
1214 * Run immediately after init.
1216 if (spec
->init_done
&& spec
->build_ctrl_done
1217 && !spec
->scodecs
[CS8409_CODEC0
]->hp_jack_in
)
1218 cs42l42_run_jack_detect(spec
->scodecs
[CS8409_CODEC0
]);
1225 /******************************************************************************
1226 * Dolphin Specific Functions
1227 * CS8409/ 2 X CS42L42
1228 ******************************************************************************/
1231 * In the case of CS8409 we do not have unsolicited events when
1232 * hs mic and hp are connected. Companion codec CS42L42 will
1233 * generate interrupt via irq_mask to notify jack events. We have to overwrite
1234 * generic snd_hda_jack_unsol_event(), read CS42L42 jack detect status registers
1235 * and then notify status via generic snd_hda_jack_unsol_event() call.
1237 static void dolphin_jack_unsol_event(struct hda_codec
*codec
, unsigned int res
)
1239 struct cs8409_spec
*spec
= codec
->spec
;
1240 struct sub_codec
*cs42l42
;
1241 struct hda_jack_tbl
*jk
;
1243 cs42l42
= spec
->scodecs
[CS8409_CODEC0
];
1244 if (!cs42l42
->suspended
&& (~res
& cs42l42
->irq_mask
) &&
1245 cs42l42_jack_unsol_event(cs42l42
)) {
1246 jk
= snd_hda_jack_tbl_get_mst(codec
, DOLPHIN_HP_PIN_NID
, 0);
1248 snd_hda_jack_unsol_event(codec
,
1249 (jk
->tag
<< AC_UNSOL_RES_TAG_SHIFT
) &
1252 jk
= snd_hda_jack_tbl_get_mst(codec
, DOLPHIN_AMIC_PIN_NID
, 0);
1254 snd_hda_jack_unsol_event(codec
,
1255 (jk
->tag
<< AC_UNSOL_RES_TAG_SHIFT
) &
1259 cs42l42
= spec
->scodecs
[CS8409_CODEC1
];
1260 if (!cs42l42
->suspended
&& (~res
& cs42l42
->irq_mask
) &&
1261 cs42l42_jack_unsol_event(cs42l42
)) {
1262 jk
= snd_hda_jack_tbl_get_mst(codec
, DOLPHIN_LO_PIN_NID
, 0);
1264 snd_hda_jack_unsol_event(codec
,
1265 (jk
->tag
<< AC_UNSOL_RES_TAG_SHIFT
) &
1270 /* Vendor specific HW configuration
1271 * PLL, ASP, I2C, SPI, GPIOs, DMIC etc...
1273 static void dolphin_hw_init(struct hda_codec
*codec
)
1275 const struct cs8409_cir_param
*seq
= dolphin_hw_cfg
;
1276 struct cs8409_spec
*spec
= codec
->spec
;
1277 struct sub_codec
*cs42l42
;
1280 if (spec
->gpio_mask
) {
1281 snd_hda_codec_write(codec
, CS8409_PIN_AFG
, 0, AC_VERB_SET_GPIO_MASK
,
1283 snd_hda_codec_write(codec
, CS8409_PIN_AFG
, 0, AC_VERB_SET_GPIO_DIRECTION
,
1285 snd_hda_codec_write(codec
, CS8409_PIN_AFG
, 0, AC_VERB_SET_GPIO_DATA
,
1289 for (; seq
->nid
; seq
++)
1290 cs8409_vendor_coef_set(codec
, seq
->cir
, seq
->coeff
);
1292 for (i
= 0; i
< spec
->num_scodecs
; i
++) {
1293 cs42l42
= spec
->scodecs
[i
];
1294 cs42l42_resume(cs42l42
);
1297 /* Enable Unsolicited Response */
1298 cs8409_enable_ur(codec
, 1);
1301 static const struct hda_codec_ops cs8409_dolphin_patch_ops
= {
1302 .build_controls
= cs8409_build_controls
,
1303 .build_pcms
= snd_hda_gen_build_pcms
,
1304 .init
= cs8409_init
,
1305 .free
= cs8409_free
,
1306 .unsol_event
= dolphin_jack_unsol_event
,
1307 .suspend
= cs8409_cs42l42_suspend
,
1310 static int dolphin_exec_verb(struct hdac_device
*dev
, unsigned int cmd
, unsigned int flags
,
1313 struct hda_codec
*codec
= container_of(dev
, struct hda_codec
, core
);
1314 struct cs8409_spec
*spec
= codec
->spec
;
1315 struct sub_codec
*cs42l42
= spec
->scodecs
[CS8409_CODEC0
];
1317 unsigned int nid
= ((cmd
>> 20) & 0x07f);
1318 unsigned int verb
= ((cmd
>> 8) & 0x0fff);
1320 /* CS8409 pins have no AC_PINSENSE_PRESENCE
1321 * capabilities. We have to intercept calls for CS42L42 pins
1322 * and return correct pin sense values for read_pin_sense() call from
1323 * hda_jack based on CS42L42 jack detect status.
1326 case DOLPHIN_HP_PIN_NID
:
1327 case DOLPHIN_LO_PIN_NID
:
1328 if (nid
== DOLPHIN_LO_PIN_NID
)
1329 cs42l42
= spec
->scodecs
[CS8409_CODEC1
];
1330 if (verb
== AC_VERB_GET_PIN_SENSE
) {
1331 *res
= (cs42l42
->hp_jack_in
) ? AC_PINSENSE_PRESENCE
: 0;
1335 case DOLPHIN_AMIC_PIN_NID
:
1336 if (verb
== AC_VERB_GET_PIN_SENSE
) {
1337 *res
= (cs42l42
->mic_jack_in
) ? AC_PINSENSE_PRESENCE
: 0;
1345 return spec
->exec_verb(dev
, cmd
, flags
, res
);
1348 void dolphin_fixups(struct hda_codec
*codec
, const struct hda_fixup
*fix
, int action
)
1350 struct cs8409_spec
*spec
= codec
->spec
;
1351 struct snd_kcontrol_new
*kctrl
;
1355 case HDA_FIXUP_ACT_PRE_PROBE
:
1356 snd_hda_add_verbs(codec
, dolphin_init_verbs
);
1357 /* verb exec op override */
1358 spec
->exec_verb
= codec
->core
.exec_verb
;
1359 codec
->core
.exec_verb
= dolphin_exec_verb
;
1361 spec
->scodecs
[CS8409_CODEC0
] = &dolphin_cs42l42_0
;
1362 spec
->scodecs
[CS8409_CODEC0
]->codec
= codec
;
1363 spec
->scodecs
[CS8409_CODEC1
] = &dolphin_cs42l42_1
;
1364 spec
->scodecs
[CS8409_CODEC1
]->codec
= codec
;
1365 spec
->num_scodecs
= 2;
1366 spec
->gen
.suppress_vmaster
= 1;
1368 codec
->patch_ops
= cs8409_dolphin_patch_ops
;
1370 /* GPIO 1,5 out, 0,4 in */
1371 spec
->gpio_dir
= spec
->scodecs
[CS8409_CODEC0
]->reset_gpio
|
1372 spec
->scodecs
[CS8409_CODEC1
]->reset_gpio
;
1373 spec
->gpio_data
= 0;
1374 spec
->gpio_mask
= 0x03f;
1376 /* Basic initial sequence for specific hw configuration */
1377 snd_hda_sequence_write(codec
, dolphin_init_verbs
);
1379 snd_hda_jack_add_kctl(codec
, DOLPHIN_LO_PIN_NID
, "Line Out", true,
1380 SND_JACK_HEADPHONE
, NULL
);
1382 snd_hda_jack_add_kctl(codec
, DOLPHIN_AMIC_PIN_NID
, "Microphone", true,
1383 SND_JACK_MICROPHONE
, NULL
);
1385 cs8409_fix_caps(codec
, DOLPHIN_HP_PIN_NID
);
1386 cs8409_fix_caps(codec
, DOLPHIN_LO_PIN_NID
);
1387 cs8409_fix_caps(codec
, DOLPHIN_AMIC_PIN_NID
);
1389 spec
->scodecs
[CS8409_CODEC0
]->full_scale_vol
= CS42L42_FULL_SCALE_VOL_MINUS6DB
;
1390 spec
->scodecs
[CS8409_CODEC1
]->full_scale_vol
= CS42L42_FULL_SCALE_VOL_MINUS6DB
;
1393 case HDA_FIXUP_ACT_PROBE
:
1394 /* Fix Sample Rate to 48kHz */
1395 spec
->gen
.stream_analog_playback
= &cs42l42_48k_pcm_analog_playback
;
1396 spec
->gen
.stream_analog_capture
= &cs42l42_48k_pcm_analog_capture
;
1398 spec
->gen
.pcm_playback_hook
= cs42l42_playback_pcm_hook
;
1399 spec
->gen
.pcm_capture_hook
= cs42l42_capture_pcm_hook
;
1400 snd_hda_gen_add_kctl(&spec
->gen
, "Headphone Playback Volume",
1401 &cs42l42_dac_volume_mixer
);
1402 snd_hda_gen_add_kctl(&spec
->gen
, "Mic Capture Volume", &cs42l42_adc_volume_mixer
);
1403 kctrl
= snd_hda_gen_add_kctl(&spec
->gen
, "Line Out Playback Volume",
1404 &cs42l42_dac_volume_mixer
);
1405 /* Update Line Out kcontrol template */
1407 kctrl
->private_value
= HDA_COMPOSE_AMP_VAL_OFS(DOLPHIN_HP_PIN_NID
, 3, CS8409_CODEC1
,
1408 HDA_OUTPUT
, CS42L42_VOL_DAC
) | HDA_AMP_VAL_MIN_MUTE
;
1409 cs8409_enable_ur(codec
, 0);
1410 snd_hda_codec_set_name(codec
, "CS8409/CS42L42");
1412 case HDA_FIXUP_ACT_INIT
:
1413 dolphin_hw_init(codec
);
1414 spec
->init_done
= 1;
1415 if (spec
->init_done
&& spec
->build_ctrl_done
) {
1416 for (i
= 0; i
< spec
->num_scodecs
; i
++) {
1417 if (!spec
->scodecs
[i
]->hp_jack_in
)
1418 cs42l42_run_jack_detect(spec
->scodecs
[i
]);
1422 case HDA_FIXUP_ACT_BUILD
:
1423 spec
->build_ctrl_done
= 1;
1424 /* Run jack auto detect first time on boot
1425 * after controls have been added, to check if jack has
1426 * been already plugged in.
1427 * Run immediately after init.
1429 if (spec
->init_done
&& spec
->build_ctrl_done
) {
1430 for (i
= 0; i
< spec
->num_scodecs
; i
++) {
1431 if (!spec
->scodecs
[i
]->hp_jack_in
)
1432 cs42l42_run_jack_detect(spec
->scodecs
[i
]);
1441 static int patch_cs8409(struct hda_codec
*codec
)
1445 if (!cs8409_alloc_spec(codec
))
1448 snd_hda_pick_fixup(codec
, cs8409_models
, cs8409_fixup_tbl
, cs8409_fixups
);
1450 codec_dbg(codec
, "Picked ID=%d, VID=%08x, DEV=%08x\n", codec
->fixup_id
,
1451 codec
->bus
->pci
->subsystem_vendor
,
1452 codec
->bus
->pci
->subsystem_device
);
1454 snd_hda_apply_fixup(codec
, HDA_FIXUP_ACT_PRE_PROBE
);
1456 err
= cs8409_parse_auto_config(codec
);
1462 snd_hda_apply_fixup(codec
, HDA_FIXUP_ACT_PROBE
);
1466 static const struct hda_device_id snd_hda_id_cs8409
[] = {
1467 HDA_CODEC_ENTRY(0x10138409, "CS8409", patch_cs8409
),
1470 MODULE_DEVICE_TABLE(hdaudio
, snd_hda_id_cs8409
);
1472 static struct hda_codec_driver cs8409_driver
= {
1473 .id
= snd_hda_id_cs8409
,
1475 module_hda_codec_driver(cs8409_driver
);
1477 MODULE_LICENSE("GPL");
1478 MODULE_DESCRIPTION("Cirrus Logic HDA bridge");