blob: fe8a7461ace5f2bf82e73e4e27235bbab01af5f7 [file] [log] [blame]
Shunli Wang11c02692019-03-29 16:34:46 +08001// SPDX-License-Identifier: GPL-2.0
2//
3// mt8183-mt6358.c --
4// MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver
5//
6// Copyright (c) 2018 MediaTek Inc.
7// Author: Shunli Wang <shunli.wang@mediatek.com>
8
9#include <linux/module.h>
10#include <sound/pcm_params.h>
11#include <sound/soc.h>
12#include <sound/jack.h>
13#include <linux/pinctrl/consumer.h>
14
15#include "mt8183-afe-common.h"
16#include "../../codecs/ts3a227e.h"
17
18static struct snd_soc_jack headset_jack;
19
Shunli Wang11c02692019-03-29 16:34:46 +080020static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
21 struct snd_pcm_hw_params *params)
22{
23 struct snd_soc_pcm_runtime *rtd = substream->private_data;
24 unsigned int rate = params_rate(params);
25 unsigned int mclk_fs_ratio = 128;
26 unsigned int mclk_fs = rate * mclk_fs_ratio;
27
28 return snd_soc_dai_set_sysclk(rtd->cpu_dai,
29 0, mclk_fs, SND_SOC_CLOCK_OUT);
30}
31
32static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {
33 .hw_params = mt8183_mt6358_i2s_hw_params,
34};
35
36static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
37 struct snd_pcm_hw_params *params)
38{
39 dev_dbg(rtd->dev, "%s(), fix format to 32bit\n", __func__);
40
41 /* fix BE i2s format to 32bit, clean param mask first */
42 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
43 0, SNDRV_PCM_FORMAT_LAST);
44
45 params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
46 return 0;
47}
48
Jiaxin Yu6191cbd2019-08-22 20:51:00 +080049static const struct snd_soc_dapm_widget
50mt8183_mt6358_ts3a227_max98357_dapm_widgets[] = {
51 SND_SOC_DAPM_OUTPUT("IT6505_8CH"),
52};
53
54static const struct snd_soc_dapm_route
55mt8183_mt6358_ts3a227_max98357_dapm_routes[] = {
56 {"IT6505_8CH", NULL, "TDM"},
57};
58
59enum PINCTRL_PIN_STATE {
60 PIN_STATE_DEFAULT = 0,
61 PIN_TDM_OUT_ON,
62 PIN_TDM_OUT_OFF,
63 PIN_STATE_MAX
64};
65
66static const char * const mt8183_pin_str[PIN_STATE_MAX] = {
67 "default", "aud_tdm_out_on", "aud_tdm_out_off",
68};
69
70struct mt8183_mt6358_ts3a227_max98357_priv {
71 struct pinctrl *pinctrl;
72 struct pinctrl_state *pin_states[PIN_STATE_MAX];
73};
74
Tzung-Bi Shih1df1e542019-04-08 18:47:28 +080075static int
76mt8183_mt6358_ts3a227_max98357_bt_sco_startup(
77 struct snd_pcm_substream *substream)
78{
79 static const unsigned int rates[] = {
80 8000, 16000
81 };
82 static const struct snd_pcm_hw_constraint_list constraints_rates = {
83 .count = ARRAY_SIZE(rates),
84 .list = rates,
85 .mask = 0,
86 };
87 static const unsigned int channels[] = {
88 1,
89 };
90 static const struct snd_pcm_hw_constraint_list constraints_channels = {
91 .count = ARRAY_SIZE(channels),
92 .list = channels,
93 .mask = 0,
94 };
95
96 struct snd_pcm_runtime *runtime = substream->runtime;
97
98 snd_pcm_hw_constraint_list(runtime, 0,
99 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
100 runtime->hw.channels_max = 1;
101 snd_pcm_hw_constraint_list(runtime, 0,
102 SNDRV_PCM_HW_PARAM_CHANNELS,
103 &constraints_channels);
104
105 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
106 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
107
108 return 0;
109}
110
111static const struct snd_soc_ops mt8183_mt6358_ts3a227_max98357_bt_sco_ops = {
112 .startup = mt8183_mt6358_ts3a227_max98357_bt_sco_startup,
113};
114
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900115/* FE */
116SND_SOC_DAILINK_DEFS(playback1,
117 DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
118 DAILINK_COMP_ARRAY(COMP_DUMMY()),
119 DAILINK_COMP_ARRAY(COMP_EMPTY()));
120
121SND_SOC_DAILINK_DEFS(playback2,
122 DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
123 DAILINK_COMP_ARRAY(COMP_DUMMY()),
124 DAILINK_COMP_ARRAY(COMP_EMPTY()));
125
126SND_SOC_DAILINK_DEFS(playback3,
127 DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
128 DAILINK_COMP_ARRAY(COMP_DUMMY()),
129 DAILINK_COMP_ARRAY(COMP_EMPTY()));
130
131SND_SOC_DAILINK_DEFS(capture1,
132 DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
133 DAILINK_COMP_ARRAY(COMP_DUMMY()),
134 DAILINK_COMP_ARRAY(COMP_EMPTY()));
135
136SND_SOC_DAILINK_DEFS(capture2,
137 DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
138 DAILINK_COMP_ARRAY(COMP_DUMMY()),
139 DAILINK_COMP_ARRAY(COMP_EMPTY()));
140
141SND_SOC_DAILINK_DEFS(capture3,
142 DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
143 DAILINK_COMP_ARRAY(COMP_DUMMY()),
144 DAILINK_COMP_ARRAY(COMP_EMPTY()));
145
146SND_SOC_DAILINK_DEFS(capture_mono,
147 DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),
148 DAILINK_COMP_ARRAY(COMP_DUMMY()),
149 DAILINK_COMP_ARRAY(COMP_EMPTY()));
150
151SND_SOC_DAILINK_DEFS(playback_hdmi,
152 DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
153 DAILINK_COMP_ARRAY(COMP_DUMMY()),
154 DAILINK_COMP_ARRAY(COMP_EMPTY()));
155
156/* BE */
157SND_SOC_DAILINK_DEFS(primary_codec,
158 DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
159 DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),
160 DAILINK_COMP_ARRAY(COMP_EMPTY()));
161
162SND_SOC_DAILINK_DEFS(pcm1,
163 DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
164 DAILINK_COMP_ARRAY(COMP_DUMMY()),
165 DAILINK_COMP_ARRAY(COMP_EMPTY()));
166
167SND_SOC_DAILINK_DEFS(pcm2,
168 DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),
169 DAILINK_COMP_ARRAY(COMP_DUMMY()),
170 DAILINK_COMP_ARRAY(COMP_EMPTY()));
171
172SND_SOC_DAILINK_DEFS(i2s0,
173 DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
174 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
175 DAILINK_COMP_ARRAY(COMP_EMPTY()));
176
177SND_SOC_DAILINK_DEFS(i2s1,
178 DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
179 DAILINK_COMP_ARRAY(COMP_DUMMY()),
180 DAILINK_COMP_ARRAY(COMP_EMPTY()));
181
182SND_SOC_DAILINK_DEFS(i2s2,
183 DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
184 DAILINK_COMP_ARRAY(COMP_DUMMY()),
185 DAILINK_COMP_ARRAY(COMP_EMPTY()));
186
187SND_SOC_DAILINK_DEFS(i2s3,
188 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
189 DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi")),
190 DAILINK_COMP_ARRAY(COMP_EMPTY()));
191
192SND_SOC_DAILINK_DEFS(i2s5,
193 DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),
194 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
195 DAILINK_COMP_ARRAY(COMP_EMPTY()));
196
197SND_SOC_DAILINK_DEFS(tdm,
198 DAILINK_COMP_ARRAY(COMP_CPU("TDM")),
199 DAILINK_COMP_ARRAY(COMP_DUMMY()),
200 DAILINK_COMP_ARRAY(COMP_EMPTY()));
201
Jiaxin Yu6191cbd2019-08-22 20:51:00 +0800202static int mt8183_mt6358_tdm_startup(struct snd_pcm_substream *substream)
203{
204 struct snd_soc_pcm_runtime *rtd = substream->private_data;
205 struct mt8183_mt6358_ts3a227_max98357_priv *priv =
206 snd_soc_card_get_drvdata(rtd->card);
207 int ret;
208
209 if (IS_ERR(priv->pin_states[PIN_TDM_OUT_ON]))
210 return PTR_ERR(priv->pin_states[PIN_TDM_OUT_ON]);
211
212 ret = pinctrl_select_state(priv->pinctrl,
213 priv->pin_states[PIN_TDM_OUT_ON]);
214 if (ret)
215 dev_err(rtd->card->dev, "%s failed to select state %d\n",
216 __func__, ret);
217
218 return ret;
219}
220
221static void mt8183_mt6358_tdm_shutdown(struct snd_pcm_substream *substream)
222{
223 struct snd_soc_pcm_runtime *rtd = substream->private_data;
224 struct mt8183_mt6358_ts3a227_max98357_priv *priv =
225 snd_soc_card_get_drvdata(rtd->card);
226 int ret;
227
228 if (IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF]))
229 return;
230
231 ret = pinctrl_select_state(priv->pinctrl,
232 priv->pin_states[PIN_TDM_OUT_OFF]);
233 if (ret)
234 dev_err(rtd->card->dev, "%s failed to select state %d\n",
235 __func__, ret);
236}
237
238static struct snd_soc_ops mt8183_mt6358_tdm_ops = {
239 .startup = mt8183_mt6358_tdm_startup,
240 .shutdown = mt8183_mt6358_tdm_shutdown,
241};
242
Shunli Wang11c02692019-03-29 16:34:46 +0800243static struct snd_soc_dai_link
244mt8183_mt6358_ts3a227_max98357_dai_links[] = {
245 /* FE */
246 {
247 .name = "Playback_1",
248 .stream_name = "Playback_1",
Shunli Wang11c02692019-03-29 16:34:46 +0800249 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
250 SND_SOC_DPCM_TRIGGER_PRE},
251 .dynamic = 1,
252 .dpcm_playback = 1,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900253 SND_SOC_DAILINK_REG(playback1),
Shunli Wang11c02692019-03-29 16:34:46 +0800254 },
255 {
256 .name = "Playback_2",
257 .stream_name = "Playback_2",
Shunli Wang11c02692019-03-29 16:34:46 +0800258 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
259 SND_SOC_DPCM_TRIGGER_PRE},
260 .dynamic = 1,
261 .dpcm_playback = 1,
Tzung-Bi Shih1df1e542019-04-08 18:47:28 +0800262 .ops = &mt8183_mt6358_ts3a227_max98357_bt_sco_ops,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900263 SND_SOC_DAILINK_REG(playback2),
Shunli Wang11c02692019-03-29 16:34:46 +0800264 },
265 {
266 .name = "Playback_3",
267 .stream_name = "Playback_3",
Shunli Wang11c02692019-03-29 16:34:46 +0800268 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
269 SND_SOC_DPCM_TRIGGER_PRE},
270 .dynamic = 1,
271 .dpcm_playback = 1,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900272 SND_SOC_DAILINK_REG(playback3),
Shunli Wang11c02692019-03-29 16:34:46 +0800273 },
274 {
275 .name = "Capture_1",
276 .stream_name = "Capture_1",
Shunli Wang11c02692019-03-29 16:34:46 +0800277 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
278 SND_SOC_DPCM_TRIGGER_PRE},
279 .dynamic = 1,
280 .dpcm_capture = 1,
Tzung-Bi Shih1df1e542019-04-08 18:47:28 +0800281 .ops = &mt8183_mt6358_ts3a227_max98357_bt_sco_ops,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900282 SND_SOC_DAILINK_REG(capture1),
Shunli Wang11c02692019-03-29 16:34:46 +0800283 },
284 {
285 .name = "Capture_2",
286 .stream_name = "Capture_2",
Shunli Wang11c02692019-03-29 16:34:46 +0800287 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
288 SND_SOC_DPCM_TRIGGER_PRE},
289 .dynamic = 1,
290 .dpcm_capture = 1,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900291 SND_SOC_DAILINK_REG(capture2),
Shunli Wang11c02692019-03-29 16:34:46 +0800292 },
293 {
294 .name = "Capture_3",
295 .stream_name = "Capture_3",
Shunli Wang11c02692019-03-29 16:34:46 +0800296 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
297 SND_SOC_DPCM_TRIGGER_PRE},
298 .dynamic = 1,
299 .dpcm_capture = 1,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900300 SND_SOC_DAILINK_REG(capture3),
Shunli Wang11c02692019-03-29 16:34:46 +0800301 },
302 {
303 .name = "Capture_Mono_1",
304 .stream_name = "Capture_Mono_1",
Shunli Wang11c02692019-03-29 16:34:46 +0800305 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
306 SND_SOC_DPCM_TRIGGER_PRE},
307 .dynamic = 1,
308 .dpcm_capture = 1,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900309 SND_SOC_DAILINK_REG(capture_mono),
Shunli Wang11c02692019-03-29 16:34:46 +0800310 },
311 {
312 .name = "Playback_HDMI",
313 .stream_name = "Playback_HDMI",
Shunli Wang11c02692019-03-29 16:34:46 +0800314 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
315 SND_SOC_DPCM_TRIGGER_PRE},
316 .dynamic = 1,
317 .dpcm_playback = 1,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900318 SND_SOC_DAILINK_REG(playback_hdmi),
Shunli Wang11c02692019-03-29 16:34:46 +0800319 },
320 /* BE */
321 {
322 .name = "Primary Codec",
Shunli Wang11c02692019-03-29 16:34:46 +0800323 .no_pcm = 1,
324 .dpcm_playback = 1,
325 .dpcm_capture = 1,
326 .ignore_suspend = 1,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900327 SND_SOC_DAILINK_REG(primary_codec),
Shunli Wang11c02692019-03-29 16:34:46 +0800328 },
329 {
330 .name = "PCM 1",
Shunli Wang11c02692019-03-29 16:34:46 +0800331 .no_pcm = 1,
332 .dpcm_playback = 1,
333 .dpcm_capture = 1,
334 .ignore_suspend = 1,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900335 SND_SOC_DAILINK_REG(pcm1),
Shunli Wang11c02692019-03-29 16:34:46 +0800336 },
337 {
338 .name = "PCM 2",
Shunli Wang11c02692019-03-29 16:34:46 +0800339 .no_pcm = 1,
340 .dpcm_playback = 1,
341 .dpcm_capture = 1,
342 .ignore_suspend = 1,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900343 SND_SOC_DAILINK_REG(pcm2),
Shunli Wang11c02692019-03-29 16:34:46 +0800344 },
345 {
346 .name = "I2S0",
Shunli Wang11c02692019-03-29 16:34:46 +0800347 .no_pcm = 1,
348 .dpcm_capture = 1,
349 .ignore_suspend = 1,
350 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
351 .ops = &mt8183_mt6358_i2s_ops,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900352 SND_SOC_DAILINK_REG(i2s0),
Shunli Wang11c02692019-03-29 16:34:46 +0800353 },
354 {
355 .name = "I2S1",
Shunli Wang11c02692019-03-29 16:34:46 +0800356 .no_pcm = 1,
357 .dpcm_playback = 1,
358 .ignore_suspend = 1,
359 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
360 .ops = &mt8183_mt6358_i2s_ops,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900361 SND_SOC_DAILINK_REG(i2s1),
Shunli Wang11c02692019-03-29 16:34:46 +0800362 },
363 {
364 .name = "I2S2",
Shunli Wang11c02692019-03-29 16:34:46 +0800365 .no_pcm = 1,
366 .dpcm_capture = 1,
367 .ignore_suspend = 1,
368 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
369 .ops = &mt8183_mt6358_i2s_ops,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900370 SND_SOC_DAILINK_REG(i2s2),
Shunli Wang11c02692019-03-29 16:34:46 +0800371 },
372 {
373 .name = "I2S3",
Shunli Wang11c02692019-03-29 16:34:46 +0800374 .no_pcm = 1,
375 .dpcm_playback = 1,
376 .ignore_suspend = 1,
377 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
378 .ops = &mt8183_mt6358_i2s_ops,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900379 SND_SOC_DAILINK_REG(i2s3),
Shunli Wang11c02692019-03-29 16:34:46 +0800380 },
381 {
382 .name = "I2S5",
Shunli Wang11c02692019-03-29 16:34:46 +0800383 .no_pcm = 1,
384 .dpcm_playback = 1,
385 .ignore_suspend = 1,
386 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
387 .ops = &mt8183_mt6358_i2s_ops,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900388 SND_SOC_DAILINK_REG(i2s5),
Shunli Wang11c02692019-03-29 16:34:46 +0800389 },
390 {
391 .name = "TDM",
Shunli Wang11c02692019-03-29 16:34:46 +0800392 .no_pcm = 1,
393 .dpcm_playback = 1,
394 .ignore_suspend = 1,
Jiaxin Yu6191cbd2019-08-22 20:51:00 +0800395 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
396 .ops = &mt8183_mt6358_tdm_ops,
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900397 SND_SOC_DAILINK_REG(tdm),
Shunli Wang11c02692019-03-29 16:34:46 +0800398 },
399};
400
401static int
402mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *cpnt);
403
404static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = {
Kuninori Morimotob812cd52019-08-08 14:53:52 +0900405 .dlc = COMP_EMPTY(),
Shunli Wang11c02692019-03-29 16:34:46 +0800406 .init = mt8183_mt6358_ts3a227_max98357_headset_init,
407};
408
409static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = {
410 .name = "mt8183_mt6358_ts3a227_max98357",
411 .owner = THIS_MODULE,
412 .dai_link = mt8183_mt6358_ts3a227_max98357_dai_links,
413 .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dai_links),
Shunli Wang11c02692019-03-29 16:34:46 +0800414};
415
416static int
417mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component)
418{
419 int ret;
420
421 /* Enable Headset and 4 Buttons Jack detection */
422 ret = snd_soc_card_jack_new(&mt8183_mt6358_ts3a227_max98357_card,
423 "Headset Jack",
424 SND_JACK_HEADSET |
425 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
426 SND_JACK_BTN_2 | SND_JACK_BTN_3,
427 &headset_jack,
Tzung-Bi Shih108d0d42019-05-22 22:55:05 +0800428 NULL, 0);
Shunli Wang11c02692019-03-29 16:34:46 +0800429 if (ret)
430 return ret;
431
432 ret = ts3a227e_enable_jack_detect(component, &headset_jack);
433
434 return ret;
435}
436
437static int
438mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
439{
440 struct snd_soc_card *card = &mt8183_mt6358_ts3a227_max98357_card;
441 struct device_node *platform_node;
442 struct snd_soc_dai_link *dai_link;
Jiaxin Yu6191cbd2019-08-22 20:51:00 +0800443 struct mt8183_mt6358_ts3a227_max98357_priv *priv;
444 int ret;
Tzung-Bi Shih63ba8e42019-05-22 22:54:02 +0800445 int i;
Shunli Wang11c02692019-03-29 16:34:46 +0800446
447 card->dev = &pdev->dev;
448
449 platform_node = of_parse_phandle(pdev->dev.of_node,
450 "mediatek,platform", 0);
451 if (!platform_node) {
452 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
453 return -EINVAL;
454 }
455
456 for_each_card_prelinks(card, i, dai_link) {
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900457 if (dai_link->platforms->name)
Shunli Wang11c02692019-03-29 16:34:46 +0800458 continue;
Kuninori Morimotofa284fd2019-06-06 13:08:49 +0900459 dai_link->platforms->of_node = platform_node;
Shunli Wang11c02692019-03-29 16:34:46 +0800460 }
461
Kuninori Morimotob812cd52019-08-08 14:53:52 +0900462 mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node =
Shunli Wang11c02692019-03-29 16:34:46 +0800463 of_parse_phandle(pdev->dev.of_node,
464 "mediatek,headset-codec", 0);
Kuninori Morimotob812cd52019-08-08 14:53:52 +0900465 if (mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node) {
Tzung-Bi Shiha962a8092019-07-16 11:24:17 +0800466 card->aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev;
467 card->num_aux_devs = 1;
Shunli Wang11c02692019-03-29 16:34:46 +0800468 }
469
Jiaxin Yu6191cbd2019-08-22 20:51:00 +0800470 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
471 if (!priv)
472 return -ENOMEM;
473
474 snd_soc_card_set_drvdata(card, priv);
475
476 priv->pinctrl = devm_pinctrl_get(&pdev->dev);
477 if (IS_ERR(priv->pinctrl)) {
478 dev_err(&pdev->dev, "%s devm_pinctrl_get failed\n",
Shunli Wang11c02692019-03-29 16:34:46 +0800479 __func__);
Jiaxin Yu6191cbd2019-08-22 20:51:00 +0800480 return PTR_ERR(priv->pinctrl);
481 }
482
483 for (i = 0 ; i < PIN_STATE_MAX ; i++) {
484 priv->pin_states[i] = pinctrl_lookup_state(priv->pinctrl,
485 mt8183_pin_str[i]);
486 if (IS_ERR(priv->pin_states[i])) {
487 ret = PTR_ERR(priv->pin_states[i]);
488 dev_info(&pdev->dev, "%s Can't find pin state %s %d\n",
489 __func__, mt8183_pin_str[i], ret);
490 }
491 }
492
493 if (!IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF])) {
494 ret = pinctrl_select_state(priv->pinctrl,
495 priv->pin_states[PIN_TDM_OUT_OFF]);
496 if (ret)
497 dev_info(&pdev->dev,
498 "%s failed to select state %d\n",
499 __func__, ret);
500 }
501
502 if (!IS_ERR(priv->pin_states[PIN_STATE_DEFAULT])) {
503 ret = pinctrl_select_state(priv->pinctrl,
504 priv->pin_states[PIN_STATE_DEFAULT]);
505 if (ret)
506 dev_info(&pdev->dev,
507 "%s failed to select state %d\n",
508 __func__, ret);
Shunli Wang11c02692019-03-29 16:34:46 +0800509 }
510
Tzung-Bi Shih63ba8e42019-05-22 22:54:02 +0800511 return devm_snd_soc_register_card(&pdev->dev, card);
Shunli Wang11c02692019-03-29 16:34:46 +0800512}
513
514#ifdef CONFIG_OF
515static const struct of_device_id mt8183_mt6358_ts3a227_max98357_dt_match[] = {
516 {.compatible = "mediatek,mt8183_mt6358_ts3a227_max98357",},
517 {}
518};
519#endif
520
521static struct platform_driver mt8183_mt6358_ts3a227_max98357_driver = {
522 .driver = {
523 .name = "mt8183_mt6358_ts3a227_max98357",
Shunli Wang11c02692019-03-29 16:34:46 +0800524#ifdef CONFIG_OF
525 .of_match_table = mt8183_mt6358_ts3a227_max98357_dt_match,
526#endif
527 },
528 .probe = mt8183_mt6358_ts3a227_max98357_dev_probe,
529};
530
531module_platform_driver(mt8183_mt6358_ts3a227_max98357_driver);
532
533/* Module information */
534MODULE_DESCRIPTION("MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver");
535MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
536MODULE_LICENSE("GPL v2");
537MODULE_ALIAS("mt8183_mt6358_ts3a227_max98357 soc card");
538