aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJarkko Nikula <jarkko.nikula@linux.intel.com>2014-05-30 08:16:43 -0400
committerMark Brown <broonie@linaro.org>2014-06-01 06:44:49 -0400
commit9b351d46893e827940e2e8da04f1791e8ec452ca (patch)
tree74e03184c5f2cc211a7343a3d995cc0e6ef845fe /sound
parent35386320898ec01f922929877a723fe1d4ddf04b (diff)
ASoC: Intel: Add Baytrail byt-max98090 machine driver
Add machine driver and ACPI probing for Baytrail SST with MAX98090 codec. Jack detect code from Kevin Strasser <kevin.strasser@intel.com>, GPIO resolving from Mika Westerberg <mika.westerberg@linux.intel.com> and fixes and cleanups from Liam Girdwood <liam.r.girdwood@linux.intel.com>. Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/intel/Kconfig9
-rw-r--r--sound/soc/intel/Makefile2
-rw-r--r--sound/soc/intel/byt-max98090.c203
-rw-r--r--sound/soc/intel/sst-acpi.c1
4 files changed, 215 insertions, 0 deletions
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 3c81b3891209..cd3498736e91 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -49,3 +49,12 @@ config SND_SOC_INTEL_BYT_RT5640_MACH
49 help 49 help
50 This adds audio driver for Intel Baytrail platform based boards 50 This adds audio driver for Intel Baytrail platform based boards
51 with the RT5640 audio codec. 51 with the RT5640 audio codec.
52
53config SND_SOC_INTEL_BYT_MAX98090_MACH
54 tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec"
55 depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS
56 select SND_SOC_INTEL_BAYTRAIL
57 select SND_SOC_MAX98090
58 help
59 This adds audio driver for Intel Baytrail platform based boards
60 with the MAX98090 audio codec.
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile
index 0db4e2f336dc..4bfca79a42ba 100644
--- a/sound/soc/intel/Makefile
+++ b/sound/soc/intel/Makefile
@@ -23,6 +23,8 @@ obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += snd-soc-sst-baytrail-pcm.o
23# Machine support 23# Machine support
24snd-soc-sst-haswell-objs := haswell.o 24snd-soc-sst-haswell-objs := haswell.o
25snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o 25snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
26snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
26 27
27obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o 28obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
28obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o 29obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
30obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
diff --git a/sound/soc/intel/byt-max98090.c b/sound/soc/intel/byt-max98090.c
new file mode 100644
index 000000000000..5fc98c64a3f4
--- /dev/null
+++ b/sound/soc/intel/byt-max98090.c
@@ -0,0 +1,203 @@
1/*
2 * Intel Baytrail SST MAX98090 machine driver
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/acpi.h>
19#include <linux/device.h>
20#include <linux/gpio.h>
21#include <linux/gpio/consumer.h>
22#include <linux/slab.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/jack.h>
27#include "../codecs/max98090.h"
28
29struct byt_max98090_private {
30 struct snd_soc_jack jack;
31};
32
33static const struct snd_soc_dapm_widget byt_max98090_widgets[] = {
34 SND_SOC_DAPM_HP("Headphone", NULL),
35 SND_SOC_DAPM_MIC("Headset Mic", NULL),
36 SND_SOC_DAPM_MIC("Int Mic", NULL),
37 SND_SOC_DAPM_SPK("Ext Spk", NULL),
38};
39
40static const struct snd_soc_dapm_route byt_max98090_audio_map[] = {
41 {"IN34", NULL, "Headset Mic"},
42 {"IN34", NULL, "MICBIAS"},
43 {"MICBIAS", NULL, "Headset Mic"},
44 {"DMICL", NULL, "Int Mic"},
45 {"Headphone", NULL, "HPL"},
46 {"Headphone", NULL, "HPR"},
47 {"Ext Spk", NULL, "SPKL"},
48 {"Ext Spk", NULL, "SPKR"},
49};
50
51static const struct snd_kcontrol_new byt_max98090_controls[] = {
52 SOC_DAPM_PIN_SWITCH("Headphone"),
53 SOC_DAPM_PIN_SWITCH("Headset Mic"),
54 SOC_DAPM_PIN_SWITCH("Int Mic"),
55 SOC_DAPM_PIN_SWITCH("Ext Spk"),
56};
57
58static struct snd_soc_jack_pin hs_jack_pins[] = {
59 {
60 .pin = "Headphone",
61 .mask = SND_JACK_HEADPHONE,
62 },
63 {
64 .pin = "Headset Mic",
65 .mask = SND_JACK_MICROPHONE,
66 },
67 {
68 .pin = "Ext Spk",
69 .mask = SND_JACK_LINEOUT,
70 },
71 {
72 .pin = "Int Mic",
73 .mask = SND_JACK_LINEIN,
74 },
75};
76
77static struct snd_soc_jack_gpio hs_jack_gpios[] = {
78 {
79 .name = "hp-gpio",
80 .idx = 0,
81 .report = SND_JACK_HEADPHONE | SND_JACK_LINEOUT,
82 .debounce_time = 200,
83 },
84 {
85 .name = "mic-gpio",
86 .idx = 1,
87 .report = SND_JACK_MICROPHONE | SND_JACK_LINEIN,
88 .debounce_time = 200,
89 },
90};
91
92static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime)
93{
94 int ret;
95 struct snd_soc_codec *codec = runtime->codec;
96 struct snd_soc_card *card = runtime->card;
97 struct byt_max98090_private *drv = snd_soc_card_get_drvdata(card);
98 struct snd_soc_jack *jack = &drv->jack;
99
100 card->dapm.idle_bias_off = true;
101
102 ret = snd_soc_dai_set_sysclk(runtime->codec_dai,
103 M98090_REG_SYSTEM_CLOCK,
104 25000000, SND_SOC_CLOCK_IN);
105 if (ret < 0) {
106 dev_err(card->dev, "Can't set codec clock %d\n", ret);
107 return ret;
108 }
109
110 /* Enable jack detection */
111 ret = snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, jack);
112 if (ret)
113 return ret;
114
115 ret = snd_soc_jack_add_pins(jack, ARRAY_SIZE(hs_jack_pins),
116 hs_jack_pins);
117 if (ret)
118 return ret;
119
120 ret = snd_soc_jack_add_gpiods(card->dev->parent, jack,
121 ARRAY_SIZE(hs_jack_gpios),
122 hs_jack_gpios);
123 if (ret)
124 return ret;
125
126 return max98090_mic_detect(codec, jack);
127}
128
129static struct snd_soc_dai_link byt_max98090_dais[] = {
130 {
131 .name = "Baytrail Audio",
132 .stream_name = "Audio",
133 .cpu_dai_name = "baytrail-pcm-audio",
134 .codec_dai_name = "HiFi",
135 .codec_name = "i2c-193C9890:00",
136 .platform_name = "baytrail-pcm-audio",
137 .init = byt_max98090_init,
138 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
139 SND_SOC_DAIFMT_CBS_CFS,
140 },
141};
142
143static struct snd_soc_card byt_max98090_card = {
144 .name = "byt-max98090",
145 .dai_link = byt_max98090_dais,
146 .num_links = ARRAY_SIZE(byt_max98090_dais),
147 .dapm_widgets = byt_max98090_widgets,
148 .num_dapm_widgets = ARRAY_SIZE(byt_max98090_widgets),
149 .dapm_routes = byt_max98090_audio_map,
150 .num_dapm_routes = ARRAY_SIZE(byt_max98090_audio_map),
151 .controls = byt_max98090_controls,
152 .num_controls = ARRAY_SIZE(byt_max98090_controls),
153};
154
155static int byt_max98090_probe(struct platform_device *pdev)
156{
157 int ret_val = 0;
158 struct byt_max98090_private *priv;
159
160 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
161 if (!priv) {
162 dev_err(&pdev->dev, "allocation failed\n");
163 return -ENOMEM;
164 }
165
166 byt_max98090_card.dev = &pdev->dev;
167 snd_soc_card_set_drvdata(&byt_max98090_card, priv);
168 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_max98090_card);
169 if (ret_val) {
170 dev_err(&pdev->dev,
171 "snd_soc_register_card failed %d\n", ret_val);
172 return ret_val;
173 }
174
175 return ret_val;
176}
177
178static int byt_max98090_remove(struct platform_device *pdev)
179{
180 struct snd_soc_card *card = platform_get_drvdata(pdev);
181 struct byt_max98090_private *priv = snd_soc_card_get_drvdata(card);
182
183 snd_soc_jack_free_gpios(&priv->jack, ARRAY_SIZE(hs_jack_gpios),
184 hs_jack_gpios);
185
186 return 0;
187}
188
189static struct platform_driver byt_max98090_driver = {
190 .probe = byt_max98090_probe,
191 .remove = byt_max98090_remove,
192 .driver = {
193 .name = "byt-max98090",
194 .owner = THIS_MODULE,
195 .pm = &snd_soc_pm_ops,
196 },
197};
198module_platform_driver(byt_max98090_driver)
199
200MODULE_DESCRIPTION("ASoC Intel(R) Baytrail Machine driver");
201MODULE_AUTHOR("Omair Md Abdullah, Jarkko Nikula");
202MODULE_LICENSE("GPL v2");
203MODULE_ALIAS("platform:byt-max98090");
diff --git a/sound/soc/intel/sst-acpi.c b/sound/soc/intel/sst-acpi.c
index 18aee77f8d4a..42edc6f4fc4a 100644
--- a/sound/soc/intel/sst-acpi.c
+++ b/sound/soc/intel/sst-acpi.c
@@ -247,6 +247,7 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = {
247 247
248static struct sst_acpi_mach baytrail_machines[] = { 248static struct sst_acpi_mach baytrail_machines[] = {
249 { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-i2s_master" }, 249 { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-i2s_master" },
250 { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-i2s_master" },
250 {} 251 {}
251}; 252};
252 253