patch_cs8409.c (165b81c4ac3062d61e5422c85fcd55e8d0f805da) patch_cs8409.c (636eb9d26f29cd9e195a6bae783315284efa11da)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * HD audio interface patch for Cirrus Logic CS8409 HDA bridge chip
4 *
5 * Copyright (C) 2021 Cirrus Logic, Inc. and
6 * Cirrus Logic International Semiconductor Ltd.
7 */
8
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
15#include "patch_cs8409.h"
16
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * HD audio interface patch for Cirrus Logic CS8409 HDA bridge chip
4 *
5 * Copyright (C) 2021 Cirrus Logic, Inc. and
6 * Cirrus Logic International Semiconductor Ltd.
7 */
8
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
15#include "patch_cs8409.h"
16
17/******************************************************************************
18 * CS8409 Specific Functions
19 ******************************************************************************/
20
17static int cs8409_parse_auto_config(struct hda_codec *codec)
18{
19 struct cs8409_spec *spec = codec->spec;
20 int err;
21 int i;
22
23 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0);
24 if (err < 0)

--- 27 unchanged lines hidden (view full) ---

52 struct cs8409_spec *spec;
53
54 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
55 if (!spec)
56 return NULL;
57 codec->spec = spec;
58 spec->codec = codec;
59 codec->power_save_node = 1;
21static int cs8409_parse_auto_config(struct hda_codec *codec)
22{
23 struct cs8409_spec *spec = codec->spec;
24 int err;
25 int i;
26
27 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0);
28 if (err < 0)

--- 27 unchanged lines hidden (view full) ---

