Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
0003 // Copyright (c) 2018, Linaro Limited
0004 
0005 #include <linux/slab.h>
0006 #include <linux/kernel.h>
0007 #include <linux/uaccess.h>
0008 #include <linux/wait.h>
0009 #include <linux/jiffies.h>
0010 #include <linux/sched.h>
0011 #include <linux/module.h>
0012 #include <linux/kref.h>
0013 #include <linux/of.h>
0014 #include <linux/of_platform.h>
0015 #include <linux/spinlock.h>
0016 #include <linux/delay.h>
0017 #include <linux/soc/qcom/apr.h>
0018 #include <sound/soc.h>
0019 #include <sound/soc-dai.h>
0020 #include <sound/pcm.h>
0021 #include <sound/pcm_params.h>
0022 #include "q6dsp-errno.h"
0023 #include "q6core.h"
0024 #include "q6afe.h"
0025 
0026 /* AFE CMDs */
0027 #define AFE_PORT_CMD_DEVICE_START   0x000100E5
0028 #define AFE_PORT_CMD_DEVICE_STOP    0x000100E6
0029 #define AFE_PORT_CMD_SET_PARAM_V2   0x000100EF
0030 #define AFE_SVC_CMD_SET_PARAM       0x000100f3
0031 #define AFE_PORT_CMDRSP_GET_PARAM_V2    0x00010106
0032 #define AFE_PARAM_ID_HDMI_CONFIG    0x00010210
0033 #define AFE_MODULE_AUDIO_DEV_INTERFACE  0x0001020C
0034 #define AFE_MODULE_TDM          0x0001028A
0035 
0036 #define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG 0x00010235
0037 
0038 #define AFE_PARAM_ID_LPAIF_CLK_CONFIG   0x00010238
0039 #define AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG 0x00010239
0040 
0041 #define AFE_PARAM_ID_SLIMBUS_CONFIG    0x00010212
0042 #define AFE_PARAM_ID_I2S_CONFIG 0x0001020D
0043 #define AFE_PARAM_ID_TDM_CONFIG 0x0001029D
0044 #define AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG   0x00010297
0045 #define AFE_PARAM_ID_CODEC_DMA_CONFIG   0x000102B8
0046 #define AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST   0x000100f4
0047 #define AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST   0x000100f5
0048 #define AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST 0x000100f6
0049 
0050 /* I2S config specific */
0051 #define AFE_API_VERSION_I2S_CONFIG  0x1
0052 #define AFE_PORT_I2S_SD0        0x1
0053 #define AFE_PORT_I2S_SD1        0x2
0054 #define AFE_PORT_I2S_SD2        0x3
0055 #define AFE_PORT_I2S_SD3        0x4
0056 #define AFE_PORT_I2S_SD0_MASK       BIT(0x0)
0057 #define AFE_PORT_I2S_SD1_MASK       BIT(0x1)
0058 #define AFE_PORT_I2S_SD2_MASK       BIT(0x2)
0059 #define AFE_PORT_I2S_SD3_MASK       BIT(0x3)
0060 #define AFE_PORT_I2S_SD0_1_MASK     GENMASK(1, 0)
0061 #define AFE_PORT_I2S_SD2_3_MASK     GENMASK(3, 2)
0062 #define AFE_PORT_I2S_SD0_1_2_MASK   GENMASK(2, 0)
0063 #define AFE_PORT_I2S_SD0_1_2_3_MASK GENMASK(3, 0)
0064 #define AFE_PORT_I2S_QUAD01     0x5
0065 #define AFE_PORT_I2S_QUAD23     0x6
0066 #define AFE_PORT_I2S_6CHS       0x7
0067 #define AFE_PORT_I2S_8CHS       0x8
0068 #define AFE_PORT_I2S_MONO       0x0
0069 #define AFE_PORT_I2S_STEREO     0x1
0070 #define AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL 0x0
0071 #define AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL 0x1
0072 #define AFE_LINEAR_PCM_DATA             0x0
0073 
0074 
0075 /* Port IDs */
0076 #define AFE_API_VERSION_HDMI_CONFIG 0x1
0077 #define AFE_PORT_ID_MULTICHAN_HDMI_RX   0x100E
0078 #define AFE_PORT_ID_HDMI_OVER_DP_RX 0x6020
0079 
0080 #define AFE_API_VERSION_SLIMBUS_CONFIG 0x1
0081 /* Clock set API version */
0082 #define AFE_API_VERSION_CLOCK_SET 1
0083 #define Q6AFE_LPASS_CLK_CONFIG_API_VERSION  0x1
0084 #define AFE_MODULE_CLOCK_SET        0x0001028F
0085 #define AFE_PARAM_ID_CLOCK_SET      0x00010290
0086 
0087 /* SLIMbus Rx port on channel 0. */
0088 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX      0x4000
0089 /* SLIMbus Tx port on channel 0. */
0090 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX      0x4001
0091 /* SLIMbus Rx port on channel 1. */
0092 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX      0x4002
0093 /* SLIMbus Tx port on channel 1. */
0094 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX      0x4003
0095 /* SLIMbus Rx port on channel 2. */
0096 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX      0x4004
0097 /* SLIMbus Tx port on channel 2. */
0098 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX      0x4005
0099 /* SLIMbus Rx port on channel 3. */
0100 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX      0x4006
0101 /* SLIMbus Tx port on channel 3. */
0102 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX      0x4007
0103 /* SLIMbus Rx port on channel 4. */
0104 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX      0x4008
0105 /* SLIMbus Tx port on channel 4. */
0106 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX      0x4009
0107 /* SLIMbus Rx port on channel 5. */
0108 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX      0x400a
0109 /* SLIMbus Tx port on channel 5. */
0110 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX      0x400b
0111 /* SLIMbus Rx port on channel 6. */
0112 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX      0x400c
0113 /* SLIMbus Tx port on channel 6. */
0114 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX      0x400d
0115 #define AFE_PORT_ID_PRIMARY_MI2S_RX         0x1000
0116 #define AFE_PORT_ID_PRIMARY_MI2S_TX         0x1001
0117 #define AFE_PORT_ID_SECONDARY_MI2S_RX       0x1002
0118 #define AFE_PORT_ID_SECONDARY_MI2S_TX       0x1003
0119 #define AFE_PORT_ID_TERTIARY_MI2S_RX        0x1004
0120 #define AFE_PORT_ID_TERTIARY_MI2S_TX        0x1005
0121 #define AFE_PORT_ID_QUATERNARY_MI2S_RX      0x1006
0122 #define AFE_PORT_ID_QUATERNARY_MI2S_TX      0x1007
0123 #define AFE_PORT_ID_QUINARY_MI2S_RX     0x1016
0124 #define AFE_PORT_ID_QUINARY_MI2S_TX     0x1017
0125 
0126 /* Start of the range of port IDs for TDM devices. */
0127 #define AFE_PORT_ID_TDM_PORT_RANGE_START    0x9000
0128 
0129 /* End of the range of port IDs for TDM devices. */
0130 #define AFE_PORT_ID_TDM_PORT_RANGE_END \
0131     (AFE_PORT_ID_TDM_PORT_RANGE_START+0x50-1)
0132 
0133 /* Size of the range of port IDs for TDM ports. */
0134 #define AFE_PORT_ID_TDM_PORT_RANGE_SIZE \
0135     (AFE_PORT_ID_TDM_PORT_RANGE_END - \
0136     AFE_PORT_ID_TDM_PORT_RANGE_START+1)
0137 
0138 #define AFE_PORT_ID_PRIMARY_TDM_RX \
0139     (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x00)
0140 #define AFE_PORT_ID_PRIMARY_TDM_RX_1 \
0141     (AFE_PORT_ID_PRIMARY_TDM_RX + 0x02)
0142 #define AFE_PORT_ID_PRIMARY_TDM_RX_2 \
0143     (AFE_PORT_ID_PRIMARY_TDM_RX + 0x04)
0144 #define AFE_PORT_ID_PRIMARY_TDM_RX_3 \
0145     (AFE_PORT_ID_PRIMARY_TDM_RX + 0x06)
0146 #define AFE_PORT_ID_PRIMARY_TDM_RX_4 \
0147     (AFE_PORT_ID_PRIMARY_TDM_RX + 0x08)
0148 #define AFE_PORT_ID_PRIMARY_TDM_RX_5 \
0149     (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0A)
0150 #define AFE_PORT_ID_PRIMARY_TDM_RX_6 \
0151     (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0C)
0152 #define AFE_PORT_ID_PRIMARY_TDM_RX_7 \
0153     (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0E)
0154 
0155 #define AFE_PORT_ID_PRIMARY_TDM_TX \
0156     (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x01)
0157 #define AFE_PORT_ID_PRIMARY_TDM_TX_1 \
0158     (AFE_PORT_ID_PRIMARY_TDM_TX + 0x02)
0159 #define AFE_PORT_ID_PRIMARY_TDM_TX_2 \
0160     (AFE_PORT_ID_PRIMARY_TDM_TX + 0x04)
0161 #define AFE_PORT_ID_PRIMARY_TDM_TX_3 \
0162     (AFE_PORT_ID_PRIMARY_TDM_TX + 0x06)
0163 #define AFE_PORT_ID_PRIMARY_TDM_TX_4 \
0164     (AFE_PORT_ID_PRIMARY_TDM_TX + 0x08)
0165 #define AFE_PORT_ID_PRIMARY_TDM_TX_5 \
0166     (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0A)
0167 #define AFE_PORT_ID_PRIMARY_TDM_TX_6 \
0168     (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0C)
0169 #define AFE_PORT_ID_PRIMARY_TDM_TX_7 \
0170     (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0E)
0171 
0172 #define AFE_PORT_ID_SECONDARY_TDM_RX \
0173     (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x10)
0174 #define AFE_PORT_ID_SECONDARY_TDM_RX_1 \
0175     (AFE_PORT_ID_SECONDARY_TDM_RX + 0x02)
0176 #define AFE_PORT_ID_SECONDARY_TDM_RX_2 \
0177     (AFE_PORT_ID_SECONDARY_TDM_RX + 0x04)
0178 #define AFE_PORT_ID_SECONDARY_TDM_RX_3 \
0179     (AFE_PORT_ID_SECONDARY_TDM_RX + 0x06)
0180 #define AFE_PORT_ID_SECONDARY_TDM_RX_4 \
0181     (AFE_PORT_ID_SECONDARY_TDM_RX + 0x08)
0182 #define AFE_PORT_ID_SECONDARY_TDM_RX_5 \
0183     (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0A)
0184 #define AFE_PORT_ID_SECONDARY_TDM_RX_6 \
0185     (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0C)
0186 #define AFE_PORT_ID_SECONDARY_TDM_RX_7 \
0187     (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0E)
0188 
0189 #define AFE_PORT_ID_SECONDARY_TDM_TX \
0190     (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x11)
0191 #define AFE_PORT_ID_SECONDARY_TDM_TX_1 \
0192     (AFE_PORT_ID_SECONDARY_TDM_TX + 0x02)
0193 #define AFE_PORT_ID_SECONDARY_TDM_TX_2 \
0194     (AFE_PORT_ID_SECONDARY_TDM_TX + 0x04)
0195 #define AFE_PORT_ID_SECONDARY_TDM_TX_3 \
0196     (AFE_PORT_ID_SECONDARY_TDM_TX + 0x06)
0197 #define AFE_PORT_ID_SECONDARY_TDM_TX_4 \
0198     (AFE_PORT_ID_SECONDARY_TDM_TX + 0x08)
0199 #define AFE_PORT_ID_SECONDARY_TDM_TX_5 \
0200     (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0A)
0201 #define AFE_PORT_ID_SECONDARY_TDM_TX_6 \
0202     (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0C)
0203 #define AFE_PORT_ID_SECONDARY_TDM_TX_7 \
0204     (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0E)
0205 
0206 #define AFE_PORT_ID_TERTIARY_TDM_RX \
0207     (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x20)
0208 #define AFE_PORT_ID_TERTIARY_TDM_RX_1 \
0209     (AFE_PORT_ID_TERTIARY_TDM_RX + 0x02)
0210 #define AFE_PORT_ID_TERTIARY_TDM_RX_2 \
0211     (AFE_PORT_ID_TERTIARY_TDM_RX + 0x04)
0212 #define AFE_PORT_ID_TERTIARY_TDM_RX_3 \
0213     (AFE_PORT_ID_TERTIARY_TDM_RX + 0x06)
0214 #define AFE_PORT_ID_TERTIARY_TDM_RX_4 \
0215     (AFE_PORT_ID_TERTIARY_TDM_RX + 0x08)
0216 #define AFE_PORT_ID_TERTIARY_TDM_RX_5 \
0217     (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0A)
0218 #define AFE_PORT_ID_TERTIARY_TDM_RX_6 \
0219     (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0C)
0220 #define AFE_PORT_ID_TERTIARY_TDM_RX_7 \
0221     (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0E)
0222 
0223 #define AFE_PORT_ID_TERTIARY_TDM_TX \
0224     (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x21)
0225 #define AFE_PORT_ID_TERTIARY_TDM_TX_1 \
0226     (AFE_PORT_ID_TERTIARY_TDM_TX + 0x02)
0227 #define AFE_PORT_ID_TERTIARY_TDM_TX_2 \
0228     (AFE_PORT_ID_TERTIARY_TDM_TX + 0x04)
0229 #define AFE_PORT_ID_TERTIARY_TDM_TX_3 \
0230     (AFE_PORT_ID_TERTIARY_TDM_TX + 0x06)
0231 #define AFE_PORT_ID_TERTIARY_TDM_TX_4 \
0232     (AFE_PORT_ID_TERTIARY_TDM_TX + 0x08)
0233 #define AFE_PORT_ID_TERTIARY_TDM_TX_5 \
0234     (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0A)
0235 #define AFE_PORT_ID_TERTIARY_TDM_TX_6 \
0236     (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0C)
0237 #define AFE_PORT_ID_TERTIARY_TDM_TX_7 \
0238     (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0E)
0239 
0240 #define AFE_PORT_ID_QUATERNARY_TDM_RX \
0241     (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x30)
0242 #define AFE_PORT_ID_QUATERNARY_TDM_RX_1 \
0243     (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x02)
0244 #define AFE_PORT_ID_QUATERNARY_TDM_RX_2 \
0245     (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x04)
0246 #define AFE_PORT_ID_QUATERNARY_TDM_RX_3 \
0247     (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x06)
0248 #define AFE_PORT_ID_QUATERNARY_TDM_RX_4 \
0249     (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x08)
0250 #define AFE_PORT_ID_QUATERNARY_TDM_RX_5 \
0251     (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0A)
0252 #define AFE_PORT_ID_QUATERNARY_TDM_RX_6 \
0253     (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0C)
0254 #define AFE_PORT_ID_QUATERNARY_TDM_RX_7 \
0255     (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0E)
0256 
0257 #define AFE_PORT_ID_QUATERNARY_TDM_TX \
0258     (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x31)
0259 #define AFE_PORT_ID_QUATERNARY_TDM_TX_1 \
0260     (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x02)
0261 #define AFE_PORT_ID_QUATERNARY_TDM_TX_2 \
0262     (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x04)
0263 #define AFE_PORT_ID_QUATERNARY_TDM_TX_3 \
0264     (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x06)
0265 #define AFE_PORT_ID_QUATERNARY_TDM_TX_4 \
0266     (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x08)
0267 #define AFE_PORT_ID_QUATERNARY_TDM_TX_5 \
0268     (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0A)
0269 #define AFE_PORT_ID_QUATERNARY_TDM_TX_6 \
0270     (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0C)
0271 #define AFE_PORT_ID_QUATERNARY_TDM_TX_7 \
0272     (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0E)
0273 
0274 #define AFE_PORT_ID_QUINARY_TDM_RX \
0275     (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x40)
0276 #define AFE_PORT_ID_QUINARY_TDM_RX_1 \
0277     (AFE_PORT_ID_QUINARY_TDM_RX + 0x02)
0278 #define AFE_PORT_ID_QUINARY_TDM_RX_2 \
0279     (AFE_PORT_ID_QUINARY_TDM_RX + 0x04)
0280 #define AFE_PORT_ID_QUINARY_TDM_RX_3 \
0281     (AFE_PORT_ID_QUINARY_TDM_RX + 0x06)
0282 #define AFE_PORT_ID_QUINARY_TDM_RX_4 \
0283     (AFE_PORT_ID_QUINARY_TDM_RX + 0x08)
0284 #define AFE_PORT_ID_QUINARY_TDM_RX_5 \
0285     (AFE_PORT_ID_QUINARY_TDM_RX + 0x0A)
0286 #define AFE_PORT_ID_QUINARY_TDM_RX_6 \
0287     (AFE_PORT_ID_QUINARY_TDM_RX + 0x0C)
0288 #define AFE_PORT_ID_QUINARY_TDM_RX_7 \
0289     (AFE_PORT_ID_QUINARY_TDM_RX + 0x0E)
0290 
0291 #define AFE_PORT_ID_QUINARY_TDM_TX \
0292     (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x41)
0293 #define AFE_PORT_ID_QUINARY_TDM_TX_1 \
0294     (AFE_PORT_ID_QUINARY_TDM_TX + 0x02)
0295 #define AFE_PORT_ID_QUINARY_TDM_TX_2 \
0296     (AFE_PORT_ID_QUINARY_TDM_TX + 0x04)
0297 #define AFE_PORT_ID_QUINARY_TDM_TX_3 \
0298     (AFE_PORT_ID_QUINARY_TDM_TX + 0x06)
0299 #define AFE_PORT_ID_QUINARY_TDM_TX_4 \
0300     (AFE_PORT_ID_QUINARY_TDM_TX + 0x08)
0301 #define AFE_PORT_ID_QUINARY_TDM_TX_5 \
0302     (AFE_PORT_ID_QUINARY_TDM_TX + 0x0A)
0303 #define AFE_PORT_ID_QUINARY_TDM_TX_6 \
0304     (AFE_PORT_ID_QUINARY_TDM_TX + 0x0C)
0305 #define AFE_PORT_ID_QUINARY_TDM_TX_7 \
0306     (AFE_PORT_ID_QUINARY_TDM_TX + 0x0E)
0307 
0308 /* AFE WSA Codec DMA Rx port 0 */
0309 #define AFE_PORT_ID_WSA_CODEC_DMA_RX_0  0xB000
0310 /* AFE WSA Codec DMA Tx port 0 */
0311 #define AFE_PORT_ID_WSA_CODEC_DMA_TX_0  0xB001
0312 /* AFE WSA Codec DMA Rx port 1 */
0313 #define AFE_PORT_ID_WSA_CODEC_DMA_RX_1  0xB002
0314 /* AFE WSA Codec DMA Tx port 1 */
0315 #define AFE_PORT_ID_WSA_CODEC_DMA_TX_1  0xB003
0316 /* AFE WSA Codec DMA Tx port 2 */
0317 #define AFE_PORT_ID_WSA_CODEC_DMA_TX_2  0xB005
0318 /* AFE VA Codec DMA Tx port 0 */
0319 #define AFE_PORT_ID_VA_CODEC_DMA_TX_0   0xB021
0320 /* AFE VA Codec DMA Tx port 1 */
0321 #define AFE_PORT_ID_VA_CODEC_DMA_TX_1   0xB023
0322 /* AFE VA Codec DMA Tx port 2 */
0323 #define AFE_PORT_ID_VA_CODEC_DMA_TX_2   0xB025
0324 /* AFE Rx Codec DMA Rx port 0 */
0325 #define AFE_PORT_ID_RX_CODEC_DMA_RX_0   0xB030
0326 /* AFE Tx Codec DMA Tx port 0 */
0327 #define AFE_PORT_ID_TX_CODEC_DMA_TX_0   0xB031
0328 /* AFE Rx Codec DMA Rx port 1 */
0329 #define AFE_PORT_ID_RX_CODEC_DMA_RX_1   0xB032
0330 /* AFE Tx Codec DMA Tx port 1 */
0331 #define AFE_PORT_ID_TX_CODEC_DMA_TX_1   0xB033
0332 /* AFE Rx Codec DMA Rx port 2 */
0333 #define AFE_PORT_ID_RX_CODEC_DMA_RX_2   0xB034
0334 /* AFE Tx Codec DMA Tx port 2 */
0335 #define AFE_PORT_ID_TX_CODEC_DMA_TX_2   0xB035
0336 /* AFE Rx Codec DMA Rx port 3 */
0337 #define AFE_PORT_ID_RX_CODEC_DMA_RX_3   0xB036
0338 /* AFE Tx Codec DMA Tx port 3 */
0339 #define AFE_PORT_ID_TX_CODEC_DMA_TX_3   0xB037
0340 /* AFE Rx Codec DMA Rx port 4 */
0341 #define AFE_PORT_ID_RX_CODEC_DMA_RX_4   0xB038
0342 /* AFE Tx Codec DMA Tx port 4 */
0343 #define AFE_PORT_ID_TX_CODEC_DMA_TX_4   0xB039
0344 /* AFE Rx Codec DMA Rx port 5 */
0345 #define AFE_PORT_ID_RX_CODEC_DMA_RX_5   0xB03A
0346 /* AFE Tx Codec DMA Tx port 5 */
0347 #define AFE_PORT_ID_TX_CODEC_DMA_TX_5   0xB03B
0348 /* AFE Rx Codec DMA Rx port 6 */
0349 #define AFE_PORT_ID_RX_CODEC_DMA_RX_6   0xB03C
0350 /* AFE Rx Codec DMA Rx port 7 */
0351 #define AFE_PORT_ID_RX_CODEC_DMA_RX_7   0xB03E
0352 
0353 #define Q6AFE_LPASS_MODE_CLK1_VALID 1
0354 #define Q6AFE_LPASS_MODE_CLK2_VALID 2
0355 #define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
0356 #define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0
0357 #define AFE_API_VERSION_TDM_CONFIG              1
0358 #define AFE_API_VERSION_SLOT_MAPPING_CONFIG 1
0359 #define AFE_API_VERSION_CODEC_DMA_CONFIG    1
0360 
0361 #define TIMEOUT_MS 1000
0362 #define AFE_CMD_RESP_AVAIL  0
0363 #define AFE_CMD_RESP_NONE   1
0364 #define AFE_CLK_TOKEN       1024
0365 
0366 struct q6afe {
0367     struct apr_device *apr;
0368     struct device *dev;
0369     struct q6core_svc_api_info ainfo;
0370     struct mutex lock;
0371     struct aprv2_ibasic_rsp_result_t result;
0372     wait_queue_head_t wait;
0373     struct list_head port_list;
0374     spinlock_t port_list_lock;
0375 };
0376 
0377 struct afe_port_cmd_device_start {
0378     u16 port_id;
0379     u16 reserved;
0380 } __packed;
0381 
0382 struct afe_port_cmd_device_stop {
0383     u16 port_id;
0384     u16 reserved;
0385 /* Reserved for 32-bit alignment. This field must be set to 0.*/
0386 } __packed;
0387 
0388 struct afe_port_param_data_v2 {
0389     u32 module_id;
0390     u32 param_id;
0391     u16 param_size;
0392     u16 reserved;
0393 } __packed;
0394 
0395 struct afe_svc_cmd_set_param {
0396     uint32_t payload_size;
0397     uint32_t payload_address_lsw;
0398     uint32_t payload_address_msw;
0399     uint32_t mem_map_handle;
0400 } __packed;
0401 
0402 struct afe_port_cmd_set_param_v2 {
0403     u16 port_id;
0404     u16 payload_size;
0405     u32 payload_address_lsw;
0406     u32 payload_address_msw;
0407     u32 mem_map_handle;
0408 } __packed;
0409 
0410 struct afe_param_id_hdmi_multi_chan_audio_cfg {
0411     u32 hdmi_cfg_minor_version;
0412     u16 datatype;
0413     u16 channel_allocation;
0414     u32 sample_rate;
0415     u16 bit_width;
0416     u16 reserved;
0417 } __packed;
0418 
0419 struct afe_param_id_slimbus_cfg {
0420     u32                  sb_cfg_minor_version;
0421 /* Minor version used for tracking the version of the SLIMBUS
0422  * configuration interface.
0423  * Supported values: #AFE_API_VERSION_SLIMBUS_CONFIG
0424  */
0425 
0426     u16                  slimbus_dev_id;
0427 /* SLIMbus hardware device ID, which is required to handle
0428  * multiple SLIMbus hardware blocks.
0429  * Supported values: - #AFE_SLIMBUS_DEVICE_1 - #AFE_SLIMBUS_DEVICE_2
0430  */
0431     u16                  bit_width;
0432 /* Bit width of the sample.
0433  * Supported values: 16, 24
0434  */
0435     u16                  data_format;
0436 /* Data format supported by the SLIMbus hardware. The default is
0437  * 0 (#AFE_SB_DATA_FORMAT_NOT_INDICATED), which indicates the
0438  * hardware does not perform any format conversions before the data
0439  * transfer.
0440  */
0441     u16                  num_channels;
0442 /* Number of channels.
0443  * Supported values: 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT
0444  */
0445     u8  shared_ch_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT];
0446 /* Mapping of shared channel IDs (128 to 255) to which the
0447  * master port is to be connected.
0448  * Shared_channel_mapping[i] represents the shared channel assigned
0449  * for audio channel i in multichannel audio data.
0450  */
0451     u32              sample_rate;
0452 /* Sampling rate of the port.
0453  * Supported values:
0454  * - #AFE_PORT_SAMPLE_RATE_8K
0455  * - #AFE_PORT_SAMPLE_RATE_16K
0456  * - #AFE_PORT_SAMPLE_RATE_48K
0457  * - #AFE_PORT_SAMPLE_RATE_96K
0458  * - #AFE_PORT_SAMPLE_RATE_192K
0459  */
0460 } __packed;
0461 
0462 struct afe_clk_cfg {
0463     u32                  i2s_cfg_minor_version;
0464     u32                  clk_val1;
0465     u32                  clk_val2;
0466     u16                  clk_src;
0467     u16                  clk_root;
0468     u16                  clk_set_mode;
0469     u16                  reserved;
0470 } __packed;
0471 
0472 struct afe_digital_clk_cfg {
0473     u32                  i2s_cfg_minor_version;
0474     u32                  clk_val;
0475     u16                  clk_root;
0476     u16                  reserved;
0477 } __packed;
0478 
0479 struct afe_param_id_i2s_cfg {
0480     u32 i2s_cfg_minor_version;
0481     u16 bit_width;
0482     u16 channel_mode;
0483     u16 mono_stereo;
0484     u16 ws_src;
0485     u32 sample_rate;
0486     u16 data_format;
0487     u16 reserved;
0488 } __packed;
0489 
0490 struct afe_param_id_tdm_cfg {
0491     u32 tdm_cfg_minor_version;
0492     u32 num_channels;
0493     u32 sample_rate;
0494     u32 bit_width;
0495     u16 data_format;
0496     u16 sync_mode;
0497     u16 sync_src;
0498     u16 nslots_per_frame;
0499     u16 ctrl_data_out_enable;
0500     u16 ctrl_invert_sync_pulse;
0501     u16 ctrl_sync_data_delay;
0502     u16 slot_width;
0503     u32 slot_mask;
0504 } __packed;
0505 
0506 struct afe_param_id_cdc_dma_cfg {
0507     u32 cdc_dma_cfg_minor_version;
0508     u32 sample_rate;
0509     u16 bit_width;
0510     u16 data_format;
0511     u16 num_channels;
0512     u16 active_channels_mask;
0513 } __packed;
0514 
0515 union afe_port_config {
0516     struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch;
0517     struct afe_param_id_slimbus_cfg           slim_cfg;
0518     struct afe_param_id_i2s_cfg i2s_cfg;
0519     struct afe_param_id_tdm_cfg tdm_cfg;
0520     struct afe_param_id_cdc_dma_cfg dma_cfg;
0521 } __packed;
0522 
0523 
0524 struct afe_clk_set {
0525     uint32_t clk_set_minor_version;
0526     uint32_t clk_id;
0527     uint32_t clk_freq_in_hz;
0528     uint16_t clk_attri;
0529     uint16_t clk_root;
0530     uint32_t enable;
0531 };
0532 
0533 struct afe_param_id_slot_mapping_cfg {
0534     u32 minor_version;
0535     u16 num_channels;
0536     u16 bitwidth;
0537     u32 data_align_type;
0538     u16 ch_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT];
0539 } __packed;
0540 
0541 struct q6afe_port {
0542     wait_queue_head_t wait;
0543     union afe_port_config port_cfg;
0544     struct afe_param_id_slot_mapping_cfg *scfg;
0545     struct aprv2_ibasic_rsp_result_t result;
0546     int token;
0547     int id;
0548     int cfg_type;
0549     struct q6afe *afe;
0550     struct kref refcount;
0551     struct list_head node;
0552 };
0553 
0554 struct afe_cmd_remote_lpass_core_hw_vote_request {
0555         uint32_t  hw_block_id;
0556         char client_name[8];
0557 } __packed;
0558 
0559 struct afe_cmd_remote_lpass_core_hw_devote_request {
0560         uint32_t  hw_block_id;
0561         uint32_t client_handle;
0562 } __packed;
0563 
0564 
0565 
0566 struct afe_port_map {
0567     int port_id;
0568     int token;
0569     int is_rx;
0570     int is_dig_pcm;
0571 };
0572 
0573 /*
0574  * Mapping between Virtual Port IDs to DSP AFE Port ID
0575  * On B Family SoCs DSP Port IDs are consistent across multiple SoCs
0576  * on A Family SoCs DSP port IDs are same as virtual Port IDs.
0577  */
0578 
0579 static struct afe_port_map port_maps[AFE_PORT_MAX] = {
0580     [HDMI_RX] = { AFE_PORT_ID_MULTICHAN_HDMI_RX, HDMI_RX, 1, 1},
0581     [SLIMBUS_0_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX,
0582                 SLIMBUS_0_RX, 1, 1},
0583     [SLIMBUS_1_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX,
0584                 SLIMBUS_1_RX, 1, 1},
0585     [SLIMBUS_2_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX,
0586                 SLIMBUS_2_RX, 1, 1},
0587     [SLIMBUS_3_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX,
0588                 SLIMBUS_3_RX, 1, 1},
0589     [SLIMBUS_4_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX,
0590                 SLIMBUS_4_RX, 1, 1},
0591     [SLIMBUS_5_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX,
0592                 SLIMBUS_5_RX, 1, 1},
0593     [SLIMBUS_6_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX,
0594                 SLIMBUS_6_RX, 1, 1},
0595     [SLIMBUS_0_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX,
0596                 SLIMBUS_0_TX, 0, 1},
0597     [SLIMBUS_1_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX,
0598                 SLIMBUS_1_TX, 0, 1},
0599     [SLIMBUS_2_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX,
0600                 SLIMBUS_2_TX, 0, 1},
0601     [SLIMBUS_3_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX,
0602                 SLIMBUS_3_TX, 0, 1},
0603     [SLIMBUS_4_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX,
0604                 SLIMBUS_4_TX, 0, 1},
0605     [SLIMBUS_5_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX,
0606                 SLIMBUS_5_TX, 0, 1},
0607     [SLIMBUS_6_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX,
0608                 SLIMBUS_6_TX, 0, 1},
0609     [PRIMARY_MI2S_RX] = { AFE_PORT_ID_PRIMARY_MI2S_RX,
0610                 PRIMARY_MI2S_RX, 1, 1},
0611     [PRIMARY_MI2S_TX] = { AFE_PORT_ID_PRIMARY_MI2S_TX,
0612                 PRIMARY_MI2S_RX, 0, 1},
0613     [SECONDARY_MI2S_RX] = { AFE_PORT_ID_SECONDARY_MI2S_RX,
0614                 SECONDARY_MI2S_RX, 1, 1},
0615     [SECONDARY_MI2S_TX] = { AFE_PORT_ID_SECONDARY_MI2S_TX,
0616                 SECONDARY_MI2S_TX, 0, 1},
0617     [TERTIARY_MI2S_RX] = { AFE_PORT_ID_TERTIARY_MI2S_RX,
0618                 TERTIARY_MI2S_RX, 1, 1},
0619     [TERTIARY_MI2S_TX] = { AFE_PORT_ID_TERTIARY_MI2S_TX,
0620                 TERTIARY_MI2S_TX, 0, 1},
0621     [QUATERNARY_MI2S_RX] = { AFE_PORT_ID_QUATERNARY_MI2S_RX,
0622                 QUATERNARY_MI2S_RX, 1, 1},
0623     [QUATERNARY_MI2S_TX] = { AFE_PORT_ID_QUATERNARY_MI2S_TX,
0624                 QUATERNARY_MI2S_TX, 0, 1},
0625     [QUINARY_MI2S_RX]  =  { AFE_PORT_ID_QUINARY_MI2S_RX,
0626                 QUINARY_MI2S_RX, 1, 1},
0627     [QUINARY_MI2S_TX] =   { AFE_PORT_ID_QUINARY_MI2S_TX,
0628                 QUINARY_MI2S_TX, 0, 1},
0629     [PRIMARY_TDM_RX_0] =  { AFE_PORT_ID_PRIMARY_TDM_RX,
0630                 PRIMARY_TDM_RX_0, 1, 1},
0631     [PRIMARY_TDM_TX_0] =  { AFE_PORT_ID_PRIMARY_TDM_TX,
0632                 PRIMARY_TDM_TX_0, 0, 1},
0633     [PRIMARY_TDM_RX_1] =  { AFE_PORT_ID_PRIMARY_TDM_RX_1,
0634                 PRIMARY_TDM_RX_1, 1, 1},
0635     [PRIMARY_TDM_TX_1] =  { AFE_PORT_ID_PRIMARY_TDM_TX_1,
0636                 PRIMARY_TDM_TX_1, 0, 1},
0637     [PRIMARY_TDM_RX_2] =  { AFE_PORT_ID_PRIMARY_TDM_RX_2,
0638                 PRIMARY_TDM_RX_2, 1, 1},
0639     [PRIMARY_TDM_TX_2] =  { AFE_PORT_ID_PRIMARY_TDM_TX_2,
0640                 PRIMARY_TDM_TX_2, 0, 1},
0641     [PRIMARY_TDM_RX_3] =  { AFE_PORT_ID_PRIMARY_TDM_RX_3,
0642                 PRIMARY_TDM_RX_3, 1, 1},
0643     [PRIMARY_TDM_TX_3] =  { AFE_PORT_ID_PRIMARY_TDM_TX_3,
0644                 PRIMARY_TDM_TX_3, 0, 1},
0645     [PRIMARY_TDM_RX_4] =  { AFE_PORT_ID_PRIMARY_TDM_RX_4,
0646                 PRIMARY_TDM_RX_4, 1, 1},
0647     [PRIMARY_TDM_TX_4] =  { AFE_PORT_ID_PRIMARY_TDM_TX_4,
0648                 PRIMARY_TDM_TX_4, 0, 1},
0649     [PRIMARY_TDM_RX_5] =  { AFE_PORT_ID_PRIMARY_TDM_RX_5,
0650                 PRIMARY_TDM_RX_5, 1, 1},
0651     [PRIMARY_TDM_TX_5] =  { AFE_PORT_ID_PRIMARY_TDM_TX_5,
0652                 PRIMARY_TDM_TX_5, 0, 1},
0653     [PRIMARY_TDM_RX_6] =  { AFE_PORT_ID_PRIMARY_TDM_RX_6,
0654                 PRIMARY_TDM_RX_6, 1, 1},
0655     [PRIMARY_TDM_TX_6] =  { AFE_PORT_ID_PRIMARY_TDM_TX_6,
0656                 PRIMARY_TDM_TX_6, 0, 1},
0657     [PRIMARY_TDM_RX_7] =  { AFE_PORT_ID_PRIMARY_TDM_RX_7,
0658                 PRIMARY_TDM_RX_7, 1, 1},
0659     [PRIMARY_TDM_TX_7] =  { AFE_PORT_ID_PRIMARY_TDM_TX_7,
0660                 PRIMARY_TDM_TX_7, 0, 1},
0661     [SECONDARY_TDM_RX_0] =  { AFE_PORT_ID_SECONDARY_TDM_RX,
0662                 SECONDARY_TDM_RX_0, 1, 1},
0663     [SECONDARY_TDM_TX_0] =  { AFE_PORT_ID_SECONDARY_TDM_TX,
0664                 SECONDARY_TDM_TX_0, 0, 1},
0665     [SECONDARY_TDM_RX_1] =  { AFE_PORT_ID_SECONDARY_TDM_RX_1,
0666                 SECONDARY_TDM_RX_1, 1, 1},
0667     [SECONDARY_TDM_TX_1] =  { AFE_PORT_ID_SECONDARY_TDM_TX_1,
0668                 SECONDARY_TDM_TX_1, 0, 1},
0669     [SECONDARY_TDM_RX_2] =  { AFE_PORT_ID_SECONDARY_TDM_RX_2,
0670                 SECONDARY_TDM_RX_2, 1, 1},
0671     [SECONDARY_TDM_TX_2] =  { AFE_PORT_ID_SECONDARY_TDM_TX_2,
0672                 SECONDARY_TDM_TX_2, 0, 1},
0673     [SECONDARY_TDM_RX_3] =  { AFE_PORT_ID_SECONDARY_TDM_RX_3,
0674                 SECONDARY_TDM_RX_3, 1, 1},
0675     [SECONDARY_TDM_TX_3] =  { AFE_PORT_ID_SECONDARY_TDM_TX_3,
0676                 SECONDARY_TDM_TX_3, 0, 1},
0677     [SECONDARY_TDM_RX_4] =  { AFE_PORT_ID_SECONDARY_TDM_RX_4,
0678                 SECONDARY_TDM_RX_4, 1, 1},
0679     [SECONDARY_TDM_TX_4] =  { AFE_PORT_ID_SECONDARY_TDM_TX_4,
0680                 SECONDARY_TDM_TX_4, 0, 1},
0681     [SECONDARY_TDM_RX_5] =  { AFE_PORT_ID_SECONDARY_TDM_RX_5,
0682                 SECONDARY_TDM_RX_5, 1, 1},
0683     [SECONDARY_TDM_TX_5] =  { AFE_PORT_ID_SECONDARY_TDM_TX_5,
0684                 SECONDARY_TDM_TX_5, 0, 1},
0685     [SECONDARY_TDM_RX_6] =  { AFE_PORT_ID_SECONDARY_TDM_RX_6,
0686                 SECONDARY_TDM_RX_6, 1, 1},
0687     [SECONDARY_TDM_TX_6] =  { AFE_PORT_ID_SECONDARY_TDM_TX_6,
0688                 SECONDARY_TDM_TX_6, 0, 1},
0689     [SECONDARY_TDM_RX_7] =  { AFE_PORT_ID_SECONDARY_TDM_RX_7,
0690                 SECONDARY_TDM_RX_7, 1, 1},
0691     [SECONDARY_TDM_TX_7] =  { AFE_PORT_ID_SECONDARY_TDM_TX_7,
0692                 SECONDARY_TDM_TX_7, 0, 1},
0693     [TERTIARY_TDM_RX_0] =  { AFE_PORT_ID_TERTIARY_TDM_RX,
0694                 TERTIARY_TDM_RX_0, 1, 1},
0695     [TERTIARY_TDM_TX_0] =  { AFE_PORT_ID_TERTIARY_TDM_TX,
0696                 TERTIARY_TDM_TX_0, 0, 1},
0697     [TERTIARY_TDM_RX_1] =  { AFE_PORT_ID_TERTIARY_TDM_RX_1,
0698                 TERTIARY_TDM_RX_1, 1, 1},
0699     [TERTIARY_TDM_TX_1] =  { AFE_PORT_ID_TERTIARY_TDM_TX_1,
0700                 TERTIARY_TDM_TX_1, 0, 1},
0701     [TERTIARY_TDM_RX_2] =  { AFE_PORT_ID_TERTIARY_TDM_RX_2,
0702                 TERTIARY_TDM_RX_2, 1, 1},
0703     [TERTIARY_TDM_TX_2] =  { AFE_PORT_ID_TERTIARY_TDM_TX_2,
0704                 TERTIARY_TDM_TX_2, 0, 1},
0705     [TERTIARY_TDM_RX_3] =  { AFE_PORT_ID_TERTIARY_TDM_RX_3,
0706                 TERTIARY_TDM_RX_3, 1, 1},
0707     [TERTIARY_TDM_TX_3] =  { AFE_PORT_ID_TERTIARY_TDM_TX_3,
0708                 TERTIARY_TDM_TX_3, 0, 1},
0709     [TERTIARY_TDM_RX_4] =  { AFE_PORT_ID_TERTIARY_TDM_RX_4,
0710                 TERTIARY_TDM_RX_4, 1, 1},
0711     [TERTIARY_TDM_TX_4] =  { AFE_PORT_ID_TERTIARY_TDM_TX_4,
0712                 TERTIARY_TDM_TX_4, 0, 1},
0713     [TERTIARY_TDM_RX_5] =  { AFE_PORT_ID_TERTIARY_TDM_RX_5,
0714                 TERTIARY_TDM_RX_5, 1, 1},
0715     [TERTIARY_TDM_TX_5] =  { AFE_PORT_ID_TERTIARY_TDM_TX_5,
0716                 TERTIARY_TDM_TX_5, 0, 1},
0717     [TERTIARY_TDM_RX_6] =  { AFE_PORT_ID_TERTIARY_TDM_RX_6,
0718                 TERTIARY_TDM_RX_6, 1, 1},
0719     [TERTIARY_TDM_TX_6] =  { AFE_PORT_ID_TERTIARY_TDM_TX_6,
0720                 TERTIARY_TDM_TX_6, 0, 1},
0721     [TERTIARY_TDM_RX_7] =  { AFE_PORT_ID_TERTIARY_TDM_RX_7,
0722                 TERTIARY_TDM_RX_7, 1, 1},
0723     [TERTIARY_TDM_TX_7] =  { AFE_PORT_ID_TERTIARY_TDM_TX_7,
0724                 TERTIARY_TDM_TX_7, 0, 1},
0725     [QUATERNARY_TDM_RX_0] =  { AFE_PORT_ID_QUATERNARY_TDM_RX,
0726                 QUATERNARY_TDM_RX_0, 1, 1},
0727     [QUATERNARY_TDM_TX_0] =  { AFE_PORT_ID_QUATERNARY_TDM_TX,
0728                 QUATERNARY_TDM_TX_0, 0, 1},
0729     [QUATERNARY_TDM_RX_1] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_1,
0730                 QUATERNARY_TDM_RX_1, 1, 1},
0731     [QUATERNARY_TDM_TX_1] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_1,
0732                 QUATERNARY_TDM_TX_1, 0, 1},
0733     [QUATERNARY_TDM_RX_2] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_2,
0734                 QUATERNARY_TDM_RX_2, 1, 1},
0735     [QUATERNARY_TDM_TX_2] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_2,
0736                 QUATERNARY_TDM_TX_2, 0, 1},
0737     [QUATERNARY_TDM_RX_3] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_3,
0738                 QUATERNARY_TDM_RX_3, 1, 1},
0739     [QUATERNARY_TDM_TX_3] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_3,
0740                 QUATERNARY_TDM_TX_3, 0, 1},
0741     [QUATERNARY_TDM_RX_4] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_4,
0742                 QUATERNARY_TDM_RX_4, 1, 1},
0743     [QUATERNARY_TDM_TX_4] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_4,
0744                 QUATERNARY_TDM_TX_4, 0, 1},
0745     [QUATERNARY_TDM_RX_5] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_5,
0746                 QUATERNARY_TDM_RX_5, 1, 1},
0747     [QUATERNARY_TDM_TX_5] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_5,
0748                 QUATERNARY_TDM_TX_5, 0, 1},
0749     [QUATERNARY_TDM_RX_6] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_6,
0750                 QUATERNARY_TDM_RX_6, 1, 1},
0751     [QUATERNARY_TDM_TX_6] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_6,
0752                 QUATERNARY_TDM_TX_6, 0, 1},
0753     [QUATERNARY_TDM_RX_7] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_7,
0754                 QUATERNARY_TDM_RX_7, 1, 1},
0755     [QUATERNARY_TDM_TX_7] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_7,
0756                 QUATERNARY_TDM_TX_7, 0, 1},
0757     [QUINARY_TDM_RX_0] =  { AFE_PORT_ID_QUINARY_TDM_RX,
0758                 QUINARY_TDM_RX_0, 1, 1},
0759     [QUINARY_TDM_TX_0] =  { AFE_PORT_ID_QUINARY_TDM_TX,
0760                 QUINARY_TDM_TX_0, 0, 1},
0761     [QUINARY_TDM_RX_1] =  { AFE_PORT_ID_QUINARY_TDM_RX_1,
0762                 QUINARY_TDM_RX_1, 1, 1},
0763     [QUINARY_TDM_TX_1] =  { AFE_PORT_ID_QUINARY_TDM_TX_1,
0764                 QUINARY_TDM_TX_1, 0, 1},
0765     [QUINARY_TDM_RX_2] =  { AFE_PORT_ID_QUINARY_TDM_RX_2,
0766                 QUINARY_TDM_RX_2, 1, 1},
0767     [QUINARY_TDM_TX_2] =  { AFE_PORT_ID_QUINARY_TDM_TX_2,
0768                 QUINARY_TDM_TX_2, 0, 1},
0769     [QUINARY_TDM_RX_3] =  { AFE_PORT_ID_QUINARY_TDM_RX_3,
0770                 QUINARY_TDM_RX_3, 1, 1},
0771     [QUINARY_TDM_TX_3] =  { AFE_PORT_ID_QUINARY_TDM_TX_3,
0772                 QUINARY_TDM_TX_3, 0, 1},
0773     [QUINARY_TDM_RX_4] =  { AFE_PORT_ID_QUINARY_TDM_RX_4,
0774                 QUINARY_TDM_RX_4, 1, 1},
0775     [QUINARY_TDM_TX_4] =  { AFE_PORT_ID_QUINARY_TDM_TX_4,
0776                 QUINARY_TDM_TX_4, 0, 1},
0777     [QUINARY_TDM_RX_5] =  { AFE_PORT_ID_QUINARY_TDM_RX_5,
0778                 QUINARY_TDM_RX_5, 1, 1},
0779     [QUINARY_TDM_TX_5] =  { AFE_PORT_ID_QUINARY_TDM_TX_5,
0780                 QUINARY_TDM_TX_5, 0, 1},
0781     [QUINARY_TDM_RX_6] =  { AFE_PORT_ID_QUINARY_TDM_RX_6,
0782                 QUINARY_TDM_RX_6, 1, 1},
0783     [QUINARY_TDM_TX_6] =  { AFE_PORT_ID_QUINARY_TDM_TX_6,
0784                 QUINARY_TDM_TX_6, 0, 1},
0785     [QUINARY_TDM_RX_7] =  { AFE_PORT_ID_QUINARY_TDM_RX_7,
0786                 QUINARY_TDM_RX_7, 1, 1},
0787     [QUINARY_TDM_TX_7] =  { AFE_PORT_ID_QUINARY_TDM_TX_7,
0788                 QUINARY_TDM_TX_7, 0, 1},
0789     [DISPLAY_PORT_RX] = { AFE_PORT_ID_HDMI_OVER_DP_RX,
0790                 DISPLAY_PORT_RX, 1, 1},
0791     [WSA_CODEC_DMA_RX_0] = { AFE_PORT_ID_WSA_CODEC_DMA_RX_0,
0792                 WSA_CODEC_DMA_RX_0, 1, 1},
0793     [WSA_CODEC_DMA_TX_0] = { AFE_PORT_ID_WSA_CODEC_DMA_TX_0,
0794                 WSA_CODEC_DMA_TX_0, 0, 1},
0795     [WSA_CODEC_DMA_RX_1] = { AFE_PORT_ID_WSA_CODEC_DMA_RX_1,
0796                 WSA_CODEC_DMA_RX_1, 1, 1},
0797     [WSA_CODEC_DMA_TX_1] = { AFE_PORT_ID_WSA_CODEC_DMA_TX_1,
0798                 WSA_CODEC_DMA_TX_1, 0, 1},
0799     [WSA_CODEC_DMA_TX_2] = { AFE_PORT_ID_WSA_CODEC_DMA_TX_2,
0800                 WSA_CODEC_DMA_TX_2, 0, 1},
0801     [VA_CODEC_DMA_TX_0] = { AFE_PORT_ID_VA_CODEC_DMA_TX_0,
0802                 VA_CODEC_DMA_TX_0, 0, 1},
0803     [VA_CODEC_DMA_TX_1] = { AFE_PORT_ID_VA_CODEC_DMA_TX_1,
0804                 VA_CODEC_DMA_TX_1, 0, 1},
0805     [VA_CODEC_DMA_TX_2] = { AFE_PORT_ID_VA_CODEC_DMA_TX_2,
0806                 VA_CODEC_DMA_TX_2, 0, 1},
0807     [RX_CODEC_DMA_RX_0] = { AFE_PORT_ID_RX_CODEC_DMA_RX_0,
0808                 RX_CODEC_DMA_RX_0, 1, 1},
0809     [TX_CODEC_DMA_TX_0] = { AFE_PORT_ID_TX_CODEC_DMA_TX_0,
0810                 TX_CODEC_DMA_TX_0, 0, 1},
0811     [RX_CODEC_DMA_RX_1] = { AFE_PORT_ID_RX_CODEC_DMA_RX_1,
0812                 RX_CODEC_DMA_RX_1, 1, 1},
0813     [TX_CODEC_DMA_TX_1] = { AFE_PORT_ID_TX_CODEC_DMA_TX_1,
0814                 TX_CODEC_DMA_TX_1, 0, 1},
0815     [RX_CODEC_DMA_RX_2] = { AFE_PORT_ID_RX_CODEC_DMA_RX_2,
0816                 RX_CODEC_DMA_RX_2, 1, 1},
0817     [TX_CODEC_DMA_TX_2] = { AFE_PORT_ID_TX_CODEC_DMA_TX_2,
0818                 TX_CODEC_DMA_TX_2, 0, 1},
0819     [RX_CODEC_DMA_RX_3] = { AFE_PORT_ID_RX_CODEC_DMA_RX_3,
0820                 RX_CODEC_DMA_RX_3, 1, 1},
0821     [TX_CODEC_DMA_TX_3] = { AFE_PORT_ID_TX_CODEC_DMA_TX_3,
0822                 TX_CODEC_DMA_TX_3, 0, 1},
0823     [RX_CODEC_DMA_RX_4] = { AFE_PORT_ID_RX_CODEC_DMA_RX_4,
0824                 RX_CODEC_DMA_RX_4, 1, 1},
0825     [TX_CODEC_DMA_TX_4] = { AFE_PORT_ID_TX_CODEC_DMA_TX_4,
0826                 TX_CODEC_DMA_TX_4, 0, 1},
0827     [RX_CODEC_DMA_RX_5] = { AFE_PORT_ID_RX_CODEC_DMA_RX_5,
0828                 RX_CODEC_DMA_RX_5, 1, 1},
0829     [TX_CODEC_DMA_TX_5] = { AFE_PORT_ID_TX_CODEC_DMA_TX_5,
0830                 TX_CODEC_DMA_TX_5, 0, 1},
0831     [RX_CODEC_DMA_RX_6] = { AFE_PORT_ID_RX_CODEC_DMA_RX_6,
0832                 RX_CODEC_DMA_RX_6, 1, 1},
0833     [RX_CODEC_DMA_RX_7] = { AFE_PORT_ID_RX_CODEC_DMA_RX_7,
0834                 RX_CODEC_DMA_RX_7, 1, 1},
0835 };
0836 
0837 static void q6afe_port_free(struct kref *ref)
0838 {
0839     struct q6afe_port *port;
0840     struct q6afe *afe;
0841     unsigned long flags;
0842 
0843     port = container_of(ref, struct q6afe_port, refcount);
0844     afe = port->afe;
0845     spin_lock_irqsave(&afe->port_list_lock, flags);
0846     list_del(&port->node);
0847     spin_unlock_irqrestore(&afe->port_list_lock, flags);
0848     kfree(port->scfg);
0849     kfree(port);
0850 }
0851 
0852 static struct q6afe_port *q6afe_find_port(struct q6afe *afe, int token)
0853 {
0854     struct q6afe_port *p;
0855     struct q6afe_port *ret = NULL;
0856     unsigned long flags;
0857 
0858     spin_lock_irqsave(&afe->port_list_lock, flags);
0859     list_for_each_entry(p, &afe->port_list, node)
0860         if (p->token == token) {
0861             ret = p;
0862             kref_get(&p->refcount);
0863             break;
0864         }
0865 
0866     spin_unlock_irqrestore(&afe->port_list_lock, flags);
0867     return ret;
0868 }
0869 
0870 static int q6afe_callback(struct apr_device *adev, struct apr_resp_pkt *data)
0871 {
0872     struct q6afe *afe = dev_get_drvdata(&adev->dev);
0873     struct aprv2_ibasic_rsp_result_t *res;
0874     struct apr_hdr *hdr = &data->hdr;
0875     struct q6afe_port *port;
0876 
0877     if (!data->payload_size)
0878         return 0;
0879 
0880     res = data->payload;
0881     switch (hdr->opcode) {
0882     case APR_BASIC_RSP_RESULT: {
0883         if (res->status) {
0884             dev_err(afe->dev, "cmd = 0x%x returned error = 0x%x\n",
0885                 res->opcode, res->status);
0886         }
0887         switch (res->opcode) {
0888         case AFE_PORT_CMD_SET_PARAM_V2:
0889         case AFE_PORT_CMD_DEVICE_STOP:
0890         case AFE_PORT_CMD_DEVICE_START:
0891         case AFE_SVC_CMD_SET_PARAM:
0892             port = q6afe_find_port(afe, hdr->token);
0893             if (port) {
0894                 port->result = *res;
0895                 wake_up(&port->wait);
0896                 kref_put(&port->refcount, q6afe_port_free);
0897             } else if (hdr->token == AFE_CLK_TOKEN) {
0898                 afe->result = *res;
0899                 wake_up(&afe->wait);
0900             }
0901             break;
0902         default:
0903             dev_err(afe->dev, "Unknown cmd 0x%x\n", res->opcode);
0904             break;
0905         }
0906     }
0907         break;
0908     case AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST:
0909         afe->result.opcode = hdr->opcode;
0910         afe->result.status = res->status;
0911         wake_up(&afe->wait);
0912         break;
0913     default:
0914         break;
0915     }
0916 
0917     return 0;
0918 }
0919 
0920 /**
0921  * q6afe_get_port_id() - Get port id from a given port index
0922  *
0923  * @index: port index
0924  *
0925  * Return: Will be an negative on error or valid port_id on success
0926  */
0927 int q6afe_get_port_id(int index)
0928 {
0929     if (index < 0 || index >= AFE_PORT_MAX)
0930         return -EINVAL;
0931 
0932     return port_maps[index].port_id;
0933 }
0934 EXPORT_SYMBOL_GPL(q6afe_get_port_id);
0935 
0936 static int afe_apr_send_pkt(struct q6afe *afe, struct apr_pkt *pkt,
0937                 struct q6afe_port *port, uint32_t rsp_opcode)
0938 {
0939     wait_queue_head_t *wait;
0940     struct aprv2_ibasic_rsp_result_t *result;
0941     int ret;
0942 
0943     mutex_lock(&afe->lock);
0944     if (port) {
0945         wait = &port->wait;
0946         result = &port->result;
0947     } else {
0948         result = &afe->result;
0949         wait = &afe->wait;
0950     }
0951 
0952     result->opcode = 0;
0953     result->status = 0;
0954 
0955     ret = apr_send_pkt(afe->apr, pkt);
0956     if (ret < 0) {
0957         dev_err(afe->dev, "packet not transmitted (%d)\n", ret);
0958         ret = -EINVAL;
0959         goto err;
0960     }
0961 
0962     ret = wait_event_timeout(*wait, (result->opcode == rsp_opcode),
0963                  msecs_to_jiffies(TIMEOUT_MS));
0964     if (!ret) {
0965         ret = -ETIMEDOUT;
0966     } else if (result->status > 0) {
0967         dev_err(afe->dev, "DSP returned error[%x]\n",
0968             result->status);
0969         ret = -EINVAL;
0970     } else {
0971         ret = 0;
0972     }
0973 
0974 err:
0975     mutex_unlock(&afe->lock);
0976 
0977     return ret;
0978 }
0979 
0980 static int q6afe_set_param(struct q6afe *afe, struct q6afe_port *port,
0981                void *data, int param_id, int module_id, int psize,
0982                int token)
0983 {
0984     struct afe_svc_cmd_set_param *param;
0985     struct afe_port_param_data_v2 *pdata;
0986     struct apr_pkt *pkt;
0987     int ret, pkt_size;
0988     void *p, *pl;
0989 
0990     pkt_size = APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata) + psize;
0991     p = kzalloc(pkt_size, GFP_KERNEL);
0992     if (!p)
0993         return -ENOMEM;
0994 
0995     pkt = p;
0996     param = p + APR_HDR_SIZE;
0997     pdata = p + APR_HDR_SIZE + sizeof(*param);
0998     pl = p + APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata);
0999     memcpy(pl, data, psize);
1000 
1001     pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1002                        APR_HDR_LEN(APR_HDR_SIZE),
1003                        APR_PKT_VER);
1004     pkt->hdr.pkt_size = pkt_size;
1005     pkt->hdr.src_port = 0;
1006     pkt->hdr.dest_port = 0;
1007     pkt->hdr.token = token;
1008     pkt->hdr.opcode = AFE_SVC_CMD_SET_PARAM;
1009 
1010     param->payload_size = sizeof(*pdata) + psize;
1011     param->payload_address_lsw = 0x00;
1012     param->payload_address_msw = 0x00;
1013     param->mem_map_handle = 0x00;
1014     pdata->module_id = module_id;
1015     pdata->param_id = param_id;
1016     pdata->param_size = psize;
1017 
1018     ret = afe_apr_send_pkt(afe, pkt, port, AFE_SVC_CMD_SET_PARAM);
1019     if (ret)
1020         dev_err(afe->dev, "AFE set params failed %d\n", ret);
1021 
1022     kfree(pkt);
1023     return ret;
1024 }
1025 
1026 static int q6afe_port_set_param(struct q6afe_port *port, void *data,
1027                 int param_id, int module_id, int psize)
1028 {
1029     return q6afe_set_param(port->afe, port, data, param_id, module_id,
1030                    psize, port->token);
1031 }
1032 
1033 static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data,
1034                    int param_id, int module_id, int psize)
1035 {
1036     struct afe_port_cmd_set_param_v2 *param;
1037     struct afe_port_param_data_v2 *pdata;
1038     struct q6afe *afe = port->afe;
1039     struct apr_pkt *pkt;
1040     u16 port_id = port->id;
1041     int ret, pkt_size;
1042     void *p, *pl;
1043 
1044     pkt_size = APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata) + psize;
1045     p = kzalloc(pkt_size, GFP_KERNEL);
1046     if (!p)
1047         return -ENOMEM;
1048 
1049     pkt = p;
1050     param = p + APR_HDR_SIZE;
1051     pdata = p + APR_HDR_SIZE + sizeof(*param);
1052     pl = p + APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata);
1053     memcpy(pl, data, psize);
1054 
1055     pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1056                        APR_HDR_LEN(APR_HDR_SIZE),
1057                        APR_PKT_VER);
1058     pkt->hdr.pkt_size = pkt_size;
1059     pkt->hdr.src_port = 0;
1060     pkt->hdr.dest_port = 0;
1061     pkt->hdr.token = port->token;
1062     pkt->hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
1063 
1064     param->port_id = port_id;
1065     param->payload_size = sizeof(*pdata) + psize;
1066     param->payload_address_lsw = 0x00;
1067     param->payload_address_msw = 0x00;
1068     param->mem_map_handle = 0x00;
1069     pdata->module_id = module_id;
1070     pdata->param_id = param_id;
1071     pdata->param_size = psize;
1072 
1073     ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_SET_PARAM_V2);
1074     if (ret)
1075         dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1076                port_id, ret);
1077 
1078     kfree(pkt);
1079     return ret;
1080 }
1081 
1082 static int q6afe_port_set_lpass_clock(struct q6afe_port *port,
1083                  struct afe_clk_cfg *cfg)
1084 {
1085     return q6afe_port_set_param_v2(port, cfg,
1086                        AFE_PARAM_ID_LPAIF_CLK_CONFIG,
1087                        AFE_MODULE_AUDIO_DEV_INTERFACE,
1088                        sizeof(*cfg));
1089 }
1090 
1091 static int q6afe_set_lpass_clock_v2(struct q6afe_port *port,
1092                  struct afe_clk_set *cfg)
1093 {
1094     return q6afe_port_set_param(port, cfg, AFE_PARAM_ID_CLOCK_SET,
1095                     AFE_MODULE_CLOCK_SET, sizeof(*cfg));
1096 }
1097 
1098 static int q6afe_set_digital_codec_core_clock(struct q6afe_port *port,
1099                           struct afe_digital_clk_cfg *cfg)
1100 {
1101     return q6afe_port_set_param_v2(port, cfg,
1102                        AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG,
1103                        AFE_MODULE_AUDIO_DEV_INTERFACE,
1104                        sizeof(*cfg));
1105 }
1106 
1107 int q6afe_set_lpass_clock(struct device *dev, int clk_id, int attri,
1108               int clk_root, unsigned int freq)
1109 {
1110     struct q6afe *afe = dev_get_drvdata(dev->parent);
1111     struct afe_clk_set cset = {0,};
1112 
1113     cset.clk_set_minor_version = AFE_API_VERSION_CLOCK_SET;
1114     cset.clk_id = clk_id;
1115     cset.clk_freq_in_hz = freq;
1116     cset.clk_attri = attri;
1117     cset.clk_root = clk_root;
1118     cset.enable = !!freq;
1119 
1120     return q6afe_set_param(afe, NULL, &cset, AFE_PARAM_ID_CLOCK_SET,
1121                    AFE_MODULE_CLOCK_SET, sizeof(cset),
1122                    AFE_CLK_TOKEN);
1123 }
1124 EXPORT_SYMBOL_GPL(q6afe_set_lpass_clock);
1125 
1126 int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id,
1127               int clk_src, int clk_root,
1128               unsigned int freq, int dir)
1129 {
1130     struct afe_clk_cfg ccfg = {0,};
1131     struct afe_clk_set cset = {0,};
1132     struct afe_digital_clk_cfg dcfg = {0,};
1133     int ret;
1134 
1135     switch (clk_id) {
1136     case LPAIF_DIG_CLK:
1137         dcfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
1138         dcfg.clk_val = freq;
1139         dcfg.clk_root = clk_root;
1140         ret = q6afe_set_digital_codec_core_clock(port, &dcfg);
1141         break;
1142     case LPAIF_BIT_CLK:
1143         ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
1144         ccfg.clk_val1 = freq;
1145         ccfg.clk_src = clk_src;
1146         ccfg.clk_root = clk_root;
1147         ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID;
1148         ret = q6afe_port_set_lpass_clock(port, &ccfg);
1149         break;
1150 
1151     case LPAIF_OSR_CLK:
1152         ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
1153         ccfg.clk_val2 = freq;
1154         ccfg.clk_src = clk_src;
1155         ccfg.clk_root = clk_root;
1156         ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID;
1157         ret = q6afe_port_set_lpass_clock(port, &ccfg);
1158         break;
1159     case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT ... Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR:
1160     case Q6AFE_LPASS_CLK_ID_MCLK_1 ... Q6AFE_LPASS_CLK_ID_INT_MCLK_1:
1161     case Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT ... Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT:
1162     case Q6AFE_LPASS_CLK_ID_WSA_CORE_MCLK ... Q6AFE_LPASS_CLK_ID_VA_CORE_2X_MCLK:
1163         cset.clk_set_minor_version = AFE_API_VERSION_CLOCK_SET;
1164         cset.clk_id = clk_id;
1165         cset.clk_freq_in_hz = freq;
1166         cset.clk_attri = clk_src;
1167         cset.clk_root = clk_root;
1168         cset.enable = !!freq;
1169         ret = q6afe_set_lpass_clock_v2(port, &cset);
1170         break;
1171     default:
1172         ret = -EINVAL;
1173         break;
1174     }
1175 
1176     return ret;
1177 }
1178 EXPORT_SYMBOL_GPL(q6afe_port_set_sysclk);
1179 
1180 /**
1181  * q6afe_port_stop() - Stop a afe port
1182  *
1183  * @port: Instance of port to stop
1184  *
1185  * Return: Will be an negative on packet size on success.
1186  */
1187 int q6afe_port_stop(struct q6afe_port *port)
1188 {
1189     struct afe_port_cmd_device_stop *stop;
1190     struct q6afe *afe = port->afe;
1191     struct apr_pkt *pkt;
1192     int port_id = port->id;
1193     int ret = 0;
1194     int index, pkt_size;
1195     void *p;
1196 
1197     index = port->token;
1198     if (index < 0 || index >= AFE_PORT_MAX) {
1199         dev_err(afe->dev, "AFE port index[%d] invalid!\n", index);
1200         return -EINVAL;
1201     }
1202 
1203     pkt_size = APR_HDR_SIZE + sizeof(*stop);
1204     p = kzalloc(pkt_size, GFP_KERNEL);
1205     if (!p)
1206         return -ENOMEM;
1207 
1208     pkt = p;
1209     stop = p + APR_HDR_SIZE;
1210 
1211     pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1212                        APR_HDR_LEN(APR_HDR_SIZE),
1213                        APR_PKT_VER);
1214     pkt->hdr.pkt_size = pkt_size;
1215     pkt->hdr.src_port = 0;
1216     pkt->hdr.dest_port = 0;
1217     pkt->hdr.token = index;
1218     pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_STOP;
1219     stop->port_id = port_id;
1220     stop->reserved = 0;
1221 
1222     ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_DEVICE_STOP);
1223     if (ret)
1224         dev_err(afe->dev, "AFE close failed %d\n", ret);
1225 
1226     kfree(pkt);
1227     return ret;
1228 }
1229 EXPORT_SYMBOL_GPL(q6afe_port_stop);
1230 
1231 /**
1232  * q6afe_slim_port_prepare() - Prepare slim afe port.
1233  *
1234  * @port: Instance of afe port
1235  * @cfg: SLIM configuration for the afe port
1236  *
1237  */
1238 void q6afe_slim_port_prepare(struct q6afe_port *port,
1239                  struct q6afe_slim_cfg *cfg)
1240 {
1241     union afe_port_config *pcfg = &port->port_cfg;
1242 
1243     pcfg->slim_cfg.sb_cfg_minor_version = AFE_API_VERSION_SLIMBUS_CONFIG;
1244     pcfg->slim_cfg.sample_rate = cfg->sample_rate;
1245     pcfg->slim_cfg.bit_width = cfg->bit_width;
1246     pcfg->slim_cfg.num_channels = cfg->num_channels;
1247     pcfg->slim_cfg.data_format = cfg->data_format;
1248     pcfg->slim_cfg.shared_ch_mapping[0] = cfg->ch_mapping[0];
1249     pcfg->slim_cfg.shared_ch_mapping[1] = cfg->ch_mapping[1];
1250     pcfg->slim_cfg.shared_ch_mapping[2] = cfg->ch_mapping[2];
1251     pcfg->slim_cfg.shared_ch_mapping[3] = cfg->ch_mapping[3];
1252 
1253 }
1254 EXPORT_SYMBOL_GPL(q6afe_slim_port_prepare);
1255 
1256 /**
1257  * q6afe_tdm_port_prepare() - Prepare tdm afe port.
1258  *
1259  * @port: Instance of afe port
1260  * @cfg: TDM configuration for the afe port
1261  *
1262  */
1263 void q6afe_tdm_port_prepare(struct q6afe_port *port,
1264                  struct q6afe_tdm_cfg *cfg)
1265 {
1266     union afe_port_config *pcfg = &port->port_cfg;
1267 
1268     pcfg->tdm_cfg.tdm_cfg_minor_version = AFE_API_VERSION_TDM_CONFIG;
1269     pcfg->tdm_cfg.num_channels = cfg->num_channels;
1270     pcfg->tdm_cfg.sample_rate = cfg->sample_rate;
1271     pcfg->tdm_cfg.bit_width = cfg->bit_width;
1272     pcfg->tdm_cfg.data_format = cfg->data_format;
1273     pcfg->tdm_cfg.sync_mode = cfg->sync_mode;
1274     pcfg->tdm_cfg.sync_src = cfg->sync_src;
1275     pcfg->tdm_cfg.nslots_per_frame = cfg->nslots_per_frame;
1276 
1277     pcfg->tdm_cfg.slot_width = cfg->slot_width;
1278     pcfg->tdm_cfg.slot_mask = cfg->slot_mask;
1279     port->scfg = kzalloc(sizeof(*port->scfg), GFP_KERNEL);
1280     if (!port->scfg)
1281         return;
1282 
1283     port->scfg->minor_version = AFE_API_VERSION_SLOT_MAPPING_CONFIG;
1284     port->scfg->num_channels = cfg->num_channels;
1285     port->scfg->bitwidth = cfg->bit_width;
1286     port->scfg->data_align_type = cfg->data_align_type;
1287     memcpy(port->scfg->ch_mapping, cfg->ch_mapping,
1288             sizeof(u16) * AFE_PORT_MAX_AUDIO_CHAN_CNT);
1289 }
1290 EXPORT_SYMBOL_GPL(q6afe_tdm_port_prepare);
1291 
1292 /**
1293  * q6afe_hdmi_port_prepare() - Prepare hdmi afe port.
1294  *
1295  * @port: Instance of afe port
1296  * @cfg: HDMI configuration for the afe port
1297  *
1298  */
1299 void q6afe_hdmi_port_prepare(struct q6afe_port *port,
1300                  struct q6afe_hdmi_cfg *cfg)
1301 {
1302     union afe_port_config *pcfg = &port->port_cfg;
1303 
1304     pcfg->hdmi_multi_ch.hdmi_cfg_minor_version =
1305                     AFE_API_VERSION_HDMI_CONFIG;
1306     pcfg->hdmi_multi_ch.datatype = cfg->datatype;
1307     pcfg->hdmi_multi_ch.channel_allocation = cfg->channel_allocation;
1308     pcfg->hdmi_multi_ch.sample_rate = cfg->sample_rate;
1309     pcfg->hdmi_multi_ch.bit_width = cfg->bit_width;
1310 }
1311 EXPORT_SYMBOL_GPL(q6afe_hdmi_port_prepare);
1312 
1313 /**
1314  * q6afe_i2s_port_prepare() - Prepare i2s afe port.
1315  *
1316  * @port: Instance of afe port
1317  * @cfg: I2S configuration for the afe port
1318  * Return: Will be an negative on error and zero on success.
1319  */
1320 int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg)
1321 {
1322     union afe_port_config *pcfg = &port->port_cfg;
1323     struct device *dev = port->afe->dev;
1324     int num_sd_lines;
1325 
1326     pcfg->i2s_cfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
1327     pcfg->i2s_cfg.sample_rate = cfg->sample_rate;
1328     pcfg->i2s_cfg.bit_width = cfg->bit_width;
1329     pcfg->i2s_cfg.data_format = AFE_LINEAR_PCM_DATA;
1330 
1331     switch (cfg->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
1332     case SND_SOC_DAIFMT_BP_FP:
1333         pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL;
1334         break;
1335     case SND_SOC_DAIFMT_BC_FC:
1336         /* CPU is slave */
1337         pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL;
1338         break;
1339     default:
1340         break;
1341     }
1342 
1343     num_sd_lines = hweight_long(cfg->sd_line_mask);
1344 
1345     switch (num_sd_lines) {
1346     case 0:
1347         dev_err(dev, "no line is assigned\n");
1348         return -EINVAL;
1349     case 1:
1350         switch (cfg->sd_line_mask) {
1351         case AFE_PORT_I2S_SD0_MASK:
1352             pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0;
1353             break;
1354         case AFE_PORT_I2S_SD1_MASK:
1355             pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD1;
1356             break;
1357         case AFE_PORT_I2S_SD2_MASK:
1358             pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2;
1359             break;
1360         case AFE_PORT_I2S_SD3_MASK:
1361             pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD3;
1362             break;
1363         default:
1364             dev_err(dev, "Invalid SD lines\n");
1365             return -EINVAL;
1366         }
1367         break;
1368     case 2:
1369         switch (cfg->sd_line_mask) {
1370         case AFE_PORT_I2S_SD0_1_MASK:
1371             pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD01;
1372             break;
1373         case AFE_PORT_I2S_SD2_3_MASK:
1374             pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD23;
1375             break;
1376         default:
1377             dev_err(dev, "Invalid SD lines\n");
1378             return -EINVAL;
1379         }
1380         break;
1381     case 3:
1382         switch (cfg->sd_line_mask) {
1383         case AFE_PORT_I2S_SD0_1_2_MASK:
1384             pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_6CHS;
1385             break;
1386         default:
1387             dev_err(dev, "Invalid SD lines\n");
1388             return -EINVAL;
1389         }
1390         break;
1391     case 4:
1392         switch (cfg->sd_line_mask) {
1393         case AFE_PORT_I2S_SD0_1_2_3_MASK:
1394             pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_8CHS;
1395 
1396             break;
1397         default:
1398             dev_err(dev, "Invalid SD lines\n");
1399             return -EINVAL;
1400         }
1401         break;
1402     default:
1403         dev_err(dev, "Invalid SD lines\n");
1404         return -EINVAL;
1405     }
1406 
1407     switch (cfg->num_channels) {
1408     case 1:
1409     case 2:
1410         switch (pcfg->i2s_cfg.channel_mode) {
1411         case AFE_PORT_I2S_QUAD01:
1412         case AFE_PORT_I2S_6CHS:
1413         case AFE_PORT_I2S_8CHS:
1414             pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0;
1415             break;
1416         case AFE_PORT_I2S_QUAD23:
1417                 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2;
1418             break;
1419         }
1420 
1421         if (cfg->num_channels == 2)
1422             pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_STEREO;
1423         else
1424             pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_MONO;
1425 
1426         break;
1427     case 3:
1428     case 4:
1429         if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_QUAD01) {
1430             dev_err(dev, "Invalid Channel mode\n");
1431             return -EINVAL;
1432         }
1433         break;
1434     case 5:
1435     case 6:
1436         if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_6CHS) {
1437             dev_err(dev, "Invalid Channel mode\n");
1438             return -EINVAL;
1439         }
1440         break;
1441     case 7:
1442     case 8:
1443         if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_8CHS) {
1444             dev_err(dev, "Invalid Channel mode\n");
1445             return -EINVAL;
1446         }
1447         break;
1448     default:
1449         break;
1450     }
1451 
1452     return 0;
1453 }
1454 EXPORT_SYMBOL_GPL(q6afe_i2s_port_prepare);
1455 
1456 /**
1457  * q6afe_cdc_dma_port_prepare() - Prepare dma afe port.
1458  *
1459  * @port: Instance of afe port
1460  * @cfg: DMA configuration for the afe port
1461  *
1462  */
1463 void q6afe_cdc_dma_port_prepare(struct q6afe_port *port,
1464                 struct q6afe_cdc_dma_cfg *cfg)
1465 {
1466     union afe_port_config *pcfg = &port->port_cfg;
1467     struct afe_param_id_cdc_dma_cfg *dma_cfg = &pcfg->dma_cfg;
1468 
1469     dma_cfg->cdc_dma_cfg_minor_version = AFE_API_VERSION_CODEC_DMA_CONFIG;
1470     dma_cfg->sample_rate = cfg->sample_rate;
1471     dma_cfg->bit_width = cfg->bit_width;
1472     dma_cfg->data_format = cfg->data_format;
1473     dma_cfg->num_channels = cfg->num_channels;
1474     if (!cfg->active_channels_mask)
1475         dma_cfg->active_channels_mask = (1 << cfg->num_channels) - 1;
1476 }
1477 EXPORT_SYMBOL_GPL(q6afe_cdc_dma_port_prepare);
1478 /**
1479  * q6afe_port_start() - Start a afe port
1480  *
1481  * @port: Instance of port to start
1482  *
1483  * Return: Will be an negative on packet size on success.
1484  */
1485 int q6afe_port_start(struct q6afe_port *port)
1486 {
1487     struct afe_port_cmd_device_start *start;
1488     struct q6afe *afe = port->afe;
1489     int port_id = port->id;
1490     int ret, param_id = port->cfg_type;
1491     struct apr_pkt *pkt;
1492     int pkt_size;
1493     void *p;
1494 
1495     ret  = q6afe_port_set_param_v2(port, &port->port_cfg, param_id,
1496                        AFE_MODULE_AUDIO_DEV_INTERFACE,
1497                        sizeof(port->port_cfg));
1498     if (ret) {
1499         dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1500             port_id, ret);
1501         return ret;
1502     }
1503 
1504     if (port->scfg) {
1505         ret  = q6afe_port_set_param_v2(port, port->scfg,
1506                     AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG,
1507                     AFE_MODULE_TDM, sizeof(*port->scfg));
1508         if (ret) {
1509             dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1510             port_id, ret);
1511             return ret;
1512         }
1513     }
1514 
1515     pkt_size = APR_HDR_SIZE + sizeof(*start);
1516     p = kzalloc(pkt_size, GFP_KERNEL);
1517     if (!p)
1518         return -ENOMEM;
1519 
1520     pkt = p;
1521     start = p + APR_HDR_SIZE;
1522 
1523     pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1524                         APR_HDR_LEN(APR_HDR_SIZE),
1525                         APR_PKT_VER);
1526     pkt->hdr.pkt_size = pkt_size;
1527     pkt->hdr.src_port = 0;
1528     pkt->hdr.dest_port = 0;
1529     pkt->hdr.token = port->token;
1530     pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_START;
1531 
1532     start->port_id = port_id;
1533 
1534     ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_DEVICE_START);
1535     if (ret)
1536         dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1537             port_id, ret);
1538 
1539     kfree(pkt);
1540     return ret;
1541 }
1542 EXPORT_SYMBOL_GPL(q6afe_port_start);
1543 
1544 /**
1545  * q6afe_port_get_from_id() - Get port instance from a port id
1546  *
1547  * @dev: Pointer to afe child device.
1548  * @id: port id
1549  *
1550  * Return: Will be an error pointer on error or a valid afe port
1551  * on success.
1552  */
1553 struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id)
1554 {
1555     int port_id;
1556     struct q6afe *afe = dev_get_drvdata(dev->parent);
1557     struct q6afe_port *port;
1558     unsigned long flags;
1559     int cfg_type;
1560 
1561     if (id < 0 || id >= AFE_PORT_MAX) {
1562         dev_err(dev, "AFE port token[%d] invalid!\n", id);
1563         return ERR_PTR(-EINVAL);
1564     }
1565 
1566     /* if port is multiple times bind/unbind before callback finishes */
1567     port = q6afe_find_port(afe, id);
1568     if (port) {
1569         dev_err(dev, "AFE Port already open\n");
1570         return port;
1571     }
1572 
1573     port_id = port_maps[id].port_id;
1574 
1575     switch (port_id) {
1576     case AFE_PORT_ID_MULTICHAN_HDMI_RX:
1577     case AFE_PORT_ID_HDMI_OVER_DP_RX:
1578         cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
1579         break;
1580     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX:
1581     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX:
1582     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX:
1583     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX:
1584     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX:
1585     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX:
1586     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX:
1587     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX:
1588     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX:
1589     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX:
1590     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX:
1591     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX:
1592     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX:
1593     case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX:
1594         cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG;
1595         break;
1596 
1597     case AFE_PORT_ID_PRIMARY_MI2S_RX:
1598     case AFE_PORT_ID_PRIMARY_MI2S_TX:
1599     case AFE_PORT_ID_SECONDARY_MI2S_RX:
1600     case AFE_PORT_ID_SECONDARY_MI2S_TX:
1601     case AFE_PORT_ID_TERTIARY_MI2S_RX:
1602     case AFE_PORT_ID_TERTIARY_MI2S_TX:
1603     case AFE_PORT_ID_QUATERNARY_MI2S_RX:
1604     case AFE_PORT_ID_QUATERNARY_MI2S_TX:
1605     case AFE_PORT_ID_QUINARY_MI2S_RX:
1606     case AFE_PORT_ID_QUINARY_MI2S_TX:
1607         cfg_type = AFE_PARAM_ID_I2S_CONFIG;
1608         break;
1609     case AFE_PORT_ID_PRIMARY_TDM_RX ... AFE_PORT_ID_QUINARY_TDM_TX_7:
1610         cfg_type = AFE_PARAM_ID_TDM_CONFIG;
1611         break;
1612     case AFE_PORT_ID_WSA_CODEC_DMA_RX_0 ... AFE_PORT_ID_RX_CODEC_DMA_RX_7:
1613         cfg_type = AFE_PARAM_ID_CODEC_DMA_CONFIG;
1614     break;
1615     default:
1616         dev_err(dev, "Invalid port id 0x%x\n", port_id);
1617         return ERR_PTR(-EINVAL);
1618     }
1619 
1620     port = kzalloc(sizeof(*port), GFP_KERNEL);
1621     if (!port)
1622         return ERR_PTR(-ENOMEM);
1623 
1624     init_waitqueue_head(&port->wait);
1625 
1626     port->token = id;
1627     port->id = port_id;
1628     port->afe = afe;
1629     port->cfg_type = cfg_type;
1630     kref_init(&port->refcount);
1631 
1632     spin_lock_irqsave(&afe->port_list_lock, flags);
1633     list_add_tail(&port->node, &afe->port_list);
1634     spin_unlock_irqrestore(&afe->port_list_lock, flags);
1635 
1636     return port;
1637 
1638 }
1639 EXPORT_SYMBOL_GPL(q6afe_port_get_from_id);
1640 
1641 /**
1642  * q6afe_port_put() - Release port reference
1643  *
1644  * @port: Instance of port to put
1645  */
1646 void q6afe_port_put(struct q6afe_port *port)
1647 {
1648     kref_put(&port->refcount, q6afe_port_free);
1649 }
1650 EXPORT_SYMBOL_GPL(q6afe_port_put);
1651 
1652 int q6afe_unvote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
1653                    uint32_t client_handle)
1654 {
1655     struct q6afe *afe = dev_get_drvdata(dev->parent);
1656     struct afe_cmd_remote_lpass_core_hw_devote_request *vote_cfg;
1657     struct apr_pkt *pkt;
1658     int ret = 0;
1659     int pkt_size;
1660     void *p;
1661 
1662     pkt_size = APR_HDR_SIZE + sizeof(*vote_cfg);
1663     p = kzalloc(pkt_size, GFP_KERNEL);
1664     if (!p)
1665         return -ENOMEM;
1666 
1667     pkt = p;
1668     vote_cfg = p + APR_HDR_SIZE;
1669 
1670     pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1671                        APR_HDR_LEN(APR_HDR_SIZE),
1672                        APR_PKT_VER);
1673     pkt->hdr.pkt_size = pkt_size;
1674     pkt->hdr.src_port = 0;
1675     pkt->hdr.dest_port = 0;
1676     pkt->hdr.token = hw_block_id;
1677     pkt->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST;
1678     vote_cfg->hw_block_id = hw_block_id;
1679     vote_cfg->client_handle = client_handle;
1680 
1681     ret = apr_send_pkt(afe->apr, pkt);
1682     if (ret < 0)
1683         dev_err(afe->dev, "AFE failed to unvote (%d)\n", hw_block_id);
1684 
1685     kfree(pkt);
1686     return ret;
1687 }
1688 EXPORT_SYMBOL(q6afe_unvote_lpass_core_hw);
1689 
1690 int q6afe_vote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
1691                  const char *client_name, uint32_t *client_handle)
1692 {
1693     struct q6afe *afe = dev_get_drvdata(dev->parent);
1694     struct afe_cmd_remote_lpass_core_hw_vote_request *vote_cfg;
1695     struct apr_pkt *pkt;
1696     int ret = 0;
1697     int pkt_size;
1698     void *p;
1699 
1700     pkt_size = APR_HDR_SIZE + sizeof(*vote_cfg);
1701     p = kzalloc(pkt_size, GFP_KERNEL);
1702     if (!p)
1703         return -ENOMEM;
1704 
1705     pkt = p;
1706     vote_cfg = p + APR_HDR_SIZE;
1707 
1708     pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1709                        APR_HDR_LEN(APR_HDR_SIZE),
1710                        APR_PKT_VER);
1711     pkt->hdr.pkt_size = pkt_size;
1712     pkt->hdr.src_port = 0;
1713     pkt->hdr.dest_port = 0;
1714     pkt->hdr.token = hw_block_id;
1715     pkt->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST;
1716     vote_cfg->hw_block_id = hw_block_id;
1717     strscpy(vote_cfg->client_name, client_name,
1718             sizeof(vote_cfg->client_name));
1719 
1720     ret = afe_apr_send_pkt(afe, pkt, NULL,
1721                    AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST);
1722     if (ret)
1723         dev_err(afe->dev, "AFE failed to vote (%d)\n", hw_block_id);
1724 
1725 
1726     kfree(pkt);
1727     return ret;
1728 }
1729 EXPORT_SYMBOL(q6afe_vote_lpass_core_hw);
1730 
1731 static int q6afe_probe(struct apr_device *adev)
1732 {
1733     struct q6afe *afe;
1734     struct device *dev = &adev->dev;
1735 
1736     afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL);
1737     if (!afe)
1738         return -ENOMEM;
1739 
1740     q6core_get_svc_api_info(adev->svc_id, &afe->ainfo);
1741     afe->apr = adev;
1742     mutex_init(&afe->lock);
1743     init_waitqueue_head(&afe->wait);
1744     afe->dev = dev;
1745     INIT_LIST_HEAD(&afe->port_list);
1746     spin_lock_init(&afe->port_list_lock);
1747 
1748     dev_set_drvdata(dev, afe);
1749 
1750     return devm_of_platform_populate(dev);
1751 }
1752 
1753 #ifdef CONFIG_OF
1754 static const struct of_device_id q6afe_device_id[]  = {
1755     { .compatible = "qcom,q6afe" },
1756     {},
1757 };
1758 MODULE_DEVICE_TABLE(of, q6afe_device_id);
1759 #endif
1760 
1761 static struct apr_driver qcom_q6afe_driver = {
1762     .probe = q6afe_probe,
1763     .callback = q6afe_callback,
1764     .driver = {
1765         .name = "qcom-q6afe",
1766         .of_match_table = of_match_ptr(q6afe_device_id),
1767 
1768     },
1769 };
1770 
1771 module_apr_driver(qcom_q6afe_driver);
1772 MODULE_DESCRIPTION("Q6 Audio Front End");
1773 MODULE_LICENSE("GPL v2");