aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarkko Nikula <jarkko.nikula@linux.intel.com>2014-09-29 09:58:16 -0400
committerMark Brown <broonie@kernel.org>2014-09-29 14:44:31 -0400
commitf8a770c2c67f28956f8f4601feb99e9bd02a16c8 (patch)
tree6831d88a9029b4d4f02bddc26520cc41342679af
parentac06dd8df6e13591524f0e1bedf36af4ca0e967b (diff)
ASoC: Intel: byt-rt5640: Add quirk for Asus T100
Asus T100 internal microphone is not digital but analogue connected to IN1P pin of the RT564x codec with shared bias between internal and headset microphones. Because of this there is need to have machine specific DAPM routes in byt-rt5640. Add handling for them with the help of DMI quirk that is used to add custom routes in addition to common. Because "Internal Mic" connected to DMIC1 is not common to all move it as a default custom route when there is no match in quirk table. Custom "Internal Mic" -> "IN1P" with MICBIAS1 route is added for Asus T100. Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/intel/byt-rt5640.c53
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[] = {
36static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { 37static 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
48static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
49 {"DMIC1", NULL, "Internal Mic"},
50};
51
52static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
53 {"Internal Mic", NULL, "MICBIAS1"},
54 {"IN1P", NULL, "Internal Mic"},
55};
56
57enum {
58 BYT_RT5640_DMIC1_MAP,
59 BYT_RT5640_IN1_MAP,
60};
61
62static unsigned long byt_rt5640_custom_map = BYT_RT5640_DMIC1_MAP;
63
48static const struct snd_kcontrol_new byt_rt5640_controls[] = { 64static 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
95static 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
101static 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
79static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) 113static 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