56 struct cs8409_spec *spec;
57
58 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
59 if (!spec)
60 return NULL;
61 codec->spec = spec;
62 spec->codec = codec;
63 codec->power_save_node = 1;
64 mutex_init(&spec->i2c_mux);
60 INIT_DELAYED_WORK(&spec->i2c_clk_work, cs8409_disable_i2c_clock_worker);
61 snd_hda_gen_spec_init(&spec->gen);
62
63 return spec;
64}
65
66static inline int cs8409_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
67{

--- 296 unchanged lines hidden (view full) ---

364 return 0;
365
366error:
367 mutex_unlock(&spec->i2c_mux);
368 codec_err(codec, "I2C Bulk Write Failed 0x%02x\n", i2c_address);
369 return -EIO;
370}
371
65 INIT_DELAYED_WORK(&spec->i2c_clk_work, cs8409_disable_i2c_clock_worker);
66 snd_hda_gen_spec_init(&spec->gen);
67
68 return spec;
69}
70
71static inline int cs8409_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
72{

--- 296 unchanged lines hidden (view full) ---

369 return 0;
370
371error:
372 mutex_unlock(&spec->i2c_mux);
373 codec_err(codec, "I2C Bulk Write Failed 0x%02x\n", i2c_address);
374 return -EIO;
375}
376
372int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo)
377static int cs8409_init(struct hda_codec *codec)
373{
378{
379 int ret = snd_hda_gen_init(codec);
380
381 if (!ret)
382 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
383
384 return ret;
385}
386
387static int cs8409_build_controls(struct hda_codec *codec)
388{
389 int err;
390
391 err = snd_hda_gen_build_controls(codec);
392 if (err < 0)
393 return err;
394 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
395
396 return 0;
397}
398
399/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */
400static void cs8409_enable_ur(struct hda_codec *codec, int flag)
401{
402 /* GPIO4 INT# and GPIO3 WAKE# */
403 snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK,
404 flag ? CS8409_CS42L42_INT : 0);
405
406 snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_UNSOLICITED_ENABLE,
407 flag ? AC_UNSOL_ENABLED : 0);
408
409}
410
411static void cs8409_fix_caps(struct hda_codec *codec, unsigned int nid)
412{
413 int caps;
414
415 /* CS8409 is simple HDA bridge and intended to be used with a remote
416 * companion codec. Most of input/output PIN(s) have only basic
417 * capabilities. Receive and Transmit NID(s) have only OUTC and INC
418 * capabilities and no presence detect capable (PDC) and call to
419 * snd_hda_gen_build_controls() will mark them as non detectable
420 * phantom jacks. However, a companion codec may be
421 * connected to these pins which supports jack detect
422 * capabilities. We have to override pin capabilities,
423 * otherwise they will not be created as input devices.
424 */
425 caps = snd_hdac_read_parm(&codec->core, nid, AC_PAR_PIN_CAP);
426 if (caps >= 0)
427 snd_hdac_override_parm(&codec->core, nid, AC_PAR_PIN_CAP,
428 (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT)));
429
430 snd_hda_override_wcaps(codec, nid, (get_wcaps(codec, nid) | AC_WCAP_UNSOL_CAP));
431}
432
433/******************************************************************************
434 * CS42L42 Specific Functions
435 ******************************************************************************/
436
437int cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo)
438{
374 unsigned int ofs = get_amp_offset(kctrl);
375 u8 chs = get_amp_channels(kctrl);
376
377 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
378 uinfo->value.integer.step = 1;
379 uinfo->count = chs == 3 ? 2 : 1;
380
381 switch (ofs) {
382 case CS42L42_VOL_DAC:
439 unsigned int ofs = get_amp_offset(kctrl);
440 u8 chs = get_amp_channels(kctrl);
441
442 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
443 uinfo->value.integer.step = 1;
444 uinfo->count = chs == 3 ? 2 : 1;
445
446 switch (ofs) {
447 case CS42L42_VOL_DAC:
383 uinfo->value.integer.min = CS8409_CS42L42_HP_VOL_REAL_MIN;
384 uinfo->value.integer.max = CS8409_CS42L42_HP_VOL_REAL_MAX;
448 uinfo->value.integer.min = CS42L42_HP_VOL_REAL_MIN;
449 uinfo->value.integer.max = CS42L42_HP_VOL_REAL_MAX;
385 break;
386 case CS42L42_VOL_ADC:
450 break;
451 case CS42L42_VOL_ADC:
387 uinfo->value.integer.min = CS8409_CS42L42_AMIC_VOL_REAL_MIN;
388 uinfo->value.integer.max = CS8409_CS42L42_AMIC_VOL_REAL_MAX;
452 uinfo->value.integer.min = CS42L42_AMIC_VOL_REAL_MIN;
453 uinfo->value.integer.max = CS42L42_AMIC_VOL_REAL_MAX;
389 break;
390 default:
391 break;
392 }
393
394 return 0;
395}
396
454 break;
455 default:
456 break;
457 }
458
459 return 0;
460}
461
397int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
462int cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
398{
399 struct hda_codec *codec = snd_kcontrol_chip(kctrl);
400 struct cs8409_spec *spec = codec->spec;
401 int chs = get_amp_channels(kctrl);
402 unsigned int ofs = get_amp_offset(kctrl);
403 long *valp = uctrl->value.integer.value;
404
405 switch (ofs) {

--- 9 unchanged lines hidden (view full) ---

415 break;
416 default:
417 break;
418 }
419
420 return 0;
421}
422
463{
464 struct hda_codec *codec = snd_kcontrol_chip(kctrl);
465 struct cs8409_spec *spec = codec->spec;
466 int chs = get_amp_channels(kctrl);
467 unsigned int ofs = get_amp_offset(kctrl);
468 long *valp = uctrl->value.integer.value;
469
470 switch (ofs) {

--- 9 unchanged lines hidden (view full) ---

480 break;
481 default:
482 break;
483 }
484
485 return 0;
486}
487
423int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
488int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
424{
425 struct hda_codec *codec = snd_kcontrol_chip(kctrl);
426 struct cs8409_spec *spec = codec->spec;
427 int chs = get_amp_channels(kctrl);
428 unsigned int ofs = get_amp_offset(kctrl);
429 long *valp = uctrl->value.integer.value;
430
431 switch (ofs) {
432 case CS42L42_VOL_DAC:
433 if (chs & BIT(0)) {
434 spec->vol[ofs] = *valp;
489{
490 struct hda_codec *codec = snd_kcontrol_chip(kctrl);
491 struct cs8409_spec *spec = codec->spec;
492 int chs = get_amp_channels(kctrl);
493 unsigned int ofs = get_amp_offset(kctrl);
494 long *valp = uctrl->value.integer.value;
495
496 switch (ofs) {
497 case CS42L42_VOL_DAC:
498 if (chs & BIT(0)) {
499 spec->vol[ofs] = *valp;
435 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA,
436 -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK);
500 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHA,
501 -(spec->vol[ofs]) & CS42L42_REG_HS_VOL_MASK);
437 }
438 if (chs & BIT(1)) {
439 ofs++;
440 valp++;
441 spec->vol[ofs] = *valp;
502 }
503 if (chs & BIT(1)) {
504 ofs++;
505 valp++;
506 spec->vol[ofs] = *valp;
442 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB,
443 -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK);
507 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHB,
508 -(spec->vol[ofs]) & CS42L42_REG_HS_VOL_MASK);
444 }
445 break;
446 case CS42L42_VOL_ADC:
447 if (chs & BIT(0)) {
448 spec->vol[ofs] = *valp;
509 }
510 break;
511 case CS42L42_VOL_ADC:
512 if (chs & BIT(0)) {
513 spec->vol[ofs] = *valp;
449 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL,
450 spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK);
514 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_AMIC_VOL,
515 spec->vol[ofs] & CS42L42_REG_AMIC_VOL_MASK);
451 }
452 break;
453 default:
454 break;
455 }
456
457 return 0;
458}
459
516 }
517 break;
518 default:
519 break;
520 }
521
522 return 0;
523}
524
460/* Assert/release RTS# line to CS42L42 */
461static void cs8409_cs42l42_reset(struct hda_codec *codec)
462{
463 struct cs8409_spec *spec = codec->spec;
464 struct cs8409_i2c_param irq_regs[] = {
465 { 0x1308, 0x00 },
466 { 0x1309, 0x00 },
467 { 0x130A, 0x00 },
468 { 0x130F, 0x00 },
469 };
470
471 /* Assert RTS# line */
472 snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0);
473 /* wait ~10ms */
474 usleep_range(10000, 15000);
475 /* Release RTS# line */
476 snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, CS8409_CS42L42_RESET);
477 /* wait ~10ms */
478 usleep_range(10000, 15000);
479
480 spec->cs42l42_suspended = 0;
481 spec->last_page = 0;
482
483 /* Clear interrupts, by reading interrupt status registers */
484 cs8409_i2c_bulk_read(codec, CS42L42_I2C_ADDR, irq_regs, ARRAY_SIZE(irq_regs));
485}
486
487/* Configure CS42L42 slave codec for jack autodetect */
525/* Configure CS42L42 slave codec for jack autodetect */
488static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec)
526static void cs42l42_enable_jack_detect(struct hda_codec *codec)
489{
490 /* Set TIP_SENSE_EN for analog front-end of tip sense.
491 * Additionally set HSBIAS_SENSE_EN for some variants.
492 */
493 if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_BULLSEYE)
494 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020);
495 else
496 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x00a0);

