diff options
-rw-r--r-- | sound/soc/intel/byt-rt5640.c | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/sound/soc/intel/byt-rt5640.c b/sound/soc/intel/byt-rt5640.c index d6d8b19c22dc..c323a101214e 100644 --- a/sound/soc/intel/byt-rt5640.c +++ b/sound/soc/intel/byt-rt5640.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/acpi.h> | 18 | #include <linux/acpi.h> |
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/dmi.h> | ||
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
21 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
22 | #include <sound/pcm_params.h> | 23 | #include <sound/pcm_params.h> |
@@ -36,7 +37,6 @@ static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = { | |||
36 | static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { | 37 | static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { |
37 | {"Headset Mic", NULL, "MICBIAS1"}, | 38 | {"Headset Mic", NULL, "MICBIAS1"}, |
38 | {"IN2P", NULL, "Headset Mic"}, | 39 | {"IN2P", NULL, "Headset Mic"}, |
39 | {"DMIC1", NULL, "Internal Mic"}, | ||
40 | {"Headphone", NULL, "HPOL"}, | 40 | {"Headphone", NULL, "HPOL"}, |
41 | {"Headphone", NULL, "HPOR"}, | 41 | {"Headphone", NULL, "HPOR"}, |
42 | {"Speaker", NULL, "SPOLP"}, | 42 | {"Speaker", NULL, "SPOLP"}, |
@@ -45,6 +45,22 @@ static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { | |||
45 | {"Speaker", NULL, "SPORN"}, | 45 | {"Speaker", NULL, "SPORN"}, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = { | ||
49 | {"DMIC1", NULL, "Internal Mic"}, | ||
50 | }; | ||
51 | |||
52 | static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = { | ||
53 | {"Internal Mic", NULL, "MICBIAS1"}, | ||
54 | {"IN1P", NULL, "Internal Mic"}, | ||
55 | }; | ||
56 | |||
57 | enum { | ||
58 | BYT_RT5640_DMIC1_MAP, | ||
59 | BYT_RT5640_IN1_MAP, | ||
60 | }; | ||
61 | |||
62 | static unsigned long byt_rt5640_custom_map = BYT_RT5640_DMIC1_MAP; | ||
63 | |||
48 | static const struct snd_kcontrol_new byt_rt5640_controls[] = { | 64 | static const struct snd_kcontrol_new byt_rt5640_controls[] = { |
49 | SOC_DAPM_PIN_SWITCH("Headphone"), | 65 | SOC_DAPM_PIN_SWITCH("Headphone"), |
50 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | 66 | SOC_DAPM_PIN_SWITCH("Headset Mic"), |
@@ -76,12 +92,32 @@ static int byt_rt5640_hw_params(struct snd_pcm_substream *substream, | |||
76 | return 0; | 92 | return 0; |
77 | } | 93 | } |
78 | 94 | ||
95 | static int byt_rt5640_quirk_cb(const struct dmi_system_id *id) | ||
96 | { | ||
97 | byt_rt5640_custom_map = (unsigned long)id->driver_data; | ||
98 | return 1; | ||
99 | } | ||
100 | |||
101 | static const struct dmi_system_id byt_rt5640_quirk_table[] = { | ||
102 | { | ||
103 | .callback = byt_rt5640_quirk_cb, | ||
104 | .matches = { | ||
105 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
106 | DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"), | ||
107 | }, | ||
108 | .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP, | ||
109 | }, | ||
110 | {} | ||
111 | }; | ||
112 | |||
79 | static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | 113 | static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) |
80 | { | 114 | { |
81 | int ret; | 115 | int ret; |
82 | struct snd_soc_codec *codec = runtime->codec; | 116 | struct snd_soc_codec *codec = runtime->codec; |
83 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 117 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
84 | struct snd_soc_card *card = runtime->card; | 118 | struct snd_soc_card *card = runtime->card; |
119 | const struct snd_soc_dapm_route *custom_map; | ||
120 | int num_routes; | ||
85 | 121 | ||
86 | card->dapm.idle_bias_off = true; | 122 | card->dapm.idle_bias_off = true; |
87 | 123 | ||
@@ -92,6 +128,21 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
92 | return ret; | 128 | return ret; |
93 | } | 129 | } |
94 | 130 | ||
131 | dmi_check_system(byt_rt5640_quirk_table); | ||
132 | switch (byt_rt5640_custom_map) { | ||
133 | case BYT_RT5640_IN1_MAP: | ||
134 | custom_map = byt_rt5640_intmic_in1_map; | ||
135 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map); | ||
136 | break; | ||
137 | default: | ||
138 | custom_map = byt_rt5640_intmic_dmic1_map; | ||
139 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map); | ||
140 | }; | ||
141 | |||
142 | ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); | ||
143 | if (ret) | ||
144 | return ret; | ||
145 | |||
95 | snd_soc_dapm_ignore_suspend(dapm, "HPOL"); | 146 | snd_soc_dapm_ignore_suspend(dapm, "HPOL"); |
96 | snd_soc_dapm_ignore_suspend(dapm, "HPOR"); | 147 | snd_soc_dapm_ignore_suspend(dapm, "HPOR"); |
97 | 148 | ||