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 * Hardware interface for Renoir ACP block 13 */ 14 15 #include <linux/platform_device.h> 16 #include <linux/module.h> 17 #include <linux/err.h> 18 #include <linux/io.h> 19 #include <sound/pcm_params.h> 20 #include <sound/soc.h> 21 #include <sound/soc-dai.h> 22 #include <linux/dma-mapping.h> 23 #include <linux/pm_runtime.h> 24 25 #include "amd.h" 26 #include "acp-mach.h" 27 28 #define DRV_NAME "acp_asoc_renoir" 29 30 static struct acp_resource rsrc = { 31 .offset = 20, 32 .no_of_ctrls = 1, 33 .irqp_used = 0, 34 .irq_reg_offset = 0x1800, 35 .i2s_pin_cfg_offset = 0x1400, 36 .i2s_mode = 0x04, 37 .scratch_reg_offset = 0x12800, 38 .sram_pte_offset = 0x02052800, 39 }; 40 41 static struct snd_soc_acpi_codecs amp_rt1019 = { 42 .num_codecs = 1, 43 .codecs = {"10EC1019"} 44 }; 45 46 static struct snd_soc_acpi_codecs amp_max = { 47 .num_codecs = 1, 48 .codecs = {"MX98360A"} 49 }; 50 51 static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = { 52 { 53 .id = "10EC5682", 54 .drv_name = "acp3xalc56821019", 55 .machine_quirk = snd_soc_acpi_codec_list, 56 .quirk_data = &_rt1019, 57 }, 58 { 59 .id = "RTL5682", 60 .drv_name = "acp3xalc5682sm98360", 61 .machine_quirk = snd_soc_acpi_codec_list, 62 .quirk_data = &_max, 63 }, 64 { 65 .id = "RTL5682", 66 .drv_name = "acp3xalc5682s1019", 67 .machine_quirk = snd_soc_acpi_codec_list, 68 .quirk_data = &_rt1019, 69 }, 70 { 71 .id = "AMDI1019", 72 .drv_name = "renoir-acp", 73 }, 74 { 75 .id = "ESSX8336", 76 .drv_name = "acp3x-es83xx", 77 }, 78 {}, 79 }; 80 81 static struct snd_soc_dai_driver acp_renoir_dai[] = { 82 { 83 .name = "acp-i2s-sp", 84 .id = I2S_SP_INSTANCE, 85 .playback = { 86 .stream_name = "I2S SP Playback", 87 .rates = SNDRV_PCM_RATE_8000_96000, 88 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 89 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 90 .channels_min = 2, 91 .channels_max = 8, 92 .rate_min = 8000, 93 .rate_max = 96000, 94 }, 95 .capture = { 96 .stream_name = "I2S SP Capture", 97 .rates = SNDRV_PCM_RATE_8000_48000, 98 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 99 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 100 .channels_min = 2, 101 .channels_max = 2, 102 .rate_min = 8000, 103 .rate_max = 48000, 104 }, 105 .ops = &asoc_acp_cpu_dai_ops, 106 }, 107 { 108 .name = "acp-i2s-bt", 109 .id = I2S_BT_INSTANCE, 110 .playback = { 111 .stream_name = "I2S BT Playback", 112 .rates = SNDRV_PCM_RATE_8000_96000, 113 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 114 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 115 .channels_min = 2, 116 .channels_max = 8, 117 .rate_min = 8000, 118 .rate_max = 96000, 119 }, 120 .capture = { 121 .stream_name = "I2S BT Capture", 122 .rates = SNDRV_PCM_RATE_8000_48000, 123 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 124 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 125 .channels_min = 2, 126 .channels_max = 2, 127 .rate_min = 8000, 128 .rate_max = 48000, 129 }, 130 .ops = &asoc_acp_cpu_dai_ops, 131 }, 132 { 133 .name = "acp-pdm-dmic", 134 .id = DMIC_INSTANCE, 135 .capture = { 136 .rates = SNDRV_PCM_RATE_8000_48000, 137 .formats = SNDRV_PCM_FMTBIT_S32_LE, 138 .channels_min = 2, 139 .channels_max = 2, 140 .rate_min = 8000, 141 .rate_max = 48000, 142 }, 143 .ops = &acp_dmic_dai_ops, 144 }, 145 }; 146 147 148 static int renoir_audio_probe(struct platform_device *pdev) 149 { 150 struct device *dev = &pdev->dev; 151 struct acp_chip_info *chip; 152 struct acp_dev_data *adata; 153 struct resource *res; 154 int ret; 155 156 chip = dev_get_platdata(&pdev->dev); 157 if (!chip || !chip->base) { 158 dev_err(&pdev->dev, "ACP chip data is NULL\n"); 159 return -ENODEV; 160 } 161 162 if (chip->acp_rev != ACP3X_DEV) { 163 dev_err(&pdev->dev, "Un-supported ACP Revision %d\n", chip->acp_rev); 164 return -ENODEV; 165 } 166 167 adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); 168 if (!adata) 169 return -ENOMEM; 170 171 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem"); 172 if (!res) { 173 dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); 174 return -ENODEV; 175 } 176 177 adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); 178 if (!adata->acp_base) 179 return -ENOMEM; 180 181 ret = platform_get_irq_byname(pdev, "acp_dai_irq"); 182 if (ret < 0) 183 return ret; 184 adata->i2s_irq = ret; 185 186 adata->dev = dev; 187 adata->dai_driver = acp_renoir_dai; 188 adata->num_dai = ARRAY_SIZE(acp_renoir_dai); 189 adata->rsrc = &rsrc; 190 adata->platform = RENOIR; 191 adata->flag = chip->flag; 192 193 adata->machines = snd_soc_acpi_amd_acp_machines; 194 acp_machine_select(adata); 195 196 dev_set_drvdata(dev, adata); 197 acp_enable_interrupts(adata); 198 acp_platform_register(dev); 199 200 pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); 201 pm_runtime_use_autosuspend(&pdev->dev); 202 pm_runtime_mark_last_busy(&pdev->dev); 203 pm_runtime_set_active(&pdev->dev); 204 pm_runtime_enable(&pdev->dev); 205 return 0; 206 } 207 208 static void renoir_audio_remove(struct platform_device *pdev) 209 { 210 struct device *dev = &pdev->dev; 211 struct acp_dev_data *adata = dev_get_drvdata(dev); 212 213 acp_disable_interrupts(adata); 214 acp_platform_unregister(dev); 215 } 216 217 static int __maybe_unused rn_pcm_resume(struct device *dev) 218 { 219 struct acp_dev_data *adata = dev_get_drvdata(dev); 220 struct acp_stream *stream; 221 struct snd_pcm_substream *substream; 222 snd_pcm_uframes_t buf_in_frames; 223 u64 buf_size; 224 225 spin_lock(&adata->acp_lock); 226 list_for_each_entry(stream, &adata->stream_list, list) { 227 substream = stream->substream; 228 if (substream && substream->runtime) { 229 buf_in_frames = (substream->runtime->buffer_size); 230 buf_size = frames_to_bytes(substream->runtime, buf_in_frames); 231 config_pte_for_stream(adata, stream); 232 config_acp_dma(adata, stream, buf_size); 233 if (stream->dai_id) 234 restore_acp_i2s_params(substream, adata, stream); 235 else 236 restore_acp_pdm_params(substream, adata); 237 } 238 } 239 spin_unlock(&adata->acp_lock); 240 return 0; 241 } 242 243 static const struct dev_pm_ops rn_dma_pm_ops = { 244 SET_SYSTEM_SLEEP_PM_OPS(NULL, rn_pcm_resume) 245 }; 246 247 static struct platform_driver renoir_driver = { 248 .probe = renoir_audio_probe, 249 .remove_new = renoir_audio_remove, 250 .driver = { 251 .name = "acp_asoc_renoir", 252 .pm = &rn_dma_pm_ops, 253 }, 254 }; 255 256 module_platform_driver(renoir_driver); 257 258 MODULE_DESCRIPTION("AMD ACP Renoir Driver"); 259 MODULE_IMPORT_NS(SND_SOC_ACP_COMMON); 260 MODULE_LICENSE("Dual BSD/GPL"); 261 MODULE_ALIAS("platform:" DRV_NAME); 262