--- 6 unchanged lines hidden (view full) ---

503 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C0);
504 /* Clear interrupts status */
505 cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f);
506 /* Enable interrupt */
507 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3);
508}
509
510/* Enable and run CS42L42 slave codec jack auto detect */
527{
528 /* Set TIP_SENSE_EN for analog front-end of tip sense.
529 * Additionally set HSBIAS_SENSE_EN for some variants.
530 */
531 if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_BULLSEYE)
532 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020);
533 else
534 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x00a0);

--- 6 unchanged lines hidden (view full) ---

541 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C0);
542 /* Clear interrupts status */
543 cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f);
544 /* Enable interrupt */
545 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3);
546}
547
548/* Enable and run CS42L42 slave codec jack auto detect */
511static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec)
549static void cs42l42_run_jack_detect(struct hda_codec *codec)
512{
513 /* Clear interrupts */
514 cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308);
515 cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77);
516 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xFF);
517 cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f);
518
519 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87);

--- 5 unchanged lines hidden (view full) ---

525 usleep_range(110000, 200000);
526 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77);
527 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0);
528 /* Wait ~10ms */
529 usleep_range(10000, 25000);
530
531}
532
550{
551 /* Clear interrupts */
552 cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308);
553 cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77);
554 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xFF);
555 cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f);
556
557 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87);

--- 5 unchanged lines hidden (view full) ---

