xref: /openbmc/linux/sound/soc/amd/acp/acp-sof-mach.c (revision fe4d0d5d)
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 //
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
5 //
6 // Copyright(c) 2021 Advanced Micro Devices, Inc.
7 //
8 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
9 //
10 
11 /*
12  * SOF Machine Driver Support for ACP HW block
13  */
14 
15 #include <sound/core.h>
16 #include <sound/pcm_params.h>
17 #include <sound/soc-acpi.h>
18 #include <sound/soc-dapm.h>
19 #include <linux/module.h>
20 
21 #include "acp-mach.h"
22 
23 static struct acp_card_drvdata sof_rt5682_rt1019_data = {
24 	.hs_cpu_id = I2S_SP,
25 	.amp_cpu_id = I2S_SP,
26 	.dmic_cpu_id = DMIC,
27 	.hs_codec_id = RT5682,
28 	.amp_codec_id = RT1019,
29 	.dmic_codec_id = DMIC,
30 	.gpio_spkr_en = EN_SPKR_GPIO_GB,
31 };
32 
33 static struct acp_card_drvdata sof_rt5682_max_data = {
34 	.hs_cpu_id = I2S_SP,
35 	.amp_cpu_id = I2S_SP,
36 	.dmic_cpu_id = DMIC,
37 	.hs_codec_id = RT5682,
38 	.amp_codec_id = MAX98360A,
39 	.dmic_codec_id = DMIC,
40 	.gpio_spkr_en = EN_SPKR_GPIO_NONE,
41 };
42 
43 static struct acp_card_drvdata sof_rt5682s_rt1019_data = {
44 	.hs_cpu_id = I2S_SP,
45 	.amp_cpu_id = I2S_SP,
46 	.dmic_cpu_id = DMIC,
47 	.hs_codec_id = RT5682S,
48 	.amp_codec_id = RT1019,
49 	.dmic_codec_id = DMIC,
50 };
51 
52 static struct acp_card_drvdata sof_rt5682s_max_data = {
53 	.hs_cpu_id = I2S_SP,
54 	.amp_cpu_id = I2S_SP,
55 	.dmic_cpu_id = DMIC,
56 	.hs_codec_id = RT5682S,
57 	.amp_codec_id = MAX98360A,
58 	.dmic_codec_id = DMIC,
59 	.gpio_spkr_en = EN_SPKR_GPIO_NONE,
60 };
61 
62 static const struct snd_kcontrol_new acp_controls[] = {
63 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
64 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
65 	SOC_DAPM_PIN_SWITCH("Spk"),
66 	SOC_DAPM_PIN_SWITCH("Left Spk"),
67 	SOC_DAPM_PIN_SWITCH("Right Spk"),
68 };
69 
70 static const struct snd_soc_dapm_widget acp_widgets[] = {
71 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
72 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
73 	SND_SOC_DAPM_SPK("Spk", event_spkr_handler),
74 	SND_SOC_DAPM_SPK("Left Spk", event_spkr_handler),
75 	SND_SOC_DAPM_SPK("Right Spk", event_spkr_handler),
76 };
77 
78 static int acp_sof_probe(struct platform_device *pdev)
79 {
80 	struct snd_soc_card *card = NULL;
81 	struct device *dev = &pdev->dev;
82 	unsigned int spkr_gpio;
83 	int ret;
84 
85 	if (!pdev->id_entry)
86 		return -EINVAL;
87 
88 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
89 	if (!card)
90 		return -ENOMEM;
91 
92 	card->dev = dev;
93 	card->owner = THIS_MODULE;
94 	card->name = pdev->id_entry->name;
95 	card->dapm_widgets = acp_widgets;
96 	card->num_dapm_widgets = ARRAY_SIZE(acp_widgets);
97 	card->controls = acp_controls;
98 	card->num_controls = ARRAY_SIZE(acp_controls);
99 	card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
100 	spkr_gpio = ((struct acp_card_drvdata *)(card->drvdata))->gpio_spkr_en;
101 
102 	acp_sofdsp_dai_links_create(card);
103 
104 	if (gpio_is_valid(spkr_gpio)) {
105 		ret = devm_gpio_request(dev, spkr_gpio, "spkren");
106 		if (ret) {
107 			dev_err(dev, "(%s) gpio request failed: %d\n",
108 				__func__, ret);
109 			return ret;
110 		}
111 		gpio_direction_output(spkr_gpio, 0);
112 	}
113 
114 	ret = devm_snd_soc_register_card(&pdev->dev, card);
115 	if (ret) {
116 		dev_err(&pdev->dev,
117 				"devm_snd_soc_register_card(%s) failed: %d\n",
118 				card->name, ret);
119 		return ret;
120 	}
121 
122 	return 0;
123 }
124 
125 static const struct platform_device_id board_ids[] = {
126 	{
127 		.name = "rt5682-rt1019",
128 		.driver_data = (kernel_ulong_t)&sof_rt5682_rt1019_data
129 	},
130 	{
131 		.name = "rt5682-max",
132 		.driver_data = (kernel_ulong_t)&sof_rt5682_max_data
133 	},
134 	{
135 		.name = "rt5682s-max",
136 		.driver_data = (kernel_ulong_t)&sof_rt5682s_max_data
137 	},
138 	{
139 		.name = "rt5682s-rt1019",
140 		.driver_data = (kernel_ulong_t)&sof_rt5682s_rt1019_data
141 	},
142 	{ }
143 };
144 static struct platform_driver acp_asoc_audio = {
145 	.driver = {
146 		.name = "sof_mach",
147 	},
148 	.probe = acp_sof_probe,
149 	.id_table = board_ids,
150 };
151 
152 module_platform_driver(acp_asoc_audio);
153 
154 MODULE_IMPORT_NS(SND_SOC_AMD_MACH);
155 MODULE_DESCRIPTION("ACP chrome SOF audio support");
156 MODULE_ALIAS("platform:rt5682-rt1019");
157 MODULE_ALIAS("platform:rt5682-max");
158 MODULE_ALIAS("platform:rt5682s-max");
159 MODULE_ALIAS("platform:rt5682s-rt1019");
160 MODULE_LICENSE("GPL v2");
161