Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: rockchip: Parse dai links from dts

Refactor rockchip_sound_probe, parse dai links from dts instead of
hard coding them.

Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Tested-by: Matthias Kaehlcke <mka@chromium.org>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Jeffy Chen and committed by
Mark Brown
0d52954f 72cfb0f2

+92 -50
+92 -50
sound/soc/rockchip/rk3399_gru_sound.c
··· 240 240 .hw_params = rockchip_sound_da7219_hw_params, 241 241 }; 242 242 243 + static struct snd_soc_card rockchip_sound_card = { 244 + .name = "rk3399-gru-sound", 245 + .owner = THIS_MODULE, 246 + .dapm_widgets = rockchip_dapm_widgets, 247 + .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets), 248 + .dapm_routes = rockchip_dapm_routes, 249 + .num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes), 250 + .controls = rockchip_controls, 251 + .num_controls = ARRAY_SIZE(rockchip_controls), 252 + }; 253 + 243 254 enum { 255 + DAILINK_DA7219, 244 256 DAILINK_MAX98357A, 245 257 DAILINK_RT5514, 246 - DAILINK_DA7219, 247 258 DAILINK_RT5514_DSP, 248 259 }; 249 260 250 - static struct snd_soc_dai_link rockchip_dailinks[] = { 261 + static const char * const dailink_compat[] = { 262 + [DAILINK_DA7219] = "dlg,da7219", 263 + [DAILINK_MAX98357A] = "maxim,max98357a", 264 + [DAILINK_RT5514] = "realtek,rt5514-i2c", 265 + [DAILINK_RT5514_DSP] = "realtek,rt5514-spi", 266 + }; 267 + 268 + static const struct snd_soc_dai_link rockchip_dais[] = { 269 + [DAILINK_DA7219] = { 270 + .name = "DA7219", 271 + .stream_name = "DA7219 PCM", 272 + .codec_dai_name = "da7219-hifi", 273 + .init = rockchip_sound_da7219_init, 274 + .ops = &rockchip_sound_da7219_ops, 275 + /* set da7219 as slave */ 276 + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 277 + SND_SOC_DAIFMT_CBS_CFS, 278 + }, 251 279 [DAILINK_MAX98357A] = { 252 280 .name = "MAX98357A", 253 281 .stream_name = "MAX98357A PCM", ··· 294 266 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 295 267 SND_SOC_DAIFMT_CBS_CFS, 296 268 }, 297 - [DAILINK_DA7219] = { 298 - .name = "DA7219", 299 - .stream_name = "DA7219 PCM", 300 - .codec_dai_name = "da7219-hifi", 301 - .init = rockchip_sound_da7219_init, 302 - .ops = &rockchip_sound_da7219_ops, 303 - /* set da7219 as slave */ 304 - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 305 - SND_SOC_DAIFMT_CBS_CFS, 306 - }, 307 269 /* RT5514 DSP for voice wakeup via spi bus */ 308 270 [DAILINK_RT5514_DSP] = { 309 271 .name = "RT5514 DSP", ··· 302 284 }, 303 285 }; 304 286 305 - static struct snd_soc_card rockchip_sound_card = { 306 - .name = "rk3399-gru-sound", 307 - .owner = THIS_MODULE, 308 - .dai_link = rockchip_dailinks, 309 - .num_links = ARRAY_SIZE(rockchip_dailinks), 310 - .dapm_widgets = rockchip_dapm_widgets, 311 - .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets), 312 - .dapm_routes = rockchip_dapm_routes, 313 - .num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes), 314 - .controls = rockchip_controls, 315 - .num_controls = ARRAY_SIZE(rockchip_controls), 316 - }; 287 + static int rockchip_sound_codec_node_match(struct device_node *np_codec) 288 + { 289 + int i; 290 + 291 + for (i = 0; i < ARRAY_SIZE(dailink_compat); i++) { 292 + if (of_device_is_compatible(np_codec, dailink_compat[i])) 293 + return i; 294 + } 295 + return -1; 296 + } 297 + 298 + static int rockchip_sound_of_parse_dais(struct device *dev, 299 + struct snd_soc_card *card) 300 + { 301 + struct device_node *np_cpu; 302 + struct device_node *np_codec; 303 + struct snd_soc_dai_link *dai; 304 + int i, index; 305 + 306 + card->dai_link = devm_kzalloc(dev, sizeof(rockchip_dais), 307 + GFP_KERNEL); 308 + if (!card->dai_link) 309 + return -ENOMEM; 310 + 311 + np_cpu = of_parse_phandle(dev->of_node, "rockchip,cpu", 0); 312 + 313 + card->num_links = 0; 314 + for (i = 0; i < ARRAY_SIZE(rockchip_dais); i++) { 315 + np_codec = of_parse_phandle(dev->of_node, 316 + "rockchip,codec", i); 317 + if (!np_codec) 318 + break; 319 + 320 + if (!of_device_is_available(np_codec)) 321 + continue; 322 + 323 + index = rockchip_sound_codec_node_match(np_codec); 324 + if (index < 0) 325 + continue; 326 + 327 + if (!np_cpu) { 328 + dev_err(dev, "Missing 'rockchip,cpu' for %s\n", 329 + rockchip_dais[index].name); 330 + return -EINVAL; 331 + } 332 + 333 + dai = &card->dai_link[card->num_links++]; 334 + *dai = rockchip_dais[index]; 335 + 336 + dai->codec_of_node = np_codec; 337 + dai->platform_of_node = np_cpu; 338 + dai->cpu_of_node = np_cpu; 339 + } 340 + 341 + return 0; 342 + } 317 343 318 344 static int rockchip_sound_probe(struct platform_device *pdev) 319 345 { 320 346 struct snd_soc_card *card = &rockchip_sound_card; 321 - struct device_node *cpu_node; 322 - int i, ret; 347 + int ret; 323 348 324 - cpu_node = of_parse_phandle(pdev->dev.of_node, "rockchip,cpu", 0); 325 - if (!cpu_node) { 326 - dev_err(&pdev->dev, "Property 'rockchip,cpu' missing or invalid\n"); 327 - return -EINVAL; 328 - } 329 - 330 - for (i = 0; i < ARRAY_SIZE(rockchip_dailinks); i++) { 331 - rockchip_dailinks[i].platform_of_node = cpu_node; 332 - rockchip_dailinks[i].cpu_of_node = cpu_node; 333 - 334 - rockchip_dailinks[i].codec_of_node = 335 - of_parse_phandle(pdev->dev.of_node, "rockchip,codec", i); 336 - if (!rockchip_dailinks[i].codec_of_node) { 337 - dev_err(&pdev->dev, 338 - "Property[%d] 'rockchip,codec' missing or invalid\n", i); 339 - return -EINVAL; 340 - } 349 + ret = rockchip_sound_of_parse_dais(&pdev->dev, card); 350 + if (ret < 0) { 351 + dev_err(&pdev->dev, "Failed to parse dais: %d\n", ret); 352 + return ret; 341 353 } 342 354 343 355 /* Set DMIC wakeup delay */ ··· 380 332 } 381 333 382 334 card->dev = &pdev->dev; 383 - 384 - ret = devm_snd_soc_register_card(&pdev->dev, card); 385 - if (ret) 386 - dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", 387 - __func__, ret); 388 - 389 - return ret; 335 + return devm_snd_soc_register_card(&pdev->dev, card); 390 336 } 391 337 392 338 static const struct of_device_id rockchip_sound_of_match[] = {