563 usleep_range(110000, 200000);
564 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77);
565 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0);
566 /* Wait ~10ms */
567 usleep_range(10000, 25000);
568
569}
570
533/*
534 * In the case of CS8409 we do not have unsolicited events from NID's 0x24
535 * and 0x34 where hs mic and hp are connected. Companion codec CS42L42 will
536 * generate interrupt via gpio 4 to notify jack events. We have to overwrite
537 * generic snd_hda_jack_unsol_event(), read CS42L42 jack detect status registers
538 * and then notify status via generic snd_hda_jack_unsol_event() call.
539 */
540static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res)
571static int cs42l42_jack_unsol_event(struct hda_codec *codec)
541{
542 struct cs8409_spec *spec = codec->spec;
543 int status_changed = 0;
544 int reg_cdc_status;
545 int reg_hs_status;
546 int reg_ts_status;
547 int type;
572{
573 struct cs8409_spec *spec = codec->spec;
574 int status_changed = 0;
575 int reg_cdc_status;
576 int reg_hs_status;
577 int reg_ts_status;
578 int type;
548 struct hda_jack_tbl *jk;
549
579
550 /* jack_unsol_event() will be called every time gpio line changing state.
551 * In this case gpio4 line goes up as a result of reading interrupt status
552 * registers in previous cs8409_jack_unsol_event() call.
553 * We don't need to handle this event, ignoring...
554 */
555 if (res & CS8409_CS42L42_INT)
556 return;
557
558 /* Read jack detect status registers */
559 reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308);
560 reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124);
561 reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f);
562
563 /* If status values are < 0, read error has occurred. */
564 if (reg_cdc_status < 0 || reg_hs_status < 0 || reg_ts_status < 0)
580 /* Read jack detect status registers */
581 reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308);
582 reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124);
583 reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f);
584
585 /* If status values are < 0, read error has occurred. */
586 if (reg_cdc_status < 0 || reg_hs_status < 0 || reg_ts_status < 0)
565 return;
587 return -EIO;
566
567 /* HSDET_AUTO_DONE */
568 if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE) {
569
570 /* Disable HSDET_AUTO_DONE */
571 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFF);
572
573 type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1);

--- 20 unchanged lines hidden (view full) ---

594
595 /* Re-Enable Tip Sense Interrupt */
596 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3);
597
598 } else {
599 /* TIP_SENSE INSERT/REMOVE */
600 switch (reg_ts_status) {
601 case CS42L42_JACK_INSERTED:
588
589 /* HSDET_AUTO_DONE */
590 if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE) {
591
592 /* Disable HSDET_AUTO_DONE */
593 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFF);
594
595 type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1);

--- 20 unchanged lines hidden (view full) ---

