aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFang, Yang A <yang.a.fang@intel.com>2015-04-23 13:23:02 -0400
committerMark Brown <broonie@kernel.org>2015-05-04 13:13:59 -0400
commitc4ba51ba1c8f8e9dd51f63069eec88580f0e1d01 (patch)
tree6d3db2682fabb1222acb658f642726b978e4a387
parent17119a4657066ccefd9a530ab1b07073d97776f8 (diff)
ASoC: Intel: Support rt5650 codec for Cherrytrail & Braswell
rt5650 and rt5645 are similar codec so reuse the cht_bsw_rt5645 driver Signed-off-by: Fang, Yang A <yang.a.fang@intel.com> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/intel/Kconfig4
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c93
2 files changed, 84 insertions, 13 deletions
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 01b2b53be0b3..4419d760ed68 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -112,14 +112,14 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
112 If unsure select "N". 112 If unsure select "N".
113 113
114config SND_SOC_INTEL_CHT_BSW_RT5645_MACH 114config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
115 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645 codec" 115 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec"
116 depends on X86_INTEL_LPSS 116 depends on X86_INTEL_LPSS
117 select SND_SOC_RT5645 117 select SND_SOC_RT5645
118 select SND_SST_MFLD_PLATFORM 118 select SND_SST_MFLD_PLATFORM
119 select SND_SST_IPC_ACPI 119 select SND_SST_IPC_ACPI
120 help 120 help
121 This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell 121 This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
122 platforms with RT5645 audio codec. 122 platforms with RT5645/5650 audio codec.
123 If unsure select "N". 123 If unsure select "N".
124 124
125config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH 125config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index 20a28b22e30f..7d23ead3fd40 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -21,6 +21,7 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/acpi.h>
24#include <linux/platform_device.h> 25#include <linux/platform_device.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
@@ -33,9 +34,16 @@
33#define CHT_PLAT_CLK_3_HZ 19200000 34#define CHT_PLAT_CLK_3_HZ 19200000
34#define CHT_CODEC_DAI "rt5645-aif1" 35#define CHT_CODEC_DAI "rt5645-aif1"
35 36
37struct cht_acpi_card {
38 char *codec_id;
39 int codec_type;
40 struct snd_soc_card *soc_card;
41};
42
36struct cht_mc_private { 43struct cht_mc_private {
37 struct snd_soc_jack hp_jack; 44 struct snd_soc_jack hp_jack;
38 struct snd_soc_jack mic_jack; 45 struct snd_soc_jack mic_jack;
46 struct cht_acpi_card *acpi_card;
39}; 47};
40 48
41static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) 49static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
@@ -94,7 +102,7 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
94 platform_clock_control, SND_SOC_DAPM_POST_PMD), 102 platform_clock_control, SND_SOC_DAPM_POST_PMD),
95}; 103};
96 104
97static const struct snd_soc_dapm_route cht_audio_map[] = { 105static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = {
98 {"IN1P", NULL, "Headset Mic"}, 106 {"IN1P", NULL, "Headset Mic"},
99 {"IN1N", NULL, "Headset Mic"}, 107 {"IN1N", NULL, "Headset Mic"},
100 {"DMIC L1", NULL, "Int Mic"}, 108 {"DMIC L1", NULL, "Int Mic"},
@@ -115,6 +123,27 @@ static const struct snd_soc_dapm_route cht_audio_map[] = {
115 {"Ext Spk", NULL, "Platform Clock"}, 123 {"Ext Spk", NULL, "Platform Clock"},
116}; 124};
117 125
126static const struct snd_soc_dapm_route cht_rt5650_audio_map[] = {
127 {"IN1P", NULL, "Headset Mic"},
128 {"IN1N", NULL, "Headset Mic"},
129 {"DMIC L2", NULL, "Int Mic"},
130 {"DMIC R2", NULL, "Int Mic"},
131 {"Headphone", NULL, "HPOL"},
132 {"Headphone", NULL, "HPOR"},
133 {"Ext Spk", NULL, "SPOL"},
134 {"Ext Spk", NULL, "SPOR"},
135 {"AIF1 Playback", NULL, "ssp2 Tx"},
136 {"ssp2 Tx", NULL, "codec_out0"},
137 {"ssp2 Tx", NULL, "codec_out1"},
138 {"codec_in0", NULL, "ssp2 Rx" },
139 {"codec_in1", NULL, "ssp2 Rx" },
140 {"ssp2 Rx", NULL, "AIF1 Capture"},
141 {"Headphone", NULL, "Platform Clock"},
142 {"Headset Mic", NULL, "Platform Clock"},
143 {"Int Mic", NULL, "Platform Clock"},
144 {"Ext Spk", NULL, "Platform Clock"},
145};
146
118static const struct snd_kcontrol_new cht_mc_controls[] = { 147static const struct snd_kcontrol_new cht_mc_controls[] = {
119 SOC_DAPM_PIN_SWITCH("Headphone"), 148 SOC_DAPM_PIN_SWITCH("Headphone"),
120 SOC_DAPM_PIN_SWITCH("Headset Mic"), 149 SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -239,7 +268,7 @@ static struct snd_soc_dai_link cht_dailink[] = {
239 .codec_dai_name = "snd-soc-dummy-dai", 268 .codec_dai_name = "snd-soc-dummy-dai",
240 .codec_name = "snd-soc-dummy", 269 .codec_name = "snd-soc-dummy",
241 .platform_name = "sst-mfld-platform", 270 .platform_name = "sst-mfld-platform",
242 .ignore_suspend = 1, 271 .nonatomic = true,
243 .dynamic = 1, 272 .dynamic = 1,
244 .dpcm_playback = 1, 273 .dpcm_playback = 1,
245 .dpcm_capture = 1, 274 .dpcm_capture = 1,
@@ -267,7 +296,7 @@ static struct snd_soc_dai_link cht_dailink[] = {
267 | SND_SOC_DAIFMT_CBS_CFS, 296 | SND_SOC_DAIFMT_CBS_CFS,
268 .init = cht_codec_init, 297 .init = cht_codec_init,
269 .be_hw_params_fixup = cht_codec_fixup, 298 .be_hw_params_fixup = cht_codec_fixup,
270 .ignore_suspend = 1, 299 .nonatomic = true,
271 .dpcm_playback = 1, 300 .dpcm_playback = 1,
272 .dpcm_capture = 1, 301 .dpcm_capture = 1,
273 .ops = &cht_be_ssp2_ops, 302 .ops = &cht_be_ssp2_ops,
@@ -275,43 +304,85 @@ static struct snd_soc_dai_link cht_dailink[] = {
275}; 304};
276 305
277/* SoC card */ 306/* SoC card */
278static struct snd_soc_card snd_soc_card_cht = { 307static struct snd_soc_card snd_soc_card_chtrt5645 = {
279 .name = "chtrt5645", 308 .name = "chtrt5645",
280 .dai_link = cht_dailink, 309 .dai_link = cht_dailink,
281 .num_links = ARRAY_SIZE(cht_dailink), 310 .num_links = ARRAY_SIZE(cht_dailink),
282 .dapm_widgets = cht_dapm_widgets, 311 .dapm_widgets = cht_dapm_widgets,
283 .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets), 312 .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),
284 .dapm_routes = cht_audio_map, 313 .dapm_routes = cht_rt5645_audio_map,
285 .num_dapm_routes = ARRAY_SIZE(cht_audio_map), 314 .num_dapm_routes = ARRAY_SIZE(cht_rt5645_audio_map),
286 .controls = cht_mc_controls, 315 .controls = cht_mc_controls,
287 .num_controls = ARRAY_SIZE(cht_mc_controls), 316 .num_controls = ARRAY_SIZE(cht_mc_controls),
288}; 317};
289 318
319static struct snd_soc_card snd_soc_card_chtrt5650 = {
320 .name = "chtrt5650",
321 .dai_link = cht_dailink,
322 .num_links = ARRAY_SIZE(cht_dailink),
323 .dapm_widgets = cht_dapm_widgets,
324 .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),
325 .dapm_routes = cht_rt5650_audio_map,
326 .num_dapm_routes = ARRAY_SIZE(cht_rt5650_audio_map),
327 .controls = cht_mc_controls,
328 .num_controls = ARRAY_SIZE(cht_mc_controls),
329};
330
331static struct cht_acpi_card snd_soc_cards[] = {
332 {"10EC5645", CODEC_TYPE_RT5645, &snd_soc_card_chtrt5645},
333 {"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650},
334};
335
336static acpi_status snd_acpi_codec_match(acpi_handle handle, u32 level,
337 void *context, void **ret)
338{
339 *(bool *)context = true;
340 return AE_OK;
341}
342
290static int snd_cht_mc_probe(struct platform_device *pdev) 343static int snd_cht_mc_probe(struct platform_device *pdev)
291{ 344{
292 int ret_val = 0; 345 int ret_val = 0;
346 int i;
293 struct cht_mc_private *drv; 347 struct cht_mc_private *drv;
348 struct snd_soc_card *card = snd_soc_cards[0].soc_card;
349 bool found = false;
350 char codec_name[16];
294 351
295 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); 352 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
296 if (!drv) 353 if (!drv)
297 return -ENOMEM; 354 return -ENOMEM;
298 355
299 snd_soc_card_cht.dev = &pdev->dev; 356 for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) {
300 snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); 357 if (ACPI_SUCCESS(acpi_get_devices(
301 ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht); 358 snd_soc_cards[i].codec_id,
359 snd_acpi_codec_match,
360 &found, NULL)) && found) {
361 dev_dbg(&pdev->dev,
362 "found codec %s\n", snd_soc_cards[i].codec_id);
363 card = snd_soc_cards[i].soc_card;
364 drv->acpi_card = &snd_soc_cards[i];
365 break;
366 }
367 }
368 card->dev = &pdev->dev;
369 sprintf(codec_name, "i2c-%s:00", drv->acpi_card->codec_id);
370 /* set correct codec name */
371 strcpy((char *)card->dai_link[2].codec_name, codec_name);
372 snd_soc_card_set_drvdata(card, drv);
373 ret_val = devm_snd_soc_register_card(&pdev->dev, card);
302 if (ret_val) { 374 if (ret_val) {
303 dev_err(&pdev->dev, 375 dev_err(&pdev->dev,
304 "snd_soc_register_card failed %d\n", ret_val); 376 "snd_soc_register_card failed %d\n", ret_val);
305 return ret_val; 377 return ret_val;
306 } 378 }
307 platform_set_drvdata(pdev, &snd_soc_card_cht); 379 platform_set_drvdata(pdev, card);
308 return ret_val; 380 return ret_val;
309} 381}
310 382
311static struct platform_driver snd_cht_mc_driver = { 383static struct platform_driver snd_cht_mc_driver = {
312 .driver = { 384 .driver = {
313 .name = "cht-bsw-rt5645", 385 .name = "cht-bsw-rt5645",
314 .pm = &snd_soc_pm_ops,
315 }, 386 },
316 .probe = snd_cht_mc_probe, 387 .probe = snd_cht_mc_probe,
317}; 388};