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) 2023 Advanced Micro Devices, Inc. 7 // 8 // Authors: Venkata Prasad Potturu <venkataprasad.potturu@amd.com> 9 10 /* 11 * Hardware interface for Audio DSP on Vangogh platform 12 */ 13 14 #include <linux/delay.h> 15 #include <linux/module.h> 16 17 #include "acp.h" 18 19 #define I2S_HS_INSTANCE 0 20 #define I2S_BT_INSTANCE 1 21 #define I2S_SP_INSTANCE 2 22 #define PDM_DMIC_INSTANCE 3 23 #define I2S_HS_VIRTUAL_INSTANCE 4 24 25 static struct snd_soc_dai_driver vangogh_sof_dai[] = { 26 [I2S_HS_INSTANCE] = { 27 .id = I2S_HS_INSTANCE, 28 .name = "acp-sof-hs", 29 .playback = { 30 .rates = SNDRV_PCM_RATE_8000_96000, 31 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 32 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 33 .channels_min = 2, 34 .channels_max = 8, 35 .rate_min = 8000, 36 .rate_max = 96000, 37 }, 38 .capture = { 39 .rates = SNDRV_PCM_RATE_8000_48000, 40 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 41 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 42 /* Supporting only stereo for I2S HS controller capture */ 43 .channels_min = 2, 44 .channels_max = 2, 45 .rate_min = 8000, 46 .rate_max = 48000, 47 }, 48 }, 49 50 [I2S_BT_INSTANCE] = { 51 .id = I2S_BT_INSTANCE, 52 .name = "acp-sof-bt", 53 .playback = { 54 .rates = SNDRV_PCM_RATE_8000_96000, 55 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 56 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 57 .channels_min = 2, 58 .channels_max = 8, 59 .rate_min = 8000, 60 .rate_max = 96000, 61 }, 62 .capture = { 63 .rates = SNDRV_PCM_RATE_8000_48000, 64 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 65 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 66 /* Supporting only stereo for I2S BT controller capture */ 67 .channels_min = 2, 68 .channels_max = 2, 69 .rate_min = 8000, 70 .rate_max = 48000, 71 }, 72 }, 73 74 [I2S_SP_INSTANCE] = { 75 .id = I2S_SP_INSTANCE, 76 .name = "acp-sof-sp", 77 .playback = { 78 .rates = SNDRV_PCM_RATE_8000_96000, 79 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 80 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 81 .channels_min = 2, 82 .channels_max = 8, 83 .rate_min = 8000, 84 .rate_max = 96000, 85 }, 86 .capture = { 87 .rates = SNDRV_PCM_RATE_8000_48000, 88 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 89 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 90 /* Supporting only stereo for I2S SP controller capture */ 91 .channels_min = 2, 92 .channels_max = 2, 93 .rate_min = 8000, 94 .rate_max = 48000, 95 }, 96 }, 97 98 [PDM_DMIC_INSTANCE] = { 99 .id = PDM_DMIC_INSTANCE, 100 .name = "acp-sof-dmic", 101 .capture = { 102 .rates = SNDRV_PCM_RATE_8000_48000, 103 .formats = SNDRV_PCM_FMTBIT_S32_LE, 104 .channels_min = 2, 105 .channels_max = 4, 106 .rate_min = 8000, 107 .rate_max = 48000, 108 }, 109 }, 110 111 [I2S_HS_VIRTUAL_INSTANCE] = { 112 .id = I2S_HS_VIRTUAL_INSTANCE, 113 .name = "acp-sof-hs-virtual", 114 .playback = { 115 .rates = SNDRV_PCM_RATE_8000_96000, 116 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 117 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 118 .channels_min = 2, 119 .channels_max = 8, 120 .rate_min = 8000, 121 .rate_max = 96000, 122 }, 123 .capture = { 124 .rates = SNDRV_PCM_RATE_8000_48000, 125 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 126 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 127 /* Supporting only stereo for I2S HS-Virtual controller capture */ 128 .channels_min = 2, 129 .channels_max = 2, 130 .rate_min = 8000, 131 .rate_max = 48000, 132 }, 133 }, 134 }; 135 136 static int sof_vangogh_post_fw_run_delay(struct snd_sof_dev *sdev) 137 { 138 /* 139 * Resuming from suspend in some cases my cause the DSP firmware 140 * to enter an unrecoverable faulty state. Delaying a bit any host 141 * to DSP transmission right after firmware boot completion seems 142 * to resolve the issue. 143 */ 144 if (!sdev->first_boot) 145 usleep_range(100, 150); 146 147 return 0; 148 } 149 150 /* Vangogh ops */ 151 struct snd_sof_dsp_ops sof_vangogh_ops; 152 EXPORT_SYMBOL_NS(sof_vangogh_ops, "SND_SOC_SOF_AMD_COMMON"); 153 154 int sof_vangogh_ops_init(struct snd_sof_dev *sdev) 155 { 156 const struct dmi_system_id *dmi_id; 157 struct acp_quirk_entry *quirks; 158 159 /* common defaults */ 160 memcpy(&sof_vangogh_ops, &sof_acp_common_ops, sizeof(struct snd_sof_dsp_ops)); 161 162 sof_vangogh_ops.drv = vangogh_sof_dai; 163 sof_vangogh_ops.num_drv = ARRAY_SIZE(vangogh_sof_dai); 164 165 dmi_id = dmi_first_match(acp_sof_quirk_table); 166 if (dmi_id) { 167 quirks = dmi_id->driver_data; 168 169 if (quirks->signed_fw_image) 170 sof_vangogh_ops.load_firmware = acp_sof_load_signed_firmware; 171 172 if (quirks->post_fw_run_delay) 173 sof_vangogh_ops.post_fw_run = sof_vangogh_post_fw_run_delay; 174 } 175 176 return 0; 177 } 178