616
617 /* Re-Enable Tip Sense Interrupt */
618 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3);
619
620 } else {
621 /* TIP_SENSE INSERT/REMOVE */
622 switch (reg_ts_status) {
623 case CS42L42_JACK_INSERTED:
602 cs8409_cs42l42_run_jack_detect(codec);
624 cs42l42_run_jack_detect(codec);
603 break;
604
605 case CS42L42_JACK_REMOVED:
606 if (spec->cs42l42_hp_jack_in || spec->cs42l42_mic_jack_in) {
607 status_changed = 1;
608 spec->cs42l42_hp_jack_in = 0;
609 spec->cs42l42_mic_jack_in = 0;
610 }
611 break;
612
613 default:
614 /* jack in transition */
615 status_changed = 0;
616 break;
617 }
618 }
619
625 break;
626
627 case CS42L42_JACK_REMOVED:
628 if (spec->cs42l42_hp_jack_in || spec->cs42l42_mic_jack_in) {
629 status_changed = 1;
630 spec->cs42l42_hp_jack_in = 0;
631 spec->cs42l42_mic_jack_in = 0;
632 }
633 break;
634
635 default:
636 /* jack in transition */
637 status_changed = 0;
638 break;
639 }
640 }
641
620 if (status_changed) {
642 return status_changed;
643}
621
644
645/* Assert/release RTS# line to CS42L42 */
646static void cs42l42_reset(struct hda_codec *codec)
647{
648 struct cs8409_spec *spec = codec->spec;
649 struct cs8409_i2c_param irq_regs[] = {
650 { 0x1308, 0x00 },
651 { 0x1309, 0x00 },
652 { 0x130A, 0x00 },
653 { 0x130F, 0x00 },
654 };
655
656 /* Assert RTS# line */
657 snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0);
658 /* wait ~10ms */
659 usleep_range(10000, 15000);
660 /* Release RTS# line */
661 snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, CS8409_CS42L42_RESET);
662 /* wait ~10ms */
663 usleep_range(10000, 15000);
664
665 spec->cs42l42_suspended = 0;
666 spec->last_page = 0;
667
668 /* Clear interrupts, by reading interrupt status registers */
669 cs8409_i2c_bulk_read(codec, CS42L42_I2C_ADDR, irq_regs, ARRAY_SIZE(irq_regs));
670}
671
672#ifdef CONFIG_PM
673static void cs42l42_suspend(struct hda_codec *codec)
674{
675 /* Power down CS42L42 ASP/EQ/MIX/HP */
676 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe);
677}
678#endif
679
680static void cs8409_free(struct hda_codec *codec)
681{
682 struct cs8409_spec *spec = codec->spec;
683
684 /* Cancel i2c clock disable timer, and disable clock if left enabled */
685 cancel_delayed_work_sync(&spec->i2c_clk_work);
686 cs8409_disable_i2c_clock(codec);
687
688 snd_hda_gen_free(codec);
689}
690
691/******************************************************************************
692 * BULLSEYE / WARLOCK / CYBORG Specific Functions
693 * CS8409/CS42L42
694 ******************************************************************************/
695
696/*
697 * In the case of CS8409 we do not have unsolicited events from NID's 0x24
698 * and 0x34 where hs mic and hp are connected. Companion codec CS42L42 will
699 * generate interrupt via gpio 4 to notify jack events. We have to overwrite
700 * generic snd_hda_jack_unsol_event(), read CS42L42 jack detect status registers
701 * and then notify status via generic snd_hda_jack_unsol_event() call.
702 */
703static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res)
704{
705 struct cs8409_spec *spec = codec->spec;
706 struct hda_jack_tbl *jk;
707
708 /* jack_unsol_event() will be called every time gpio line changing state.
709 * In this case gpio4 line goes up as a result of reading interrupt status
710 * registers in previous cs8409_jack_unsol_event() call.
711 * We don't need to handle this event, ignoring...
712 */
713 if (res & CS8409_CS42L42_INT)
714 return;
715
716 if (cs42l42_jack_unsol_event(codec)) {
622 snd_hda_set_pin_ctl(codec, CS8409_CS42L42_SPK_PIN_NID,
623 spec->cs42l42_hp_jack_in ? 0 : PIN_OUT);
717 snd_hda_set_pin_ctl(codec, CS8409_CS42L42_SPK_PIN_NID,
718 spec->cs42l42_hp_jack_in ? 0 : PIN_OUT);
624
625 /* Report jack*/
626 jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_HP_PIN_NID, 0);
719 /* Report jack*/
720 jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_HP_PIN_NID, 0);
627 if (jk) {
721 if (jk)
628 snd_hda_jack_unsol_event(codec, (jk->tag << AC_UNSOL_RES_TAG_SHIFT) &
629 AC_UNSOL_RES_TAG);
722 snd_hda_jack_unsol_event(codec, (jk->tag << AC_UNSOL_RES_TAG_SHIFT) &
723 AC_UNSOL_RES_TAG);
630 }
631 /* Report jack*/
632 jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_AMIC_PIN_NID, 0);
724 /* Report jack*/
725 jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_AMIC_PIN_NID, 0);
633 if (jk) {
726 if (jk)
634 snd_hda_jack_unsol_event(codec, (jk->tag << AC_UNSOL_RES_TAG_SHIFT) &
635 AC_UNSOL_RES_TAG);
727 snd_hda_jack_unsol_event(codec, (jk->tag << AC_UNSOL_RES_TAG_SHIFT) &
728 AC_UNSOL_RES_TAG);
636 }
637 }
638}
639
729 }
730}
731
640/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */
641static void cs8409_enable_ur(struct hda_codec *codec, int flag)
642{
643 /* GPIO4 INT# and GPIO3 WAKE# */
644 snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK,
645 flag ? CS8409_CS42L42_INT : 0);
646
647 snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_UNSOLICITED_ENABLE,
648 flag ? AC_UNSOL_ENABLED : 0);
649
650}
651
652#ifdef CONFIG_PM
653/* Manage PDREF, when transition to D3hot */
732#ifdef CONFIG_PM
733/* Manage PDREF, when transition to D3hot */
654static int cs8409_suspend(struct hda_codec *codec)
734static int cs8409_cs42l42_suspend(struct hda_codec *codec)
655{
656 struct cs8409_spec *spec = codec->spec;
657
658 cs8409_enable_ur(codec, 0);
659
735{
736 struct cs8409_spec *spec = codec->spec;
737
738 cs8409_enable_ur(codec, 0);
739
660 /* Power down CS42L42 ASP/EQ/MIX/HP */
661 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe);
740 cs42l42_suspend(codec);
662
663 spec->cs42l42_suspended = 1;
664
665 /* Assert CS42L42 RTS# line */
666 snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0);
667
668 /* Cancel i2c clock disable timer, and disable clock if left enabled */
669 cancel_delayed_work_sync(&spec->i2c_clk_work);
670 cs8409_disable_i2c_clock(codec);
671
672 snd_hda_shutup_pins(codec);
673
674 return 0;
675}
676#endif
677
741
742 spec->cs42l42_suspended = 1;
743
744 /* Assert CS42L42 RTS# line */
745 snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0);
746
747 /* Cancel i2c clock disable timer, and disable clock if left enabled */
748 cancel_delayed_work_sync(&spec->i2c_clk_work);
749 cs8409_disable_i2c_clock(codec);
750
751 snd_hda_shutup_pins(codec);
752
753 return 0;
754}
755#endif
756
678static void cs8409_free(struct hda_codec *codec)
679{
680 struct cs8409_spec *spec = codec->spec;
681
682 /* Cancel i2c clock disable timer, and disable clock if left enabled */
683 cancel_delayed_work_sync(&spec->i2c_clk_work);
684 cs8409_disable_i2c_clock(codec);
685
686 snd_hda_gen_free(codec);
687}
688
689/* Vendor specific HW configuration
690 * PLL, ASP, I2C, SPI, GPIOs, DMIC etc...
691 */
692static void cs8409_cs42l42_hw_init(struct hda_codec *codec)
693{
694 const struct cs8409_cir_param *seq = cs8409_cs42l42_hw_cfg;
695 const struct cs8409_cir_param *seq_bullseye = cs8409_cs42l42_bullseye_atn;
696 struct cs8409_spec *spec = codec->spec;

--- 10 unchanged lines hidden (view full) ---

707 for (; seq->nid; seq++)
708 cs8409_vendor_coef_set(codec, seq->cir, seq->coeff);
709
710 if (codec->fixup_id == CS8409_BULLSEYE)
711 for (; seq_bullseye->nid; seq_bullseye++)
712 cs8409_vendor_coef_set(codec, seq_bullseye->cir, seq_bullseye->coeff);
713
714 /* Reset CS42L42 */
757/* Vendor specific HW configuration
758 * PLL, ASP, I2C, SPI, GPIOs, DMIC etc...
759 */
760static void cs8409_cs42l42_hw_init(struct hda_codec *codec)
761{
762 const struct cs8409_cir_param *seq = cs8409_cs42l42_hw_cfg;
763 const struct cs8409_cir_param *seq_bullseye = cs8409_cs42l42_bullseye_atn;
764 struct cs8409_spec *spec = codec->spec;

--- 10 unchanged lines hidden (view full) ---

775 for (; seq->nid; seq++)
776 cs8409_vendor_coef_set(codec, seq->cir, seq->coeff);
777
778 if (codec->fixup_id == CS8409_BULLSEYE)
779 for (; seq_bullseye->nid; seq_bullseye++)
780 cs8409_vendor_coef_set(codec, seq_bullseye->cir, seq_bullseye->coeff);
781
782 /* Reset CS42L42 */
715 cs8409_cs42l42_reset(codec);
783 cs42l42_reset(codec);
716
717 /* Initialise CS42L42 companion codec */
718 cs8409_i2c_bulk_write(codec, CS42L42_I2C_ADDR, cs42l42_init_reg_seq,
719 CS42L42_INIT_REG_SEQ_SIZE);
720
721 if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) {
722 /* FULL_SCALE_VOL = 0 for Warlock / Cyborg */
723 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01);
724 /* DMIC1_MO=00b, DMIC1/2_SR=1 */
725 cs8409_vendor_coef_set(codec, 0x09, 0x0003);
726 }
727
728 /* Restore Volumes after Resume */
784
785 /* Initialise CS42L42 companion codec */
786 cs8409_i2c_bulk_write(codec, CS42L42_I2C_ADDR, cs42l42_init_reg_seq,
787 CS42L42_INIT_REG_SEQ_SIZE);
788
789 if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) {
790 /* FULL_SCALE_VOL = 0 for Warlock / Cyborg */
791 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01);
792 /* DMIC1_MO=00b, DMIC1/2_SR=1 */
793 cs8409_vendor_coef_set(codec, 0x09, 0x0003);
794 }
795
796 /* Restore Volumes after Resume */
729 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA,
730 -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK);
731 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB,
732 -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK);
733 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL,
734 spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK);
797 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHA,
798 -(spec->vol[1]) & CS42L42_REG_HS_VOL_MASK);
799 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHB,
800 -(spec->vol[2]) & CS42L42_REG_HS_VOL_MASK);
801 cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_AMIC_VOL,
802 spec->vol[0] & CS42L42_REG_AMIC_VOL_MASK);
735
803
736 cs8409_cs42l42_enable_jack_detect(codec);
804 cs42l42_enable_jack_detect(codec);
737
738 /* Enable Unsolicited Response */
739 cs8409_enable_ur(codec, 1);
740}
741
805
806 /* Enable Unsolicited Response */
807 cs8409_enable_ur(codec, 1);
808}
809
742static int cs8409_cs42l42_init(struct hda_codec *codec)
743{
744 int ret = snd_hda_gen_init(codec);
745
746 if (!ret)
747 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
748
749 return ret;
750}
751
752static int cs8409_build_controls(struct hda_codec *codec)
753{
754 int err;
755
756 err = snd_hda_gen_build_controls(codec);
757 if (err < 0)
758 return err;
759 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
760
761 return 0;
762}
763
764static const struct hda_codec_ops cs8409_cs42l42_patch_ops = {
765 .build_controls = cs8409_build_controls,
766 .build_pcms = snd_hda_gen_build_pcms,
810static const struct hda_codec_ops cs8409_cs42l42_patch_ops = {
811 .build_controls = cs8409_build_controls,
812 .build_pcms = snd_hda_gen_build_pcms,
767 .init = cs8409_cs42l42_init,
813 .init = cs8409_init,
768 .free = cs8409_free,
769 .unsol_event = cs8409_jack_unsol_event,
770#ifdef CONFIG_PM
814 .free = cs8409_free,
815 .unsol_event = cs8409_jack_unsol_event,
816#ifdef CONFIG_PM
771 .suspend = cs8409_suspend,
817 .suspend = cs8409_cs42l42_suspend,
772#endif
773};
774
775static int cs8409_cs42l42_exec_verb(struct hdac_device *dev, unsigned int cmd, unsigned int flags,
776 unsigned int *res)
777{
778 struct hda_codec *codec = container_of(dev, struct hda_codec, core);
779 struct cs8409_spec *spec = codec->spec;

--- 26 unchanged lines hidden (view full) ---

806 }
807
808 return spec->exec_verb(dev, cmd, flags, res);
809}
810
811void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action)
812{
813 struct cs8409_spec *spec = codec->spec;
818#endif
819};
820
821static int cs8409_cs42l42_exec_verb(struct hdac_device *dev, unsigned int cmd, unsigned int flags,
822 unsigned int *res)
823{
824 struct hda_codec *codec = container_of(dev, struct hda_codec, core);
825 struct cs8409_spec *spec = codec->spec;

--- 26 unchanged lines hidden (view full) ---

852 }
853
854 return spec->exec_verb(dev, cmd, flags, res);
855}
856
857void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action)
858{
859 struct cs8409_spec *spec = codec->spec;
814 int caps;
815
816 switch (action) {
817 case HDA_FIXUP_ACT_PRE_PROBE:
818 snd_hda_add_verbs(codec, cs8409_cs42l42_init_verbs);
819 /* verb exec op override */
820 spec->exec_verb = codec->core.exec_verb;
821 codec->core.exec_verb = cs8409_cs42l42_exec_verb;
822
860
861 switch (action) {
862 case HDA_FIXUP_ACT_PRE_PROBE:
863 snd_hda_add_verbs(codec, cs8409_cs42l42_init_verbs);
864 /* verb exec op override */
865 spec->exec_verb = codec->core.exec_verb;
866 codec->core.exec_verb = cs8409_cs42l42_exec_verb;
867
823 mutex_init(&spec->i2c_mux);
824
825 codec->patch_ops = cs8409_cs42l42_patch_ops;
826
827 spec->gen.suppress_auto_mute = 1;
828 spec->gen.no_primary_hp = 1;
829 spec->gen.suppress_vmaster = 1;
830
831 /* GPIO 5 out, 3,4 in */
832 spec->gpio_dir = CS8409_CS42L42_RESET;
833 spec->gpio_data = 0;
834 spec->gpio_mask = 0x03f;
835
836 spec->cs42l42_hp_jack_in = 0;
837 spec->cs42l42_mic_jack_in = 0;
838 spec->cs42l42_suspended = 1;
839 spec->paged = 1;
840
841 /* Basic initial sequence for specific hw configuration */
842 snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs);
843
868 codec->patch_ops = cs8409_cs42l42_patch_ops;
869
870 spec->gen.suppress_auto_mute = 1;
871 spec->gen.no_primary_hp = 1;
872 spec->gen.suppress_vmaster = 1;
873
874 /* GPIO 5 out, 3,4 in */
875 spec->gpio_dir = CS8409_CS42L42_RESET;
876 spec->gpio_data = 0;
877 spec->gpio_mask = 0x03f;
878
879 spec->cs42l42_hp_jack_in = 0;
880 spec->cs42l42_mic_jack_in = 0;
881 spec->cs42l42_suspended = 1;
882 spec->paged = 1;
883
884 /* Basic initial sequence for specific hw configuration */
885 snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs);
886
844 /* CS8409 is simple HDA bridge and intended to be used with a remote
845 * companion codec. Most of input/output PIN(s) have only basic
846 * capabilities. NID(s) 0x24 and 0x34 have only OUTC and INC
847 * capabilities and no presence detect capable (PDC) and call to
848 * snd_hda_gen_build_controls() will mark them as non detectable
849 * phantom jacks. However, in this configuration companion codec
850 * CS42L42 is connected to these pins and it has jack detect
851 * capabilities. We have to override pin capabilities,
852 * otherwise they will not be created as input devices.
853 */
854 caps = snd_hdac_read_parm(&codec->core, CS8409_CS42L42_HP_PIN_NID,
855 AC_PAR_PIN_CAP);
856 if (caps >= 0)
857 snd_hdac_override_parm(&codec->core,
858 CS8409_CS42L42_HP_PIN_NID, AC_PAR_PIN_CAP,
859 (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT)));
887 cs8409_fix_caps(codec, CS8409_CS42L42_HP_PIN_NID);
888 cs8409_fix_caps(codec, CS8409_CS42L42_AMIC_PIN_NID);
860
889
861 caps = snd_hdac_read_parm(&codec->core, CS8409_CS42L42_AMIC_PIN_NID,
862 AC_PAR_PIN_CAP);
863 if (caps >= 0)
864 snd_hdac_override_parm(&codec->core,
865 CS8409_CS42L42_AMIC_PIN_NID, AC_PAR_PIN_CAP,
866 (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT)));
867
868 snd_hda_override_wcaps(codec, CS8409_CS42L42_HP_PIN_NID,
869 (get_wcaps(codec, CS8409_CS42L42_HP_PIN_NID) | AC_WCAP_UNSOL_CAP));
870
871 snd_hda_override_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID,
872 (get_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID) | AC_WCAP_UNSOL_CAP));
873 break;
874 case HDA_FIXUP_ACT_PROBE:
875 /* Set initial DMIC volume to -26 dB */
876 snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID,
877 HDA_INPUT, 0, 0xff, 0x19);
878 snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume",
879 &cs42l42_dac_volume_mixer);
880 snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume",

