1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2018, Linaro Limited 3 4 #include <linux/module.h> 5 #include <linux/platform_device.h> 6 #include <linux/of_device.h> 7 #include <sound/soc.h> 8 #include <sound/soc-dapm.h> 9 #include <sound/pcm.h> 10 #include "common.h" 11 12 static int apq8096_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 13 struct snd_pcm_hw_params *params) 14 { 15 struct snd_interval *rate = hw_param_interval(params, 16 SNDRV_PCM_HW_PARAM_RATE); 17 struct snd_interval *channels = hw_param_interval(params, 18 SNDRV_PCM_HW_PARAM_CHANNELS); 19 20 rate->min = rate->max = 48000; 21 channels->min = channels->max = 2; 22 23 return 0; 24 } 25 26 static void apq8096_add_be_ops(struct snd_soc_card *card) 27 { 28 struct snd_soc_dai_link *link; 29 int i; 30 31 for_each_card_prelinks(card, i, link) { 32 if (link->no_pcm == 1) 33 link->be_hw_params_fixup = apq8096_be_hw_params_fixup; 34 } 35 } 36 37 static int apq8096_platform_probe(struct platform_device *pdev) 38 { 39 struct snd_soc_card *card; 40 struct device *dev = &pdev->dev; 41 int ret; 42 43 card = kzalloc(sizeof(*card), GFP_KERNEL); 44 if (!card) 45 return -ENOMEM; 46 47 card->dev = dev; 48 dev_set_drvdata(dev, card); 49 ret = qcom_snd_parse_of(card); 50 if (ret) { 51 dev_err(dev, "Error parsing OF data\n"); 52 goto err; 53 } 54 55 apq8096_add_be_ops(card); 56 ret = snd_soc_register_card(card); 57 if (ret) 58 goto err_card_register; 59 60 return 0; 61 62 err_card_register: 63 kfree(card->dai_link); 64 err: 65 kfree(card); 66 return ret; 67 } 68 69 static int apq8096_platform_remove(struct platform_device *pdev) 70 { 71 struct snd_soc_card *card = dev_get_drvdata(&pdev->dev); 72 73 snd_soc_unregister_card(card); 74 kfree(card->dai_link); 75 kfree(card); 76 77 return 0; 78 } 79 80 static const struct of_device_id msm_snd_apq8096_dt_match[] = { 81 {.compatible = "qcom,apq8096-sndcard"}, 82 {} 83 }; 84 85 MODULE_DEVICE_TABLE(of, msm_snd_apq8096_dt_match); 86 87 static struct platform_driver msm_snd_apq8096_driver = { 88 .probe = apq8096_platform_probe, 89 .remove = apq8096_platform_remove, 90 .driver = { 91 .name = "msm-snd-apq8096", 92 .of_match_table = msm_snd_apq8096_dt_match, 93 }, 94 }; 95 module_platform_driver(msm_snd_apq8096_driver); 96 MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org"); 97 MODULE_DESCRIPTION("APQ8096 ASoC Machine Driver"); 98 MODULE_LICENSE("GPL v2"); 99