*/
 #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 */
 
 
 #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;
        /* 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];
                                    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];
        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) {
                        spec->last_input = spec->cur_input;
                        spec->cur_input = spec->automic_idx;
                        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);
        }
 }
 
                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);
                                         * 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);
+               }
        }
 }
 
        .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;
 {
        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,
        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)
 */
 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);
        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,
 #endif
 };
 
-static int patch_cs421x(struct hda_codec *codec)
+static int patch_cs4210(struct hda_codec *codec)
 {
        struct cs_spec *spec;
        int err;
                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,
            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:
 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");