--- 7 unchanged lines hidden (view full) ---

888 cs8409_cs42l42_hw_init(codec);
889 fallthrough;
890 case HDA_FIXUP_ACT_BUILD:
891 /* Run jack auto detect first time on boot
892 * after controls have been added, to check if jack has
893 * been already plugged in.
894 * Run immediately after init.
895 */
890 break;
891 case HDA_FIXUP_ACT_PROBE:
892 /* Set initial DMIC volume to -26 dB */
893 snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID,
894 HDA_INPUT, 0, 0xff, 0x19);
895 snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume",
896 &cs42l42_dac_volume_mixer);
897 snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume",

--- 7 unchanged lines hidden (view full) ---

905 cs8409_cs42l42_hw_init(codec);
906 fallthrough;
907 case HDA_FIXUP_ACT_BUILD:
908 /* Run jack auto detect first time on boot
909 * after controls have been added, to check if jack has
910 * been already plugged in.
911 * Run immediately after init.
912 */
896 cs8409_cs42l42_run_jack_detect(codec);
913 cs42l42_run_jack_detect(codec);
897 usleep_range(100000, 150000);
898 break;
899 default:
900 break;
901 }
902}
903
904static int patch_cs8409(struct hda_codec *codec)

--- 37 unchanged lines hidden ---
914 usleep_range(100000, 150000);
915 break;
916 default:
917 break;
918 }
919}
920
921static int patch_cs8409(struct hda_codec *codec)

--- 37 unchanged lines hidden ---