.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Rockchip machine ASoC driver for boards using MAX98357A/RT5514/DA7219 |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2016, ROCKCHIP CORPORATION. All rights reserved. |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify it |
---|
7 | | - * under the terms and conditions of the GNU General Public License, |
---|
8 | | - * version 2, as published by the Free Software Foundation. |
---|
9 | | - * |
---|
10 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
13 | | - * more details. |
---|
14 | | - * |
---|
15 | | - * You should have received a copy of the GNU General Public License |
---|
16 | | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
17 | 6 | */ |
---|
18 | 7 | |
---|
19 | 8 | #include <linux/module.h> |
---|
.. | .. |
---|
43 | 32 | |
---|
44 | 33 | static struct snd_soc_jack rockchip_sound_jack; |
---|
45 | 34 | |
---|
| 35 | +/* Headset jack detection DAPM pins */ |
---|
| 36 | +static struct snd_soc_jack_pin rockchip_sound_jack_pins[] = { |
---|
| 37 | + { |
---|
| 38 | + .pin = "Headphones", |
---|
| 39 | + .mask = SND_JACK_HEADPHONE, |
---|
| 40 | + }, |
---|
| 41 | + { |
---|
| 42 | + .pin = "Headset Mic", |
---|
| 43 | + .mask = SND_JACK_MICROPHONE, |
---|
| 44 | + }, |
---|
| 45 | + |
---|
| 46 | +}; |
---|
| 47 | + |
---|
46 | 48 | static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = { |
---|
47 | 49 | SND_SOC_DAPM_HP("Headphones", NULL), |
---|
48 | 50 | SND_SOC_DAPM_SPK("Speakers", NULL), |
---|
.. | .. |
---|
62 | 64 | static int rockchip_sound_max98357a_hw_params(struct snd_pcm_substream *substream, |
---|
63 | 65 | struct snd_pcm_hw_params *params) |
---|
64 | 66 | { |
---|
65 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 67 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
66 | 68 | unsigned int mclk; |
---|
67 | 69 | int ret; |
---|
68 | 70 | |
---|
69 | | - /* max98357a supports these sample rates */ |
---|
70 | | - switch (params_rate(params)) { |
---|
71 | | - case 8000: |
---|
72 | | - case 16000: |
---|
73 | | - case 48000: |
---|
74 | | - case 96000: |
---|
75 | | - mclk = params_rate(params) * SOUND_FS; |
---|
76 | | - break; |
---|
77 | | - default: |
---|
78 | | - dev_err(rtd->card->dev, "%s() doesn't support this sample rate: %d\n", |
---|
79 | | - __func__, params_rate(params)); |
---|
80 | | - return -EINVAL; |
---|
81 | | - } |
---|
| 71 | + mclk = params_rate(params) * SOUND_FS; |
---|
82 | 72 | |
---|
83 | | - ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 0); |
---|
| 73 | + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0); |
---|
84 | 74 | if (ret) { |
---|
85 | 75 | dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n", |
---|
86 | 76 | __func__, mclk, ret); |
---|
.. | .. |
---|
93 | 83 | static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream, |
---|
94 | 84 | struct snd_pcm_hw_params *params) |
---|
95 | 85 | { |
---|
96 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
97 | | - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
---|
98 | | - struct snd_soc_dai *codec_dai = rtd->codec_dai; |
---|
| 86 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
| 87 | + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); |
---|
| 88 | + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); |
---|
99 | 89 | unsigned int mclk; |
---|
100 | 90 | int ret; |
---|
101 | 91 | |
---|
.. | .. |
---|
125 | 115 | static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream, |
---|
126 | 116 | struct snd_pcm_hw_params *params) |
---|
127 | 117 | { |
---|
128 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
129 | | - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
---|
130 | | - struct snd_soc_dai *codec_dai = rtd->codec_dai; |
---|
| 118 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
| 119 | + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); |
---|
| 120 | + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); |
---|
131 | 121 | int mclk, ret; |
---|
132 | 122 | |
---|
133 | 123 | /* in bypass mode, the mclk has to be one of the frequencies below */ |
---|
.. | .. |
---|
176 | 166 | |
---|
177 | 167 | static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd) |
---|
178 | 168 | { |
---|
179 | | - struct snd_soc_component *component = rtd->codec_dais[0]->component; |
---|
180 | | - struct snd_soc_dai *codec_dai = rtd->codec_dai; |
---|
| 169 | + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; |
---|
| 170 | + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); |
---|
181 | 171 | int ret; |
---|
182 | 172 | |
---|
183 | 173 | /* We need default MCLK and PLL settings for the accessory detection */ |
---|
.. | .. |
---|
199 | 189 | SND_JACK_HEADSET | SND_JACK_LINEOUT | |
---|
200 | 190 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | |
---|
201 | 191 | SND_JACK_BTN_2 | SND_JACK_BTN_3, |
---|
202 | | - &rockchip_sound_jack, NULL, 0); |
---|
| 192 | + &rockchip_sound_jack, |
---|
| 193 | + rockchip_sound_jack_pins, |
---|
| 194 | + ARRAY_SIZE(rockchip_sound_jack_pins)); |
---|
203 | 195 | |
---|
204 | 196 | if (ret) { |
---|
205 | 197 | dev_err(rtd->card->dev, "New Headset Jack failed! (%d)\n", ret); |
---|
.. | .. |
---|
223 | 215 | static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream, |
---|
224 | 216 | struct snd_pcm_hw_params *params) |
---|
225 | 217 | { |
---|
226 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 218 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
227 | 219 | unsigned int mclk; |
---|
228 | 220 | int ret; |
---|
229 | 221 | |
---|
230 | 222 | mclk = params_rate(params) * SOUND_FS; |
---|
231 | 223 | |
---|
232 | | - ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 0); |
---|
| 224 | + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0); |
---|
233 | 225 | if (ret) { |
---|
234 | 226 | dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n", |
---|
235 | 227 | __func__, mclk, ret); |
---|
.. | .. |
---|
242 | 234 | return 0; |
---|
243 | 235 | } |
---|
244 | 236 | |
---|
| 237 | +static int rockchip_sound_startup(struct snd_pcm_substream *substream) |
---|
| 238 | +{ |
---|
| 239 | + struct snd_pcm_runtime *runtime = substream->runtime; |
---|
| 240 | + |
---|
| 241 | + runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; |
---|
| 242 | + return snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, |
---|
| 243 | + 8000, 96000); |
---|
| 244 | +} |
---|
| 245 | + |
---|
245 | 246 | static const struct snd_soc_ops rockchip_sound_max98357a_ops = { |
---|
| 247 | + .startup = rockchip_sound_startup, |
---|
246 | 248 | .hw_params = rockchip_sound_max98357a_hw_params, |
---|
247 | 249 | }; |
---|
248 | 250 | |
---|
249 | 251 | static const struct snd_soc_ops rockchip_sound_rt5514_ops = { |
---|
| 252 | + .startup = rockchip_sound_startup, |
---|
250 | 253 | .hw_params = rockchip_sound_rt5514_hw_params, |
---|
251 | 254 | }; |
---|
252 | 255 | |
---|
253 | 256 | static const struct snd_soc_ops rockchip_sound_da7219_ops = { |
---|
| 257 | + .startup = rockchip_sound_startup, |
---|
254 | 258 | .hw_params = rockchip_sound_da7219_hw_params, |
---|
255 | 259 | }; |
---|
256 | 260 | |
---|
257 | 261 | static const struct snd_soc_ops rockchip_sound_dmic_ops = { |
---|
| 262 | + .startup = rockchip_sound_startup, |
---|
258 | 263 | .hw_params = rockchip_sound_dmic_hw_params, |
---|
259 | 264 | }; |
---|
260 | 265 | |
---|
.. | .. |
---|
276 | 281 | DAILINK_RT5514_DSP, |
---|
277 | 282 | }; |
---|
278 | 283 | |
---|
| 284 | +SND_SOC_DAILINK_DEFS(cdndp, |
---|
| 285 | + DAILINK_COMP_ARRAY(COMP_EMPTY()), |
---|
| 286 | + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "spdif-hifi")), |
---|
| 287 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
---|
| 288 | + |
---|
| 289 | +SND_SOC_DAILINK_DEFS(da7219, |
---|
| 290 | + DAILINK_COMP_ARRAY(COMP_EMPTY()), |
---|
| 291 | + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "da7219-hifi")), |
---|
| 292 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
---|
| 293 | + |
---|
| 294 | +SND_SOC_DAILINK_DEFS(dmic, |
---|
| 295 | + DAILINK_COMP_ARRAY(COMP_EMPTY()), |
---|
| 296 | + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "dmic-hifi")), |
---|
| 297 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
---|
| 298 | + |
---|
| 299 | +SND_SOC_DAILINK_DEFS(max98357a, |
---|
| 300 | + DAILINK_COMP_ARRAY(COMP_EMPTY()), |
---|
| 301 | + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "HiFi")), |
---|
| 302 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
---|
| 303 | + |
---|
| 304 | +SND_SOC_DAILINK_DEFS(rt5514, |
---|
| 305 | + DAILINK_COMP_ARRAY(COMP_EMPTY()), |
---|
| 306 | + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "rt5514-aif1")), |
---|
| 307 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
---|
| 308 | + |
---|
| 309 | +SND_SOC_DAILINK_DEFS(rt5514_dsp, |
---|
| 310 | + DAILINK_COMP_ARRAY(COMP_EMPTY()), |
---|
| 311 | + DAILINK_COMP_ARRAY(COMP_DUMMY()), |
---|
| 312 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
---|
| 313 | + |
---|
279 | 314 | static const struct snd_soc_dai_link rockchip_dais[] = { |
---|
280 | 315 | [DAILINK_CDNDP] = { |
---|
281 | 316 | .name = "DP", |
---|
282 | 317 | .stream_name = "DP PCM", |
---|
283 | | - .codec_dai_name = "spdif-hifi", |
---|
284 | 318 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
---|
285 | 319 | SND_SOC_DAIFMT_CBS_CFS, |
---|
| 320 | + SND_SOC_DAILINK_REG(cdndp), |
---|
286 | 321 | }, |
---|
287 | 322 | [DAILINK_DA7219] = { |
---|
288 | 323 | .name = "DA7219", |
---|
289 | 324 | .stream_name = "DA7219 PCM", |
---|
290 | | - .codec_dai_name = "da7219-hifi", |
---|
291 | 325 | .init = rockchip_sound_da7219_init, |
---|
292 | 326 | .ops = &rockchip_sound_da7219_ops, |
---|
293 | 327 | /* set da7219 as slave */ |
---|
294 | 328 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
---|
295 | 329 | SND_SOC_DAIFMT_CBS_CFS, |
---|
| 330 | + SND_SOC_DAILINK_REG(da7219), |
---|
296 | 331 | }, |
---|
297 | 332 | [DAILINK_DMIC] = { |
---|
298 | 333 | .name = "DMIC", |
---|
299 | 334 | .stream_name = "DMIC PCM", |
---|
300 | | - .codec_dai_name = "dmic-hifi", |
---|
301 | 335 | .ops = &rockchip_sound_dmic_ops, |
---|
302 | 336 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
---|
303 | 337 | SND_SOC_DAIFMT_CBS_CFS, |
---|
| 338 | + SND_SOC_DAILINK_REG(dmic), |
---|
304 | 339 | }, |
---|
305 | 340 | [DAILINK_MAX98357A] = { |
---|
306 | 341 | .name = "MAX98357A", |
---|
307 | 342 | .stream_name = "MAX98357A PCM", |
---|
308 | | - .codec_dai_name = "HiFi", |
---|
309 | 343 | .ops = &rockchip_sound_max98357a_ops, |
---|
310 | 344 | /* set max98357a as slave */ |
---|
311 | 345 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
---|
312 | 346 | SND_SOC_DAIFMT_CBS_CFS, |
---|
| 347 | + SND_SOC_DAILINK_REG(max98357a), |
---|
313 | 348 | }, |
---|
314 | 349 | [DAILINK_RT5514] = { |
---|
315 | 350 | .name = "RT5514", |
---|
316 | 351 | .stream_name = "RT5514 PCM", |
---|
317 | | - .codec_dai_name = "rt5514-aif1", |
---|
318 | 352 | .ops = &rockchip_sound_rt5514_ops, |
---|
319 | 353 | /* set rt5514 as slave */ |
---|
320 | 354 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
---|
321 | 355 | SND_SOC_DAIFMT_CBS_CFS, |
---|
| 356 | + SND_SOC_DAILINK_REG(rt5514), |
---|
322 | 357 | }, |
---|
323 | 358 | /* RT5514 DSP for voice wakeup via spi bus */ |
---|
324 | 359 | [DAILINK_RT5514_DSP] = { |
---|
325 | 360 | .name = "RT5514 DSP", |
---|
326 | 361 | .stream_name = "Wake on Voice", |
---|
327 | | - .codec_name = "snd-soc-dummy", |
---|
328 | | - .codec_dai_name = "snd-soc-dummy-dai", |
---|
| 362 | + SND_SOC_DAILINK_REG(rt5514_dsp), |
---|
329 | 363 | }, |
---|
330 | 364 | }; |
---|
331 | 365 | |
---|
.. | .. |
---|
416 | 450 | }, |
---|
417 | 451 | }; |
---|
418 | 452 | |
---|
419 | | -static int of_dev_node_match(struct device *dev, void *data) |
---|
420 | | -{ |
---|
421 | | - return dev->of_node == data; |
---|
422 | | -} |
---|
423 | | - |
---|
424 | 453 | static int rockchip_sound_codec_node_match(struct device_node *np_codec) |
---|
425 | 454 | { |
---|
426 | 455 | struct device *dev; |
---|
.. | .. |
---|
432 | 461 | continue; |
---|
433 | 462 | |
---|
434 | 463 | if (dailink_match[i].bus_type) { |
---|
435 | | - dev = bus_find_device(dailink_match[i].bus_type, NULL, |
---|
436 | | - np_codec, of_dev_node_match); |
---|
| 464 | + dev = bus_find_device_by_of_node(dailink_match[i].bus_type, |
---|
| 465 | + np_codec); |
---|
437 | 466 | if (!dev) |
---|
438 | 467 | continue; |
---|
439 | 468 | put_device(dev); |
---|
.. | .. |
---|
507 | 536 | dai = &card->dai_link[card->num_links++]; |
---|
508 | 537 | *dai = rockchip_dais[index]; |
---|
509 | 538 | |
---|
510 | | - if (!dai->codec_name) |
---|
511 | | - dai->codec_of_node = np_codec; |
---|
512 | | - dai->platform_of_node = np_cpu; |
---|
513 | | - dai->cpu_of_node = np_cpu; |
---|
| 539 | + if (!dai->codecs->name) |
---|
| 540 | + dai->codecs->of_node = np_codec; |
---|
| 541 | + dai->platforms->of_node = np_cpu; |
---|
| 542 | + dai->cpus->of_node = np_cpu; |
---|
514 | 543 | |
---|
515 | 544 | if (card->num_dapm_routes + rockchip_routes[index].num_routes > |
---|
516 | 545 | num_routes) { |
---|