| .. | .. |
|---|
| 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) { |
|---|