xref: /openbmc/linux/sound/soc/sof/amd/renoir.c (revision 5b4fc395)
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  * Hardware interface for Audio DSP on Renoir platform
12  */
13 
14 #include <linux/platform_device.h>
15 #include <linux/module.h>
16 
17 #include "../ops.h"
18 #include "../sof-audio.h"
19 #include "acp.h"
20 #include "acp-dsp-offset.h"
21 
22 #define I2S_BT_INSTANCE		0
23 #define I2S_SP_INSTANCE		1
24 #define PDM_DMIC_INSTANCE	2
25 
26 #define I2S_MODE		0x04
27 
28 static int renoir_dai_probe(struct snd_soc_dai *dai)
29 {
30 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component);
31 	unsigned int val;
32 
33 	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_I2S_PIN_CONFIG);
34 	if (val != I2S_MODE) {
35 		dev_err(sdev->dev, "I2S Mode is not supported (I2S_PIN_CONFIG: %#x)\n", val);
36 		return -EINVAL;
37 	}
38 
39 	return 0;
40 }
41 
42 static struct snd_soc_dai_driver renoir_sof_dai[] = {
43 	[I2S_BT_INSTANCE] = {
44 		.id = I2S_BT_INSTANCE,
45 		.name = "acp-sof-bt",
46 		.playback = {
47 			.rates = SNDRV_PCM_RATE_8000_96000,
48 			.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
49 				   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
50 			.channels_min = 2,
51 			.channels_max = 8,
52 			.rate_min = 8000,
53 			.rate_max = 96000,
54 		},
55 		.capture = {
56 			.rates = SNDRV_PCM_RATE_8000_48000,
57 			.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
58 				   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
59 			/* Supporting only stereo for I2S BT controller capture */
60 			.channels_min = 2,
61 			.channels_max = 2,
62 			.rate_min = 8000,
63 			.rate_max = 48000,
64 		},
65 		.probe = &renoir_dai_probe,
66 	},
67 
68 	[I2S_SP_INSTANCE] = {
69 		.id = I2S_SP_INSTANCE,
70 		.name = "acp-sof-sp",
71 		.playback = {
72 			.rates = SNDRV_PCM_RATE_8000_96000,
73 			.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
74 				   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
75 			.channels_min = 2,
76 			.channels_max = 8,
77 			.rate_min = 8000,
78 			.rate_max = 96000,
79 		},
80 		.capture = {
81 			.rates = SNDRV_PCM_RATE_8000_48000,
82 			.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
83 				   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
84 			/* Supporting only stereo for I2S SP controller capture */
85 			.channels_min = 2,
86 			.channels_max = 2,
87 			.rate_min = 8000,
88 			.rate_max = 48000,
89 		},
90 		.probe = &renoir_dai_probe,
91 	},
92 
93 	[PDM_DMIC_INSTANCE] = {
94 		.id = PDM_DMIC_INSTANCE,
95 		.name = "acp-sof-dmic",
96 		.capture = {
97 			.rates = SNDRV_PCM_RATE_8000_48000,
98 			.formats = SNDRV_PCM_FMTBIT_S32_LE,
99 			.channels_min = 2,
100 			.channels_max = 4,
101 			.rate_min = 8000,
102 			.rate_max = 48000,
103 		},
104 	},
105 };
106 
107 static struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev)
108 {
109 	struct snd_sof_pdata *sof_pdata = sdev->pdata;
110 	const struct sof_dev_desc *desc = sof_pdata->desc;
111 	struct snd_soc_acpi_mach *mach;
112 
113 	mach = snd_soc_acpi_find_machine(desc->machines);
114 	if (!mach) {
115 		dev_warn(sdev->dev, "No matching ASoC machine driver found\n");
116 		return NULL;
117 	}
118 
119 	sof_pdata->tplg_filename = mach->sof_tplg_filename;
120 	sof_pdata->fw_filename = mach->fw_filename;
121 
122 	return mach;
123 }
124 
125 /* AMD Renoir DSP ops */
126 struct snd_sof_dsp_ops sof_renoir_ops = {
127 	/* probe and remove */
128 	.probe			= amd_sof_acp_probe,
129 	.remove			= amd_sof_acp_remove,
130 
131 	/* Register IO */
132 	.write			= sof_io_write,
133 	.read			= sof_io_read,
134 
135 	/* Block IO */
136 	.block_read		= acp_dsp_block_read,
137 	.block_write		= acp_dsp_block_write,
138 
139 	/*Firmware loading */
140 	.load_firmware		= snd_sof_load_firmware_memcpy,
141 	.pre_fw_run		= acp_dsp_pre_fw_run,
142 	.get_bar_index		= acp_get_bar_index,
143 
144 	/* DSP core boot */
145 	.run			= acp_sof_dsp_run,
146 
147 	/*IPC */
148 	.send_msg		= acp_sof_ipc_send_msg,
149 	.ipc_msg_data		= acp_sof_ipc_msg_data,
150 	.get_mailbox_offset	= acp_sof_ipc_get_mailbox_offset,
151 	.irq_thread		= acp_sof_ipc_irq_thread,
152 
153 	/* DAI drivers */
154 	.drv			= renoir_sof_dai,
155 	.num_drv		= ARRAY_SIZE(renoir_sof_dai),
156 
157 	/* stream callbacks */
158 	.pcm_open		= acp_pcm_open,
159 	.pcm_close		= acp_pcm_close,
160 	.pcm_hw_params		= acp_pcm_hw_params,
161 
162 	.hw_info		= SNDRV_PCM_INFO_MMAP |
163 				  SNDRV_PCM_INFO_MMAP_VALID |
164 				  SNDRV_PCM_INFO_INTERLEAVED |
165 				  SNDRV_PCM_INFO_PAUSE |
166 				  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
167 
168 	/* Machine driver callbacks */
169 	.machine_select		= amd_sof_machine_select,
170 	.machine_register	= sof_machine_register,
171 	.machine_unregister	= sof_machine_unregister,
172 
173 	/* Trace Logger */
174 	.trace_init		= acp_sof_trace_init,
175 	.trace_release		= acp_sof_trace_release,
176 
177 	/* PM */
178 	.suspend                = amd_sof_acp_suspend,
179 	.resume                 = amd_sof_acp_resume,
180 };
181 EXPORT_SYMBOL(sof_renoir_ops);
182 
183 MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON);
184 MODULE_DESCRIPTION("RENOIR SOF Driver");
185 MODULE_LICENSE("Dual BSD/GPL");
186