|
@@ -111,6 +111,9 @@ enum {
|
|
|
/* 0x0009 - 0x0014 -> 12 test regs */
|
|
|
/* 0x0015 - visibility reg */
|
|
|
|
|
|
+/* Cirrus Logic CS4208 */
|
|
|
+#define CS4208_VENDOR_NID 0x24
|
|
|
+
|
|
|
/*
|
|
|
* Cirrus Logic CS4210
|
|
|
*
|
|
@@ -223,6 +226,16 @@ static const struct hda_verb cs_coef_init_verbs[] = {
|
|
|
{} /* terminator */
|
|
|
};
|
|
|
|
|
|
+static const struct hda_verb cs4208_coef_init_verbs[] = {
|
|
|
+ {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */
|
|
|
+ {0x24, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */
|
|
|
+ {0x24, AC_VERB_SET_COEF_INDEX, 0x0033},
|
|
|
+ {0x24, AC_VERB_SET_PROC_COEF, 0x0001}, /* A1 ICS */
|
|
|
+ {0x24, AC_VERB_SET_COEF_INDEX, 0x0034},
|
|
|
+ {0x24, AC_VERB_SET_PROC_COEF, 0x1C01}, /* A1 Enable, A Thresh = 300mV */
|
|
|
+ {} /* terminator */
|
|
|
+};
|
|
|
+
|
|
|
/* Errata: CS4207 rev C0/C1/C2 Silicon
|
|
|
*
|
|
|
* http://www.cirrus.com/en/pubs/errata/ER880C3.pdf
|
|
@@ -295,6 +308,8 @@ static int cs_init(struct hda_codec *codec)
|
|
|
/* init_verb sequence for C0/C1/C2 errata*/
|
|
|
snd_hda_sequence_write(codec, cs_errata_init_verbs);
|
|
|
snd_hda_sequence_write(codec, cs_coef_init_verbs);
|
|
|
+ } else if (spec->vendor_nid == CS4208_VENDOR_NID) {
|
|
|
+ snd_hda_sequence_write(codec, cs4208_coef_init_verbs);
|
|
|
}
|
|
|
|
|
|
snd_hda_gen_init(codec);
|
|
@@ -434,6 +449,29 @@ static const struct hda_pintbl mba42_pincfgs[] = {
|
|
|
{} /* terminator */
|
|
|
};
|
|
|
|
|
|
+static const struct hda_pintbl mba6_pincfgs[] = {
|
|
|
+ { 0x10, 0x032120f0 }, /* HP */
|
|
|
+ { 0x11, 0x500000f0 },
|
|
|
+ { 0x12, 0x90100010 }, /* Speaker */
|
|
|
+ { 0x13, 0x500000f0 },
|
|
|
+ { 0x14, 0x500000f0 },
|
|
|
+ { 0x15, 0x770000f0 },
|
|
|
+ { 0x16, 0x770000f0 },
|
|
|
+ { 0x17, 0x430000f0 },
|
|
|
+ { 0x18, 0x43ab9030 }, /* Mic */
|
|
|
+ { 0x19, 0x770000f0 },
|
|
|
+ { 0x1a, 0x770000f0 },
|
|
|
+ { 0x1b, 0x770000f0 },
|
|
|
+ { 0x1c, 0x90a00090 },
|
|
|
+ { 0x1d, 0x500000f0 },
|
|
|
+ { 0x1e, 0x500000f0 },
|
|
|
+ { 0x1f, 0x500000f0 },
|
|
|
+ { 0x20, 0x500000f0 },
|
|
|
+ { 0x21, 0x430000f0 },
|
|
|
+ { 0x22, 0x430000f0 },
|
|
|
+ {} /* terminator */
|
|
|
+};
|
|
|
+
|
|
|
static void cs420x_fixup_gpio_13(struct hda_codec *codec,
|
|
|
const struct hda_fixup *fix, int action)
|
|
|
{
|
|
@@ -556,22 +594,23 @@ static int patch_cs420x(struct hda_codec *codec)
|
|
|
|
|
|
/*
|
|
|
* CS4208 support:
|
|
|
- * Its layout is no longer compatible with CS4206/CS4207, and the generic
|
|
|
- * parser seems working fairly well, except for trivial fixups.
|
|
|
+ * Its layout is no longer compatible with CS4206/CS4207
|
|
|
*/
|
|
|
enum {
|
|
|
+ CS4208_MBA6,
|
|
|
CS4208_GPIO0,
|
|
|
};
|
|
|
|
|
|
static const struct hda_model_fixup cs4208_models[] = {
|
|
|
{ .id = CS4208_GPIO0, .name = "gpio0" },
|
|
|
+ { .id = CS4208_MBA6, .name = "mba6" },
|
|
|
{}
|
|
|
};
|
|
|
|
|
|
static const struct snd_pci_quirk cs4208_fixup_tbl[] = {
|
|
|
/* codec SSID */
|
|
|
- SND_PCI_QUIRK(0x106b, 0x7100, "MacBookPro 6,1", CS4208_GPIO0),
|
|
|
- SND_PCI_QUIRK(0x106b, 0x7200, "MacBookPro 6,2", CS4208_GPIO0),
|
|
|
+ SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6),
|
|
|
+ SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6),
|
|
|
{} /* terminator */
|
|
|
};
|
|
|
|
|
@@ -588,18 +627,35 @@ static void cs4208_fixup_gpio0(struct hda_codec *codec,
|
|
|
}
|
|
|
|
|
|
static const struct hda_fixup cs4208_fixups[] = {
|
|
|
+ [CS4208_MBA6] = {
|
|
|
+ .type = HDA_FIXUP_PINS,
|
|
|
+ .v.pins = mba6_pincfgs,
|
|
|
+ .chained = true,
|
|
|
+ .chain_id = CS4208_GPIO0,
|
|
|
+ },
|
|
|
[CS4208_GPIO0] = {
|
|
|
.type = HDA_FIXUP_FUNC,
|
|
|
.v.func = cs4208_fixup_gpio0,
|
|
|
},
|
|
|
};
|
|
|
|
|
|
+/* correct the 0dB offset of input pins */
|
|
|
+static void cs4208_fix_amp_caps(struct hda_codec *codec, hda_nid_t adc)
|
|
|
+{
|
|
|
+ unsigned int caps;
|
|
|
+
|
|
|
+ caps = query_amp_caps(codec, adc, HDA_INPUT);
|
|
|
+ caps &= ~(AC_AMPCAP_OFFSET);
|
|
|
+ caps |= 0x02;
|
|
|
+ snd_hda_override_amp_caps(codec, adc, HDA_INPUT, caps);
|
|
|
+}
|
|
|
+
|
|
|
static int patch_cs4208(struct hda_codec *codec)
|
|
|
{
|
|
|
struct cs_spec *spec;
|
|
|
int err;
|
|
|
|
|
|
- spec = cs_alloc_spec(codec, 0); /* no specific w/a */
|
|
|
+ spec = cs_alloc_spec(codec, CS4208_VENDOR_NID);
|
|
|
if (!spec)
|
|
|
return -ENOMEM;
|
|
|
|
|
@@ -609,6 +665,12 @@ static int patch_cs4208(struct hda_codec *codec)
|
|
|
cs4208_fixups);
|
|
|
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
|
|
|
|
|
|
+ snd_hda_override_wcaps(codec, 0x18,
|
|
|
+ get_wcaps(codec, 0x18) | AC_WCAP_STEREO);
|
|
|
+ cs4208_fix_amp_caps(codec, 0x18);
|
|
|
+ cs4208_fix_amp_caps(codec, 0x1b);
|
|
|
+ cs4208_fix_amp_caps(codec, 0x1c);
|
|
|
+
|
|
|
err = cs_parse_auto_config(codec);
|
|
|
if (err < 0)
|
|
|
goto error;
|