Ack: Re: [12.04 SRU PATCH] ALSA: HDA: Add support for Cirrus Logic 4213
Herton Ronaldo Krzesinski
herton.krzesinski at canonical.com
Tue Jun 5 14:18:40 UTC 2012
On Tue, Jun 05, 2012 at 09:50:58AM +0200, David Henningsson wrote:
> The CS4213 chip is similar to the CS4210, but it does not have
> SPDIF capabilities. Also, it has fewer pins, and the vendor specific
> nid is different. With this patch, we have working inputs and outputs
> (and automute/autoswitch). However, we don't know anything about
> the vendor specific processing coefficients, so we don't read or write
> to that node in this patch.
>
> BugLink: https://bugs.launchpad.net/bugs/910792
> Tested-by: Hsin-Yi Chen <hychen at canonical.com>
> Signed-off-by: David Henningsson <david.henningsson at canonical.com>
> Signed-off-by: Takashi Iwai <tiwai at suse.de>
>
> (cherry picked from commit 5660ffd06935e564404412997a703279e325fa64)
> Signed-off-by: David Henningsson <david.henningsson at canonical.com>
> ---
> sound/pci/hda/patch_cirrus.c | 105 ++++++++++++++++++++++++++++--------------
> 1 file changed, 70 insertions(+), 35 deletions(-)
>
> Anthony Wong asked me to try to SRU this patch in order to be able to certify
> a machine for 12.04.
> The CS4213 shares some code with the CS4210 chip, but the CS4210 chip - which
> would be the possible regression risk here, was AFAIK never used in production.
> Therefore I believe this should be safe to SRU.
Ack, patch looks ok, code moves etc. all well isolated.
>
> diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
> index ee2c1ed..297f5e2 100644
> --- a/sound/pci/hda/patch_cirrus.c
> +++ b/sound/pci/hda/patch_cirrus.c
> @@ -138,7 +138,7 @@ enum {
> */
> #define CS4210_DAC_NID 0x02
> #define CS4210_ADC_NID 0x03
> -#define CS421X_VENDOR_NID 0x0B
> +#define CS4210_VENDOR_NID 0x0B
> #define CS421X_DMIC_PIN_NID 0x09 /* Port E */
> #define CS421X_SPDIF_PIN_NID 0x0A /* Port H */
>
> @@ -149,6 +149,10 @@ enum {
>
> #define SPDIF_EVENT 0x04
>
> +/* Cirrus Logic CS4213 is like CS4210 but does not have SPDIF input/output */
> +#define CS4213_VENDOR_NID 0x09
> +
> +
> static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
> {
> struct cs_spec *spec = codec->spec;
> @@ -923,8 +927,8 @@ static void cs_automute(struct hda_codec *codec)
> /* mute speakers if spdif or hp jack is plugged in */
> for (i = 0; i < cfg->speaker_outs; i++) {
> int pin_ctl = hp_present ? 0 : PIN_OUT;
> - /* detect on spdif is specific to CS421x */
> - if (spdif_present && (spec->vendor_nid == CS421X_VENDOR_NID))
> + /* detect on spdif is specific to CS4210 */
> + if (spdif_present && (spec->vendor_nid == CS4210_VENDOR_NID))
> pin_ctl = 0;
>
> nid = cfg->speaker_pins[i];
> @@ -938,8 +942,8 @@ static void cs_automute(struct hda_codec *codec)
> AC_VERB_SET_GPIO_DATA, gpio);
> }
>
> - /* specific to CS421x */
> - if (spec->vendor_nid == CS421X_VENDOR_NID) {
> + /* specific to CS4210 */
> + if (spec->vendor_nid == CS4210_VENDOR_NID) {
> /* mute HPs if spdif jack (SENSE_B) is present */
> for (i = 0; i < cfg->hp_outs; i++) {
> nid = cfg->hp_pins[i];
> @@ -976,7 +980,12 @@ static void cs_automic(struct hda_codec *codec)
> present = snd_hda_jack_detect(codec, nid);
>
> /* specific to CS421x, single ADC */
> - if (spec->vendor_nid == CS421X_VENDOR_NID) {
> + if (spec->vendor_nid == CS420X_VENDOR_NID) {
> + if (present)
> + change_cur_input(codec, spec->automic_idx, 0);
> + else
> + change_cur_input(codec, !spec->automic_idx, 0);
> + } else {
> if (present) {
> if (spec->cur_input != spec->automic_idx) {
> spec->last_input = spec->cur_input;
> @@ -986,11 +995,6 @@ static void cs_automic(struct hda_codec *codec)
> spec->cur_input = spec->last_input;
> }
> cs_update_input_select(codec);
> - } else {
> - if (present)
> - change_cur_input(codec, spec->automic_idx, 0);
> - else
> - change_cur_input(codec, !spec->automic_idx, 0);
> }
> }
>
> @@ -1072,15 +1076,8 @@ static void init_input(struct hda_codec *codec)
> if (spec->mic_detect && spec->automic_idx == i)
> snd_hda_jack_detect_enable(codec, pin, MIC_EVENT);
> }
> - /* specific to CS421x */
> - if (spec->vendor_nid == CS421X_VENDOR_NID) {
> - if (spec->mic_detect)
> - cs_automic(codec);
> - else {
> - spec->cur_adc = spec->adc_nid[spec->cur_input];
> - cs_update_input_select(codec);
> - }
> - } else {
> + /* CS420x has multiple ADC, CS421x has single ADC */
> + if (spec->vendor_nid == CS420X_VENDOR_NID) {
> change_cur_input(codec, spec->cur_input, 1);
> if (spec->mic_detect)
> cs_automic(codec);
> @@ -1094,6 +1091,13 @@ static void init_input(struct hda_codec *codec)
> * selected in IDX_SPDIF_CTL.
> */
> cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
> + } else {
> + if (spec->mic_detect)
> + cs_automic(codec);
> + else {
> + spec->cur_adc = spec->adc_nid[spec->cur_input];
> + cs_update_input_select(codec);
> + }
> }
> }
>
> @@ -1567,7 +1571,7 @@ static const struct snd_kcontrol_new cs421x_speaker_bost_ctl = {
> .tlv = { .p = cs421x_speaker_boost_db_scale },
> };
>
> -static void cs421x_pinmux_init(struct hda_codec *codec)
> +static void cs4210_pinmux_init(struct hda_codec *codec)
> {
> struct cs_spec *spec = codec->spec;
> unsigned int def_conf, coef;
> @@ -1622,10 +1626,11 @@ static int cs421x_init(struct hda_codec *codec)
> {
> struct cs_spec *spec = codec->spec;
>
> - snd_hda_sequence_write(codec, cs421x_coef_init_verbs);
> - snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes);
> -
> - cs421x_pinmux_init(codec);
> + if (spec->vendor_nid == CS4210_VENDOR_NID) {
> + snd_hda_sequence_write(codec, cs421x_coef_init_verbs);
> + snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes);
> + cs4210_pinmux_init(codec);
> + }
>
> if (spec->gpio_mask) {
> snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
> @@ -1793,7 +1798,7 @@ static int build_cs421x_output(struct hda_codec *codec)
> if (err < 0)
> return err;
>
> - if (cfg->speaker_outs) {
> + if (cfg->speaker_outs && (spec->vendor_nid == CS4210_VENDOR_NID)) {
> err = snd_hda_ctl_add(codec, 0,
> snd_ctl_new1(&cs421x_speaker_bost_ctl, codec));
> if (err < 0)
> @@ -1890,6 +1895,7 @@ static int cs421x_parse_auto_config(struct hda_codec *codec)
> */
> static int cs421x_suspend(struct hda_codec *codec, pm_message_t state)
> {
> + struct cs_spec *spec = codec->spec;
> unsigned int coef;
>
> snd_hda_shutup_pins(codec);
> @@ -1899,15 +1905,17 @@ static int cs421x_suspend(struct hda_codec *codec, pm_message_t state)
> snd_hda_codec_write(codec, CS4210_ADC_NID, 0,
> AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
>
> - coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
> - coef |= 0x0004; /* PDREF */
> - cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
> + if (spec->vendor_nid == CS4210_VENDOR_NID) {
> + coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
> + coef |= 0x0004; /* PDREF */
> + cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
> + }
>
> return 0;
> }
> #endif
>
> -static struct hda_codec_ops cs4210_patch_ops = {
> +static struct hda_codec_ops cs421x_patch_ops = {
> .build_controls = cs421x_build_controls,
> .build_pcms = cs_build_pcms,
> .init = cs421x_init,
> @@ -1918,7 +1926,7 @@ static struct hda_codec_ops cs4210_patch_ops = {
> #endif
> };
>
> -static int patch_cs421x(struct hda_codec *codec)
> +static int patch_cs4210(struct hda_codec *codec)
> {
> struct cs_spec *spec;
> int err;
> @@ -1928,7 +1936,7 @@ static int patch_cs421x(struct hda_codec *codec)
> return -ENOMEM;
> codec->spec = spec;
>
> - spec->vendor_nid = CS421X_VENDOR_NID;
> + spec->vendor_nid = CS4210_VENDOR_NID;
>
> spec->board_config =
> snd_hda_check_board_config(codec, CS421X_MODELS,
> @@ -1956,14 +1964,39 @@ static int patch_cs421x(struct hda_codec *codec)
> is auto-parsed. If GPIO or SENSE_B is forced, DMIC input
> is disabled.
> */
> - cs421x_pinmux_init(codec);
> + cs4210_pinmux_init(codec);
>
> err = cs421x_parse_auto_config(codec);
> if (err < 0)
> goto error;
>
> - codec->patch_ops = cs4210_patch_ops;
> + codec->patch_ops = cs421x_patch_ops;
> +
> + return 0;
> +
> + error:
> + kfree(codec->spec);
> + codec->spec = NULL;
> + return err;
> +}
> +
> +static int patch_cs4213(struct hda_codec *codec)
> +{
> + struct cs_spec *spec;
> + int err;
> +
> + spec = kzalloc(sizeof(*spec), GFP_KERNEL);
> + if (!spec)
> + return -ENOMEM;
> + codec->spec = spec;
> +
> + spec->vendor_nid = CS4213_VENDOR_NID;
> +
> + err = cs421x_parse_auto_config(codec);
> + if (err < 0)
> + goto error;
>
> + codec->patch_ops = cs421x_patch_ops;
> return 0;
>
> error:
> @@ -1979,13 +2012,15 @@ static int patch_cs421x(struct hda_codec *codec)
> static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
> { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
> { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
> - { .id = 0x10134210, .name = "CS4210", .patch = patch_cs421x },
> + { .id = 0x10134210, .name = "CS4210", .patch = patch_cs4210 },
> + { .id = 0x10134213, .name = "CS4213", .patch = patch_cs4213 },
> {} /* terminator */
> };
>
> MODULE_ALIAS("snd-hda-codec-id:10134206");
> MODULE_ALIAS("snd-hda-codec-id:10134207");
> MODULE_ALIAS("snd-hda-codec-id:10134210");
> +MODULE_ALIAS("snd-hda-codec-id:10134213");
>
> MODULE_LICENSE("GPL");
> MODULE_DESCRIPTION("Cirrus Logic HD-audio codec");
> --
> 1.7.9.5
>
>
> --
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
>
--
[]'s
Herton
More information about the kernel-team
mailing list