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 = card->dai_link; 29 int i, num_links = card->num_links; 30 31 for (i = 0; i < num_links; i++) { 32 if (link->no_pcm == 1) 33 link->be_hw_params_fixup = apq8096_be_hw_params_fixup; 34 link++; 35 } 36 } 37 38 static int apq8096_platform_probe(struct platform_device *pdev) 39 { 40 struct snd_soc_card *card; 41 struct device *dev = &pdev->dev; 42 int ret; 43 44 card = kzalloc(sizeof(*card), GFP_KERNEL); 45 if (!card) 46 return -ENOMEM; 47 48 card->dev = dev; 49 dev_set_drvdata(dev, card); 50 ret = qcom_snd_parse_of(card); 51 if (ret) { 52 dev_err(dev, "Error parsing OF data\n"); 53 goto err; 54 } 55 56 apq8096_add_be_ops(card); 57 ret = snd_soc_register_card(card); 58 if (ret) 59 goto err_card_register; 60 61 return 0; 62 63 err_card_register: 64 kfree(card->dai_link); 65 err: 66 kfree(card); 67 return ret; 68 } 69 70 static int apq8096_platform_remove(struct platform_device *pdev) 71 { 72 struct snd_soc_card *card = dev_get_drvdata(&pdev->dev); 73 74 snd_soc_unregister_card(card); 75 kfree(card->dai_link); 76 kfree(card); 77 78 return 0; 79 } 80 81 static const struct of_device_id msm_snd_apq8096_dt_match[] = { 82 {.compatible = "qcom,apq8096-sndcard"}, 83 {} 84 }; 85 86 MODULE_DEVICE_TABLE(of, msm_snd_apq8096_dt_match); 87 88 static struct platform_driver msm_snd_apq8096_driver = { 89 .probe = apq8096_platform_probe, 90 .remove = apq8096_platform_remove, 91 .driver = { 92 .name = "msm-snd-apq8096", 93 .of_match_table = msm_snd_apq8096_dt_match, 94 }, 95 }; 96 module_platform_driver(msm_snd_apq8096_driver); 97 MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org"); 98 MODULE_DESCRIPTION("APQ8096 ASoC Machine Driver"); 99 MODULE_LICENSE("GPL v2"); 100