root/sound/soc/qcom/qdsp6/q6afe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. q6afe_port_free
  2. q6afe_find_port
  3. q6afe_callback
  4. q6afe_get_port_id
  5. afe_apr_send_pkt
  6. q6afe_port_set_param
  7. q6afe_port_set_param_v2
  8. q6afe_set_lpass_clock
  9. q6afe_set_lpass_clock_v2
  10. q6afe_set_digital_codec_core_clock
  11. q6afe_port_set_sysclk
  12. q6afe_port_stop
  13. q6afe_slim_port_prepare
  14. q6afe_tdm_port_prepare
  15. q6afe_hdmi_port_prepare
  16. q6afe_i2s_port_prepare
  17. q6afe_port_start
  18. q6afe_port_get_from_id
  19. q6afe_port_put
  20. q6afe_probe
  21. q6afe_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
   3 // Copyright (c) 2018, Linaro Limited
   4 
   5 #include <linux/slab.h>
   6 #include <linux/kernel.h>
   7 #include <linux/uaccess.h>
   8 #include <linux/wait.h>
   9 #include <linux/jiffies.h>
  10 #include <linux/sched.h>
  11 #include <linux/module.h>
  12 #include <linux/kref.h>
  13 #include <linux/of.h>
  14 #include <linux/of_platform.h>
  15 #include <linux/spinlock.h>
  16 #include <linux/delay.h>
  17 #include <linux/soc/qcom/apr.h>
  18 #include <sound/soc.h>
  19 #include <sound/soc-dai.h>
  20 #include <sound/pcm.h>
  21 #include <sound/pcm_params.h>
  22 #include "q6dsp-errno.h"
  23 #include "q6core.h"
  24 #include "q6afe.h"
  25 
  26 /* AFE CMDs */
  27 #define AFE_PORT_CMD_DEVICE_START       0x000100E5
  28 #define AFE_PORT_CMD_DEVICE_STOP        0x000100E6
  29 #define AFE_PORT_CMD_SET_PARAM_V2       0x000100EF
  30 #define AFE_SVC_CMD_SET_PARAM           0x000100f3
  31 #define AFE_PORT_CMDRSP_GET_PARAM_V2    0x00010106
  32 #define AFE_PARAM_ID_HDMI_CONFIG        0x00010210
  33 #define AFE_MODULE_AUDIO_DEV_INTERFACE  0x0001020C
  34 #define AFE_MODULE_TDM                  0x0001028A
  35 
  36 #define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG 0x00010235
  37 
  38 #define AFE_PARAM_ID_LPAIF_CLK_CONFIG   0x00010238
  39 #define AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG 0x00010239
  40 
  41 #define AFE_PARAM_ID_SLIMBUS_CONFIG    0x00010212
  42 #define AFE_PARAM_ID_I2S_CONFIG 0x0001020D
  43 #define AFE_PARAM_ID_TDM_CONFIG 0x0001029D
  44 #define AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG   0x00010297
  45 
  46 /* I2S config specific */
  47 #define AFE_API_VERSION_I2S_CONFIG      0x1
  48 #define AFE_PORT_I2S_SD0                0x1
  49 #define AFE_PORT_I2S_SD1                0x2
  50 #define AFE_PORT_I2S_SD2                0x3
  51 #define AFE_PORT_I2S_SD3                0x4
  52 #define AFE_PORT_I2S_SD0_MASK           BIT(0x0)
  53 #define AFE_PORT_I2S_SD1_MASK           BIT(0x1)
  54 #define AFE_PORT_I2S_SD2_MASK           BIT(0x2)
  55 #define AFE_PORT_I2S_SD3_MASK           BIT(0x3)
  56 #define AFE_PORT_I2S_SD0_1_MASK         GENMASK(1, 0)
  57 #define AFE_PORT_I2S_SD2_3_MASK         GENMASK(3, 2)
  58 #define AFE_PORT_I2S_SD0_1_2_MASK       GENMASK(2, 0)
  59 #define AFE_PORT_I2S_SD0_1_2_3_MASK     GENMASK(3, 0)
  60 #define AFE_PORT_I2S_QUAD01             0x5
  61 #define AFE_PORT_I2S_QUAD23             0x6
  62 #define AFE_PORT_I2S_6CHS               0x7
  63 #define AFE_PORT_I2S_8CHS               0x8
  64 #define AFE_PORT_I2S_MONO               0x0
  65 #define AFE_PORT_I2S_STEREO             0x1
  66 #define AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL     0x0
  67 #define AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL     0x1
  68 #define AFE_LINEAR_PCM_DATA                             0x0
  69 
  70 
  71 /* Port IDs */
  72 #define AFE_API_VERSION_HDMI_CONFIG     0x1
  73 #define AFE_PORT_ID_MULTICHAN_HDMI_RX   0x100E
  74 #define AFE_PORT_ID_HDMI_OVER_DP_RX     0x6020
  75 
  76 #define AFE_API_VERSION_SLIMBUS_CONFIG 0x1
  77 /* Clock set API version */
  78 #define AFE_API_VERSION_CLOCK_SET 1
  79 #define Q6AFE_LPASS_CLK_CONFIG_API_VERSION      0x1
  80 #define AFE_MODULE_CLOCK_SET            0x0001028F
  81 #define AFE_PARAM_ID_CLOCK_SET          0x00010290
  82 
  83 /* SLIMbus Rx port on channel 0. */
  84 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX      0x4000
  85 /* SLIMbus Tx port on channel 0. */
  86 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX      0x4001
  87 /* SLIMbus Rx port on channel 1. */
  88 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX      0x4002
  89 /* SLIMbus Tx port on channel 1. */
  90 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX      0x4003
  91 /* SLIMbus Rx port on channel 2. */
  92 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX      0x4004
  93 /* SLIMbus Tx port on channel 2. */
  94 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX      0x4005
  95 /* SLIMbus Rx port on channel 3. */
  96 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX      0x4006
  97 /* SLIMbus Tx port on channel 3. */
  98 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX      0x4007
  99 /* SLIMbus Rx port on channel 4. */
 100 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX      0x4008
 101 /* SLIMbus Tx port on channel 4. */
 102 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX      0x4009
 103 /* SLIMbus Rx port on channel 5. */
 104 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX      0x400a
 105 /* SLIMbus Tx port on channel 5. */
 106 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX      0x400b
 107 /* SLIMbus Rx port on channel 6. */
 108 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX      0x400c
 109 /* SLIMbus Tx port on channel 6. */
 110 #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX      0x400d
 111 #define AFE_PORT_ID_PRIMARY_MI2S_RX         0x1000
 112 #define AFE_PORT_ID_PRIMARY_MI2S_TX         0x1001
 113 #define AFE_PORT_ID_SECONDARY_MI2S_RX       0x1002
 114 #define AFE_PORT_ID_SECONDARY_MI2S_TX       0x1003
 115 #define AFE_PORT_ID_TERTIARY_MI2S_RX        0x1004
 116 #define AFE_PORT_ID_TERTIARY_MI2S_TX        0x1005
 117 #define AFE_PORT_ID_QUATERNARY_MI2S_RX      0x1006
 118 #define AFE_PORT_ID_QUATERNARY_MI2S_TX      0x1007
 119 
 120 /* Start of the range of port IDs for TDM devices. */
 121 #define AFE_PORT_ID_TDM_PORT_RANGE_START        0x9000
 122 
 123 /* End of the range of port IDs for TDM devices. */
 124 #define AFE_PORT_ID_TDM_PORT_RANGE_END \
 125         (AFE_PORT_ID_TDM_PORT_RANGE_START+0x50-1)
 126 
 127 /* Size of the range of port IDs for TDM ports. */
 128 #define AFE_PORT_ID_TDM_PORT_RANGE_SIZE \
 129         (AFE_PORT_ID_TDM_PORT_RANGE_END - \
 130         AFE_PORT_ID_TDM_PORT_RANGE_START+1)
 131 
 132 #define AFE_PORT_ID_PRIMARY_TDM_RX \
 133         (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x00)
 134 #define AFE_PORT_ID_PRIMARY_TDM_RX_1 \
 135         (AFE_PORT_ID_PRIMARY_TDM_RX + 0x02)
 136 #define AFE_PORT_ID_PRIMARY_TDM_RX_2 \
 137         (AFE_PORT_ID_PRIMARY_TDM_RX + 0x04)
 138 #define AFE_PORT_ID_PRIMARY_TDM_RX_3 \
 139         (AFE_PORT_ID_PRIMARY_TDM_RX + 0x06)
 140 #define AFE_PORT_ID_PRIMARY_TDM_RX_4 \
 141         (AFE_PORT_ID_PRIMARY_TDM_RX + 0x08)
 142 #define AFE_PORT_ID_PRIMARY_TDM_RX_5 \
 143         (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0A)
 144 #define AFE_PORT_ID_PRIMARY_TDM_RX_6 \
 145         (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0C)
 146 #define AFE_PORT_ID_PRIMARY_TDM_RX_7 \
 147         (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0E)
 148 
 149 #define AFE_PORT_ID_PRIMARY_TDM_TX \
 150         (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x01)
 151 #define AFE_PORT_ID_PRIMARY_TDM_TX_1 \
 152         (AFE_PORT_ID_PRIMARY_TDM_TX + 0x02)
 153 #define AFE_PORT_ID_PRIMARY_TDM_TX_2 \
 154         (AFE_PORT_ID_PRIMARY_TDM_TX + 0x04)
 155 #define AFE_PORT_ID_PRIMARY_TDM_TX_3 \
 156         (AFE_PORT_ID_PRIMARY_TDM_TX + 0x06)
 157 #define AFE_PORT_ID_PRIMARY_TDM_TX_4 \
 158         (AFE_PORT_ID_PRIMARY_TDM_TX + 0x08)
 159 #define AFE_PORT_ID_PRIMARY_TDM_TX_5 \
 160         (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0A)
 161 #define AFE_PORT_ID_PRIMARY_TDM_TX_6 \
 162         (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0C)
 163 #define AFE_PORT_ID_PRIMARY_TDM_TX_7 \
 164         (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0E)
 165 
 166 #define AFE_PORT_ID_SECONDARY_TDM_RX \
 167         (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x10)
 168 #define AFE_PORT_ID_SECONDARY_TDM_RX_1 \
 169         (AFE_PORT_ID_SECONDARY_TDM_RX + 0x02)
 170 #define AFE_PORT_ID_SECONDARY_TDM_RX_2 \
 171         (AFE_PORT_ID_SECONDARY_TDM_RX + 0x04)
 172 #define AFE_PORT_ID_SECONDARY_TDM_RX_3 \
 173         (AFE_PORT_ID_SECONDARY_TDM_RX + 0x06)
 174 #define AFE_PORT_ID_SECONDARY_TDM_RX_4 \
 175         (AFE_PORT_ID_SECONDARY_TDM_RX + 0x08)
 176 #define AFE_PORT_ID_SECONDARY_TDM_RX_5 \
 177         (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0A)
 178 #define AFE_PORT_ID_SECONDARY_TDM_RX_6 \
 179         (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0C)
 180 #define AFE_PORT_ID_SECONDARY_TDM_RX_7 \
 181         (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0E)
 182 
 183 #define AFE_PORT_ID_SECONDARY_TDM_TX \
 184         (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x11)
 185 #define AFE_PORT_ID_SECONDARY_TDM_TX_1 \
 186         (AFE_PORT_ID_SECONDARY_TDM_TX + 0x02)
 187 #define AFE_PORT_ID_SECONDARY_TDM_TX_2 \
 188         (AFE_PORT_ID_SECONDARY_TDM_TX + 0x04)
 189 #define AFE_PORT_ID_SECONDARY_TDM_TX_3 \
 190         (AFE_PORT_ID_SECONDARY_TDM_TX + 0x06)
 191 #define AFE_PORT_ID_SECONDARY_TDM_TX_4 \
 192         (AFE_PORT_ID_SECONDARY_TDM_TX + 0x08)
 193 #define AFE_PORT_ID_SECONDARY_TDM_TX_5 \
 194         (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0A)
 195 #define AFE_PORT_ID_SECONDARY_TDM_TX_6 \
 196         (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0C)
 197 #define AFE_PORT_ID_SECONDARY_TDM_TX_7 \
 198         (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0E)
 199 
 200 #define AFE_PORT_ID_TERTIARY_TDM_RX \
 201         (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x20)
 202 #define AFE_PORT_ID_TERTIARY_TDM_RX_1 \
 203         (AFE_PORT_ID_TERTIARY_TDM_RX + 0x02)
 204 #define AFE_PORT_ID_TERTIARY_TDM_RX_2 \
 205         (AFE_PORT_ID_TERTIARY_TDM_RX + 0x04)
 206 #define AFE_PORT_ID_TERTIARY_TDM_RX_3 \
 207         (AFE_PORT_ID_TERTIARY_TDM_RX + 0x06)
 208 #define AFE_PORT_ID_TERTIARY_TDM_RX_4 \
 209         (AFE_PORT_ID_TERTIARY_TDM_RX + 0x08)
 210 #define AFE_PORT_ID_TERTIARY_TDM_RX_5 \
 211         (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0A)
 212 #define AFE_PORT_ID_TERTIARY_TDM_RX_6 \
 213         (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0C)
 214 #define AFE_PORT_ID_TERTIARY_TDM_RX_7 \
 215         (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0E)
 216 
 217 #define AFE_PORT_ID_TERTIARY_TDM_TX \
 218         (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x21)
 219 #define AFE_PORT_ID_TERTIARY_TDM_TX_1 \
 220         (AFE_PORT_ID_TERTIARY_TDM_TX + 0x02)
 221 #define AFE_PORT_ID_TERTIARY_TDM_TX_2 \
 222         (AFE_PORT_ID_TERTIARY_TDM_TX + 0x04)
 223 #define AFE_PORT_ID_TERTIARY_TDM_TX_3 \
 224         (AFE_PORT_ID_TERTIARY_TDM_TX + 0x06)
 225 #define AFE_PORT_ID_TERTIARY_TDM_TX_4 \
 226         (AFE_PORT_ID_TERTIARY_TDM_TX + 0x08)
 227 #define AFE_PORT_ID_TERTIARY_TDM_TX_5 \
 228         (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0A)
 229 #define AFE_PORT_ID_TERTIARY_TDM_TX_6 \
 230         (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0C)
 231 #define AFE_PORT_ID_TERTIARY_TDM_TX_7 \
 232         (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0E)
 233 
 234 #define AFE_PORT_ID_QUATERNARY_TDM_RX \
 235         (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x30)
 236 #define AFE_PORT_ID_QUATERNARY_TDM_RX_1 \
 237         (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x02)
 238 #define AFE_PORT_ID_QUATERNARY_TDM_RX_2 \
 239         (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x04)
 240 #define AFE_PORT_ID_QUATERNARY_TDM_RX_3 \
 241         (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x06)
 242 #define AFE_PORT_ID_QUATERNARY_TDM_RX_4 \
 243         (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x08)
 244 #define AFE_PORT_ID_QUATERNARY_TDM_RX_5 \
 245         (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0A)
 246 #define AFE_PORT_ID_QUATERNARY_TDM_RX_6 \
 247         (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0C)
 248 #define AFE_PORT_ID_QUATERNARY_TDM_RX_7 \
 249         (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0E)
 250 
 251 #define AFE_PORT_ID_QUATERNARY_TDM_TX \
 252         (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x31)
 253 #define AFE_PORT_ID_QUATERNARY_TDM_TX_1 \
 254         (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x02)
 255 #define AFE_PORT_ID_QUATERNARY_TDM_TX_2 \
 256         (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x04)
 257 #define AFE_PORT_ID_QUATERNARY_TDM_TX_3 \
 258         (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x06)
 259 #define AFE_PORT_ID_QUATERNARY_TDM_TX_4 \
 260         (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x08)
 261 #define AFE_PORT_ID_QUATERNARY_TDM_TX_5 \
 262         (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0A)
 263 #define AFE_PORT_ID_QUATERNARY_TDM_TX_6 \
 264         (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0C)
 265 #define AFE_PORT_ID_QUATERNARY_TDM_TX_7 \
 266         (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0E)
 267 
 268 #define AFE_PORT_ID_QUINARY_TDM_RX \
 269         (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x40)
 270 #define AFE_PORT_ID_QUINARY_TDM_RX_1 \
 271         (AFE_PORT_ID_QUINARY_TDM_RX + 0x02)
 272 #define AFE_PORT_ID_QUINARY_TDM_RX_2 \
 273         (AFE_PORT_ID_QUINARY_TDM_RX + 0x04)
 274 #define AFE_PORT_ID_QUINARY_TDM_RX_3 \
 275         (AFE_PORT_ID_QUINARY_TDM_RX + 0x06)
 276 #define AFE_PORT_ID_QUINARY_TDM_RX_4 \
 277         (AFE_PORT_ID_QUINARY_TDM_RX + 0x08)
 278 #define AFE_PORT_ID_QUINARY_TDM_RX_5 \
 279         (AFE_PORT_ID_QUINARY_TDM_RX + 0x0A)
 280 #define AFE_PORT_ID_QUINARY_TDM_RX_6 \
 281         (AFE_PORT_ID_QUINARY_TDM_RX + 0x0C)
 282 #define AFE_PORT_ID_QUINARY_TDM_RX_7 \
 283         (AFE_PORT_ID_QUINARY_TDM_RX + 0x0E)
 284 
 285 #define AFE_PORT_ID_QUINARY_TDM_TX \
 286         (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x41)
 287 #define AFE_PORT_ID_QUINARY_TDM_TX_1 \
 288         (AFE_PORT_ID_QUINARY_TDM_TX + 0x02)
 289 #define AFE_PORT_ID_QUINARY_TDM_TX_2 \
 290         (AFE_PORT_ID_QUINARY_TDM_TX + 0x04)
 291 #define AFE_PORT_ID_QUINARY_TDM_TX_3 \
 292         (AFE_PORT_ID_QUINARY_TDM_TX + 0x06)
 293 #define AFE_PORT_ID_QUINARY_TDM_TX_4 \
 294         (AFE_PORT_ID_QUINARY_TDM_TX + 0x08)
 295 #define AFE_PORT_ID_QUINARY_TDM_TX_5 \
 296         (AFE_PORT_ID_QUINARY_TDM_TX + 0x0A)
 297 #define AFE_PORT_ID_QUINARY_TDM_TX_6 \
 298         (AFE_PORT_ID_QUINARY_TDM_TX + 0x0C)
 299 #define AFE_PORT_ID_QUINARY_TDM_TX_7 \
 300         (AFE_PORT_ID_QUINARY_TDM_TX + 0x0E)
 301 
 302 #define Q6AFE_LPASS_MODE_CLK1_VALID 1
 303 #define Q6AFE_LPASS_MODE_CLK2_VALID 2
 304 #define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
 305 #define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0
 306 #define AFE_API_VERSION_TDM_CONFIG              1
 307 #define AFE_API_VERSION_SLOT_MAPPING_CONFIG     1
 308 
 309 #define TIMEOUT_MS 1000
 310 #define AFE_CMD_RESP_AVAIL      0
 311 #define AFE_CMD_RESP_NONE       1
 312 
 313 struct q6afe {
 314         struct apr_device *apr;
 315         struct device *dev;
 316         struct q6core_svc_api_info ainfo;
 317         struct mutex lock;
 318         struct list_head port_list;
 319         spinlock_t port_list_lock;
 320 };
 321 
 322 struct afe_port_cmd_device_start {
 323         u16 port_id;
 324         u16 reserved;
 325 } __packed;
 326 
 327 struct afe_port_cmd_device_stop {
 328         u16 port_id;
 329         u16 reserved;
 330 /* Reserved for 32-bit alignment. This field must be set to 0.*/
 331 } __packed;
 332 
 333 struct afe_port_param_data_v2 {
 334         u32 module_id;
 335         u32 param_id;
 336         u16 param_size;
 337         u16 reserved;
 338 } __packed;
 339 
 340 struct afe_svc_cmd_set_param {
 341         uint32_t payload_size;
 342         uint32_t payload_address_lsw;
 343         uint32_t payload_address_msw;
 344         uint32_t mem_map_handle;
 345 } __packed;
 346 
 347 struct afe_port_cmd_set_param_v2 {
 348         u16 port_id;
 349         u16 payload_size;
 350         u32 payload_address_lsw;
 351         u32 payload_address_msw;
 352         u32 mem_map_handle;
 353 } __packed;
 354 
 355 struct afe_param_id_hdmi_multi_chan_audio_cfg {
 356         u32 hdmi_cfg_minor_version;
 357         u16 datatype;
 358         u16 channel_allocation;
 359         u32 sample_rate;
 360         u16 bit_width;
 361         u16 reserved;
 362 } __packed;
 363 
 364 struct afe_param_id_slimbus_cfg {
 365         u32                  sb_cfg_minor_version;
 366 /* Minor version used for tracking the version of the SLIMBUS
 367  * configuration interface.
 368  * Supported values: #AFE_API_VERSION_SLIMBUS_CONFIG
 369  */
 370 
 371         u16                  slimbus_dev_id;
 372 /* SLIMbus hardware device ID, which is required to handle
 373  * multiple SLIMbus hardware blocks.
 374  * Supported values: - #AFE_SLIMBUS_DEVICE_1 - #AFE_SLIMBUS_DEVICE_2
 375  */
 376         u16                  bit_width;
 377 /* Bit width of the sample.
 378  * Supported values: 16, 24
 379  */
 380         u16                  data_format;
 381 /* Data format supported by the SLIMbus hardware. The default is
 382  * 0 (#AFE_SB_DATA_FORMAT_NOT_INDICATED), which indicates the
 383  * hardware does not perform any format conversions before the data
 384  * transfer.
 385  */
 386         u16                  num_channels;
 387 /* Number of channels.
 388  * Supported values: 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT
 389  */
 390         u8  shared_ch_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT];
 391 /* Mapping of shared channel IDs (128 to 255) to which the
 392  * master port is to be connected.
 393  * Shared_channel_mapping[i] represents the shared channel assigned
 394  * for audio channel i in multichannel audio data.
 395  */
 396         u32              sample_rate;
 397 /* Sampling rate of the port.
 398  * Supported values:
 399  * - #AFE_PORT_SAMPLE_RATE_8K
 400  * - #AFE_PORT_SAMPLE_RATE_16K
 401  * - #AFE_PORT_SAMPLE_RATE_48K
 402  * - #AFE_PORT_SAMPLE_RATE_96K
 403  * - #AFE_PORT_SAMPLE_RATE_192K
 404  */
 405 } __packed;
 406 
 407 struct afe_clk_cfg {
 408         u32                  i2s_cfg_minor_version;
 409         u32                  clk_val1;
 410         u32                  clk_val2;
 411         u16                  clk_src;
 412         u16                  clk_root;
 413         u16                  clk_set_mode;
 414         u16                  reserved;
 415 } __packed;
 416 
 417 struct afe_digital_clk_cfg {
 418         u32                  i2s_cfg_minor_version;
 419         u32                  clk_val;
 420         u16                  clk_root;
 421         u16                  reserved;
 422 } __packed;
 423 
 424 struct afe_param_id_i2s_cfg {
 425         u32     i2s_cfg_minor_version;
 426         u16     bit_width;
 427         u16     channel_mode;
 428         u16     mono_stereo;
 429         u16     ws_src;
 430         u32     sample_rate;
 431         u16     data_format;
 432         u16     reserved;
 433 } __packed;
 434 
 435 struct afe_param_id_tdm_cfg {
 436         u32     tdm_cfg_minor_version;
 437         u32     num_channels;
 438         u32     sample_rate;
 439         u32     bit_width;
 440         u16     data_format;
 441         u16     sync_mode;
 442         u16     sync_src;
 443         u16     nslots_per_frame;
 444         u16     ctrl_data_out_enable;
 445         u16     ctrl_invert_sync_pulse;
 446         u16     ctrl_sync_data_delay;
 447         u16     slot_width;
 448         u32     slot_mask;
 449 } __packed;
 450 
 451 union afe_port_config {
 452         struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch;
 453         struct afe_param_id_slimbus_cfg           slim_cfg;
 454         struct afe_param_id_i2s_cfg     i2s_cfg;
 455         struct afe_param_id_tdm_cfg     tdm_cfg;
 456 } __packed;
 457 
 458 
 459 struct afe_clk_set {
 460         uint32_t clk_set_minor_version;
 461         uint32_t clk_id;
 462         uint32_t clk_freq_in_hz;
 463         uint16_t clk_attri;
 464         uint16_t clk_root;
 465         uint32_t enable;
 466 };
 467 
 468 struct afe_param_id_slot_mapping_cfg {
 469         u32     minor_version;
 470         u16     num_channels;
 471         u16     bitwidth;
 472         u32     data_align_type;
 473         u16     ch_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT];
 474 } __packed;
 475 
 476 struct q6afe_port {
 477         wait_queue_head_t wait;
 478         union afe_port_config port_cfg;
 479         struct afe_param_id_slot_mapping_cfg *scfg;
 480         struct aprv2_ibasic_rsp_result_t result;
 481         int token;
 482         int id;
 483         int cfg_type;
 484         struct q6afe *afe;
 485         struct kref refcount;
 486         struct list_head node;
 487 };
 488 
 489 struct afe_port_map {
 490         int port_id;
 491         int token;
 492         int is_rx;
 493         int is_dig_pcm;
 494 };
 495 
 496 /*
 497  * Mapping between Virtual Port IDs to DSP AFE Port ID
 498  * On B Family SoCs DSP Port IDs are consistent across multiple SoCs
 499  * on A Family SoCs DSP port IDs are same as virtual Port IDs.
 500  */
 501 
 502 static struct afe_port_map port_maps[AFE_PORT_MAX] = {
 503         [HDMI_RX] = { AFE_PORT_ID_MULTICHAN_HDMI_RX, HDMI_RX, 1, 1},
 504         [SLIMBUS_0_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX,
 505                                 SLIMBUS_0_RX, 1, 1},
 506         [SLIMBUS_1_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX,
 507                                 SLIMBUS_1_RX, 1, 1},
 508         [SLIMBUS_2_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX,
 509                                 SLIMBUS_2_RX, 1, 1},
 510         [SLIMBUS_3_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX,
 511                                 SLIMBUS_3_RX, 1, 1},
 512         [SLIMBUS_4_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX,
 513                                 SLIMBUS_4_RX, 1, 1},
 514         [SLIMBUS_5_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX,
 515                                 SLIMBUS_5_RX, 1, 1},
 516         [SLIMBUS_6_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX,
 517                                 SLIMBUS_6_RX, 1, 1},
 518         [SLIMBUS_0_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX,
 519                                 SLIMBUS_0_TX, 0, 1},
 520         [SLIMBUS_1_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX,
 521                                 SLIMBUS_1_TX, 0, 1},
 522         [SLIMBUS_2_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX,
 523                                 SLIMBUS_2_TX, 0, 1},
 524         [SLIMBUS_3_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX,
 525                                 SLIMBUS_3_TX, 0, 1},
 526         [SLIMBUS_4_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX,
 527                                 SLIMBUS_4_TX, 0, 1},
 528         [SLIMBUS_5_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX,
 529                                 SLIMBUS_5_TX, 0, 1},
 530         [SLIMBUS_6_TX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX,
 531                                 SLIMBUS_6_TX, 0, 1},
 532         [PRIMARY_MI2S_RX] = { AFE_PORT_ID_PRIMARY_MI2S_RX,
 533                                 PRIMARY_MI2S_RX, 1, 1},
 534         [PRIMARY_MI2S_TX] = { AFE_PORT_ID_PRIMARY_MI2S_TX,
 535                                 PRIMARY_MI2S_RX, 0, 1},
 536         [SECONDARY_MI2S_RX] = { AFE_PORT_ID_SECONDARY_MI2S_RX,
 537                                 SECONDARY_MI2S_RX, 1, 1},
 538         [SECONDARY_MI2S_TX] = { AFE_PORT_ID_SECONDARY_MI2S_TX,
 539                                 SECONDARY_MI2S_TX, 0, 1},
 540         [TERTIARY_MI2S_RX] = { AFE_PORT_ID_TERTIARY_MI2S_RX,
 541                                 TERTIARY_MI2S_RX, 1, 1},
 542         [TERTIARY_MI2S_TX] = { AFE_PORT_ID_TERTIARY_MI2S_TX,
 543                                 TERTIARY_MI2S_TX, 0, 1},
 544         [QUATERNARY_MI2S_RX] = { AFE_PORT_ID_QUATERNARY_MI2S_RX,
 545                                 QUATERNARY_MI2S_RX, 1, 1},
 546         [QUATERNARY_MI2S_TX] = { AFE_PORT_ID_QUATERNARY_MI2S_TX,
 547                                 QUATERNARY_MI2S_TX, 0, 1},
 548         [PRIMARY_TDM_RX_0] =  { AFE_PORT_ID_PRIMARY_TDM_RX,
 549                                 PRIMARY_TDM_RX_0, 1, 1},
 550         [PRIMARY_TDM_TX_0] =  { AFE_PORT_ID_PRIMARY_TDM_TX,
 551                                 PRIMARY_TDM_TX_0, 0, 1},
 552         [PRIMARY_TDM_RX_1] =  { AFE_PORT_ID_PRIMARY_TDM_RX_1,
 553                                 PRIMARY_TDM_RX_1, 1, 1},
 554         [PRIMARY_TDM_TX_1] =  { AFE_PORT_ID_PRIMARY_TDM_TX_1,
 555                                 PRIMARY_TDM_TX_1, 0, 1},
 556         [PRIMARY_TDM_RX_2] =  { AFE_PORT_ID_PRIMARY_TDM_RX_2,
 557                                 PRIMARY_TDM_RX_2, 1, 1},
 558         [PRIMARY_TDM_TX_2] =  { AFE_PORT_ID_PRIMARY_TDM_TX_2,
 559                                 PRIMARY_TDM_TX_2, 0, 1},
 560         [PRIMARY_TDM_RX_3] =  { AFE_PORT_ID_PRIMARY_TDM_RX_3,
 561                                 PRIMARY_TDM_RX_3, 1, 1},
 562         [PRIMARY_TDM_TX_3] =  { AFE_PORT_ID_PRIMARY_TDM_TX_3,
 563                                 PRIMARY_TDM_TX_3, 0, 1},
 564         [PRIMARY_TDM_RX_4] =  { AFE_PORT_ID_PRIMARY_TDM_RX_4,
 565                                 PRIMARY_TDM_RX_4, 1, 1},
 566         [PRIMARY_TDM_TX_4] =  { AFE_PORT_ID_PRIMARY_TDM_TX_4,
 567                                 PRIMARY_TDM_TX_4, 0, 1},
 568         [PRIMARY_TDM_RX_5] =  { AFE_PORT_ID_PRIMARY_TDM_RX_5,
 569                                 PRIMARY_TDM_RX_5, 1, 1},
 570         [PRIMARY_TDM_TX_5] =  { AFE_PORT_ID_PRIMARY_TDM_TX_5,
 571                                 PRIMARY_TDM_TX_5, 0, 1},
 572         [PRIMARY_TDM_RX_6] =  { AFE_PORT_ID_PRIMARY_TDM_RX_6,
 573                                 PRIMARY_TDM_RX_6, 1, 1},
 574         [PRIMARY_TDM_TX_6] =  { AFE_PORT_ID_PRIMARY_TDM_TX_6,
 575                                 PRIMARY_TDM_TX_6, 0, 1},
 576         [PRIMARY_TDM_RX_7] =  { AFE_PORT_ID_PRIMARY_TDM_RX_7,
 577                                 PRIMARY_TDM_RX_7, 1, 1},
 578         [PRIMARY_TDM_TX_7] =  { AFE_PORT_ID_PRIMARY_TDM_TX_7,
 579                                 PRIMARY_TDM_TX_7, 0, 1},
 580         [SECONDARY_TDM_RX_0] =  { AFE_PORT_ID_SECONDARY_TDM_RX,
 581                                 SECONDARY_TDM_RX_0, 1, 1},
 582         [SECONDARY_TDM_TX_0] =  { AFE_PORT_ID_SECONDARY_TDM_TX,
 583                                 SECONDARY_TDM_TX_0, 0, 1},
 584         [SECONDARY_TDM_RX_1] =  { AFE_PORT_ID_SECONDARY_TDM_RX_1,
 585                                 SECONDARY_TDM_RX_1, 1, 1},
 586         [SECONDARY_TDM_TX_1] =  { AFE_PORT_ID_SECONDARY_TDM_TX_1,
 587                                 SECONDARY_TDM_TX_1, 0, 1},
 588         [SECONDARY_TDM_RX_2] =  { AFE_PORT_ID_SECONDARY_TDM_RX_2,
 589                                 SECONDARY_TDM_RX_2, 1, 1},
 590         [SECONDARY_TDM_TX_2] =  { AFE_PORT_ID_SECONDARY_TDM_TX_2,
 591                                 SECONDARY_TDM_TX_2, 0, 1},
 592         [SECONDARY_TDM_RX_3] =  { AFE_PORT_ID_SECONDARY_TDM_RX_3,
 593                                 SECONDARY_TDM_RX_3, 1, 1},
 594         [SECONDARY_TDM_TX_3] =  { AFE_PORT_ID_SECONDARY_TDM_TX_3,
 595                                 SECONDARY_TDM_TX_3, 0, 1},
 596         [SECONDARY_TDM_RX_4] =  { AFE_PORT_ID_SECONDARY_TDM_RX_4,
 597                                 SECONDARY_TDM_RX_4, 1, 1},
 598         [SECONDARY_TDM_TX_4] =  { AFE_PORT_ID_SECONDARY_TDM_TX_4,
 599                                 SECONDARY_TDM_TX_4, 0, 1},
 600         [SECONDARY_TDM_RX_5] =  { AFE_PORT_ID_SECONDARY_TDM_RX_5,
 601                                 SECONDARY_TDM_RX_5, 1, 1},
 602         [SECONDARY_TDM_TX_5] =  { AFE_PORT_ID_SECONDARY_TDM_TX_5,
 603                                 SECONDARY_TDM_TX_5, 0, 1},
 604         [SECONDARY_TDM_RX_6] =  { AFE_PORT_ID_SECONDARY_TDM_RX_6,
 605                                 SECONDARY_TDM_RX_6, 1, 1},
 606         [SECONDARY_TDM_TX_6] =  { AFE_PORT_ID_SECONDARY_TDM_TX_6,
 607                                 SECONDARY_TDM_TX_6, 0, 1},
 608         [SECONDARY_TDM_RX_7] =  { AFE_PORT_ID_SECONDARY_TDM_RX_7,
 609                                 SECONDARY_TDM_RX_7, 1, 1},
 610         [SECONDARY_TDM_TX_7] =  { AFE_PORT_ID_SECONDARY_TDM_TX_7,
 611                                 SECONDARY_TDM_TX_7, 0, 1},
 612         [TERTIARY_TDM_RX_0] =  { AFE_PORT_ID_TERTIARY_TDM_RX,
 613                                 TERTIARY_TDM_RX_0, 1, 1},
 614         [TERTIARY_TDM_TX_0] =  { AFE_PORT_ID_TERTIARY_TDM_TX,
 615                                 TERTIARY_TDM_TX_0, 0, 1},
 616         [TERTIARY_TDM_RX_1] =  { AFE_PORT_ID_TERTIARY_TDM_RX_1,
 617                                 TERTIARY_TDM_RX_1, 1, 1},
 618         [TERTIARY_TDM_TX_1] =  { AFE_PORT_ID_TERTIARY_TDM_TX_1,
 619                                 TERTIARY_TDM_TX_1, 0, 1},
 620         [TERTIARY_TDM_RX_2] =  { AFE_PORT_ID_TERTIARY_TDM_RX_2,
 621                                 TERTIARY_TDM_RX_2, 1, 1},
 622         [TERTIARY_TDM_TX_2] =  { AFE_PORT_ID_TERTIARY_TDM_TX_2,
 623                                 TERTIARY_TDM_TX_2, 0, 1},
 624         [TERTIARY_TDM_RX_3] =  { AFE_PORT_ID_TERTIARY_TDM_RX_3,
 625                                 TERTIARY_TDM_RX_3, 1, 1},
 626         [TERTIARY_TDM_TX_3] =  { AFE_PORT_ID_TERTIARY_TDM_TX_3,
 627                                 TERTIARY_TDM_TX_3, 0, 1},
 628         [TERTIARY_TDM_RX_4] =  { AFE_PORT_ID_TERTIARY_TDM_RX_4,
 629                                 TERTIARY_TDM_RX_4, 1, 1},
 630         [TERTIARY_TDM_TX_4] =  { AFE_PORT_ID_TERTIARY_TDM_TX_4,
 631                                 TERTIARY_TDM_TX_4, 0, 1},
 632         [TERTIARY_TDM_RX_5] =  { AFE_PORT_ID_TERTIARY_TDM_RX_5,
 633                                 TERTIARY_TDM_RX_5, 1, 1},
 634         [TERTIARY_TDM_TX_5] =  { AFE_PORT_ID_TERTIARY_TDM_TX_5,
 635                                 TERTIARY_TDM_TX_5, 0, 1},
 636         [TERTIARY_TDM_RX_6] =  { AFE_PORT_ID_TERTIARY_TDM_RX_6,
 637                                 TERTIARY_TDM_RX_6, 1, 1},
 638         [TERTIARY_TDM_TX_6] =  { AFE_PORT_ID_TERTIARY_TDM_TX_6,
 639                                 TERTIARY_TDM_TX_6, 0, 1},
 640         [TERTIARY_TDM_RX_7] =  { AFE_PORT_ID_TERTIARY_TDM_RX_7,
 641                                 TERTIARY_TDM_RX_7, 1, 1},
 642         [TERTIARY_TDM_TX_7] =  { AFE_PORT_ID_TERTIARY_TDM_TX_7,
 643                                 TERTIARY_TDM_TX_7, 0, 1},
 644         [QUATERNARY_TDM_RX_0] =  { AFE_PORT_ID_QUATERNARY_TDM_RX,
 645                                 QUATERNARY_TDM_RX_0, 1, 1},
 646         [QUATERNARY_TDM_TX_0] =  { AFE_PORT_ID_QUATERNARY_TDM_TX,
 647                                 QUATERNARY_TDM_TX_0, 0, 1},
 648         [QUATERNARY_TDM_RX_1] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_1,
 649                                 QUATERNARY_TDM_RX_1, 1, 1},
 650         [QUATERNARY_TDM_TX_1] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_1,
 651                                 QUATERNARY_TDM_TX_1, 0, 1},
 652         [QUATERNARY_TDM_RX_2] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_2,
 653                                 QUATERNARY_TDM_RX_2, 1, 1},
 654         [QUATERNARY_TDM_TX_2] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_2,
 655                                 QUATERNARY_TDM_TX_2, 0, 1},
 656         [QUATERNARY_TDM_RX_3] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_3,
 657                                 QUATERNARY_TDM_RX_3, 1, 1},
 658         [QUATERNARY_TDM_TX_3] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_3,
 659                                 QUATERNARY_TDM_TX_3, 0, 1},
 660         [QUATERNARY_TDM_RX_4] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_4,
 661                                 QUATERNARY_TDM_RX_4, 1, 1},
 662         [QUATERNARY_TDM_TX_4] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_4,
 663                                 QUATERNARY_TDM_TX_4, 0, 1},
 664         [QUATERNARY_TDM_RX_5] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_5,
 665                                 QUATERNARY_TDM_RX_5, 1, 1},
 666         [QUATERNARY_TDM_TX_5] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_5,
 667                                 QUATERNARY_TDM_TX_5, 0, 1},
 668         [QUATERNARY_TDM_RX_6] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_6,
 669                                 QUATERNARY_TDM_RX_6, 1, 1},
 670         [QUATERNARY_TDM_TX_6] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_6,
 671                                 QUATERNARY_TDM_TX_6, 0, 1},
 672         [QUATERNARY_TDM_RX_7] =  { AFE_PORT_ID_QUATERNARY_TDM_RX_7,
 673                                 QUATERNARY_TDM_RX_7, 1, 1},
 674         [QUATERNARY_TDM_TX_7] =  { AFE_PORT_ID_QUATERNARY_TDM_TX_7,
 675                                 QUATERNARY_TDM_TX_7, 0, 1},
 676         [QUINARY_TDM_RX_0] =  { AFE_PORT_ID_QUINARY_TDM_RX,
 677                                 QUINARY_TDM_RX_0, 1, 1},
 678         [QUINARY_TDM_TX_0] =  { AFE_PORT_ID_QUINARY_TDM_TX,
 679                                 QUINARY_TDM_TX_0, 0, 1},
 680         [QUINARY_TDM_RX_1] =  { AFE_PORT_ID_QUINARY_TDM_RX_1,
 681                                 QUINARY_TDM_RX_1, 1, 1},
 682         [QUINARY_TDM_TX_1] =  { AFE_PORT_ID_QUINARY_TDM_TX_1,
 683                                 QUINARY_TDM_TX_1, 0, 1},
 684         [QUINARY_TDM_RX_2] =  { AFE_PORT_ID_QUINARY_TDM_RX_2,
 685                                 QUINARY_TDM_RX_2, 1, 1},
 686         [QUINARY_TDM_TX_2] =  { AFE_PORT_ID_QUINARY_TDM_TX_2,
 687                                 QUINARY_TDM_TX_2, 0, 1},
 688         [QUINARY_TDM_RX_3] =  { AFE_PORT_ID_QUINARY_TDM_RX_3,
 689                                 QUINARY_TDM_RX_3, 1, 1},
 690         [QUINARY_TDM_TX_3] =  { AFE_PORT_ID_QUINARY_TDM_TX_3,
 691                                 QUINARY_TDM_TX_3, 0, 1},
 692         [QUINARY_TDM_RX_4] =  { AFE_PORT_ID_QUINARY_TDM_RX_4,
 693                                 QUINARY_TDM_RX_4, 1, 1},
 694         [QUINARY_TDM_TX_4] =  { AFE_PORT_ID_QUINARY_TDM_TX_4,
 695                                 QUINARY_TDM_TX_4, 0, 1},
 696         [QUINARY_TDM_RX_5] =  { AFE_PORT_ID_QUINARY_TDM_RX_5,
 697                                 QUINARY_TDM_RX_5, 1, 1},
 698         [QUINARY_TDM_TX_5] =  { AFE_PORT_ID_QUINARY_TDM_TX_5,
 699                                 QUINARY_TDM_TX_5, 0, 1},
 700         [QUINARY_TDM_RX_6] =  { AFE_PORT_ID_QUINARY_TDM_RX_6,
 701                                 QUINARY_TDM_RX_6, 1, 1},
 702         [QUINARY_TDM_TX_6] =  { AFE_PORT_ID_QUINARY_TDM_TX_6,
 703                                 QUINARY_TDM_TX_6, 0, 1},
 704         [QUINARY_TDM_RX_7] =  { AFE_PORT_ID_QUINARY_TDM_RX_7,
 705                                 QUINARY_TDM_RX_7, 1, 1},
 706         [QUINARY_TDM_TX_7] =  { AFE_PORT_ID_QUINARY_TDM_TX_7,
 707                                 QUINARY_TDM_TX_7, 0, 1},
 708         [DISPLAY_PORT_RX] = { AFE_PORT_ID_HDMI_OVER_DP_RX,
 709                                 DISPLAY_PORT_RX, 1, 1},
 710 };
 711 
 712 static void q6afe_port_free(struct kref *ref)
 713 {
 714         struct q6afe_port *port;
 715         struct q6afe *afe;
 716         unsigned long flags;
 717 
 718         port = container_of(ref, struct q6afe_port, refcount);
 719         afe = port->afe;
 720         spin_lock_irqsave(&afe->port_list_lock, flags);
 721         list_del(&port->node);
 722         spin_unlock_irqrestore(&afe->port_list_lock, flags);
 723         kfree(port->scfg);
 724         kfree(port);
 725 }
 726 
 727 static struct q6afe_port *q6afe_find_port(struct q6afe *afe, int token)
 728 {
 729         struct q6afe_port *p = NULL;
 730         struct q6afe_port *ret = NULL;
 731         unsigned long flags;
 732 
 733         spin_lock_irqsave(&afe->port_list_lock, flags);
 734         list_for_each_entry(p, &afe->port_list, node)
 735                 if (p->token == token) {
 736                         ret = p;
 737                         kref_get(&p->refcount);
 738                         break;
 739                 }
 740 
 741         spin_unlock_irqrestore(&afe->port_list_lock, flags);
 742         return ret;
 743 }
 744 
 745 static int q6afe_callback(struct apr_device *adev, struct apr_resp_pkt *data)
 746 {
 747         struct q6afe *afe = dev_get_drvdata(&adev->dev);
 748         struct aprv2_ibasic_rsp_result_t *res;
 749         struct apr_hdr *hdr = &data->hdr;
 750         struct q6afe_port *port;
 751 
 752         if (!data->payload_size)
 753                 return 0;
 754 
 755         res = data->payload;
 756         switch (hdr->opcode) {
 757         case APR_BASIC_RSP_RESULT: {
 758                 if (res->status) {
 759                         dev_err(afe->dev, "cmd = 0x%x returned error = 0x%x\n",
 760                                 res->opcode, res->status);
 761                 }
 762                 switch (res->opcode) {
 763                 case AFE_PORT_CMD_SET_PARAM_V2:
 764                 case AFE_PORT_CMD_DEVICE_STOP:
 765                 case AFE_PORT_CMD_DEVICE_START:
 766                 case AFE_SVC_CMD_SET_PARAM:
 767                         port = q6afe_find_port(afe, hdr->token);
 768                         if (port) {
 769                                 port->result = *res;
 770                                 wake_up(&port->wait);
 771                                 kref_put(&port->refcount, q6afe_port_free);
 772                         }
 773                         break;
 774                 default:
 775                         dev_err(afe->dev, "Unknown cmd 0x%x\n", res->opcode);
 776                         break;
 777                 }
 778         }
 779                 break;
 780         default:
 781                 break;
 782         }
 783 
 784         return 0;
 785 }
 786 
 787 /**
 788  * q6afe_get_port_id() - Get port id from a given port index
 789  *
 790  * @index: port index
 791  *
 792  * Return: Will be an negative on error or valid port_id on success
 793  */
 794 int q6afe_get_port_id(int index)
 795 {
 796         if (index < 0 || index >= AFE_PORT_MAX)
 797                 return -EINVAL;
 798 
 799         return port_maps[index].port_id;
 800 }
 801 EXPORT_SYMBOL_GPL(q6afe_get_port_id);
 802 
 803 static int afe_apr_send_pkt(struct q6afe *afe, struct apr_pkt *pkt,
 804                             struct q6afe_port *port)
 805 {
 806         wait_queue_head_t *wait = &port->wait;
 807         struct apr_hdr *hdr = &pkt->hdr;
 808         int ret;
 809 
 810         mutex_lock(&afe->lock);
 811         port->result.opcode = 0;
 812         port->result.status = 0;
 813 
 814         ret = apr_send_pkt(afe->apr, pkt);
 815         if (ret < 0) {
 816                 dev_err(afe->dev, "packet not transmitted (%d)\n", ret);
 817                 ret = -EINVAL;
 818                 goto err;
 819         }
 820 
 821         ret = wait_event_timeout(*wait, (port->result.opcode == hdr->opcode),
 822                                  msecs_to_jiffies(TIMEOUT_MS));
 823         if (!ret) {
 824                 ret = -ETIMEDOUT;
 825         } else if (port->result.status > 0) {
 826                 dev_err(afe->dev, "DSP returned error[%x]\n",
 827                         port->result.status);
 828                 ret = -EINVAL;
 829         } else {
 830                 ret = 0;
 831         }
 832 
 833 err:
 834         mutex_unlock(&afe->lock);
 835 
 836         return ret;
 837 }
 838 
 839 static int q6afe_port_set_param(struct q6afe_port *port, void *data,
 840                                 int param_id, int module_id, int psize)
 841 {
 842         struct afe_svc_cmd_set_param *param;
 843         struct afe_port_param_data_v2 *pdata;
 844         struct q6afe *afe = port->afe;
 845         struct apr_pkt *pkt;
 846         u16 port_id = port->id;
 847         int ret, pkt_size;
 848         void *p, *pl;
 849 
 850         pkt_size = APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata) + psize;
 851         p = kzalloc(pkt_size, GFP_KERNEL);
 852         if (!p)
 853                 return -ENOMEM;
 854 
 855         pkt = p;
 856         param = p + APR_HDR_SIZE;
 857         pdata = p + APR_HDR_SIZE + sizeof(*param);
 858         pl = p + APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata);
 859         memcpy(pl, data, psize);
 860 
 861         pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 862                                            APR_HDR_LEN(APR_HDR_SIZE),
 863                                            APR_PKT_VER);
 864         pkt->hdr.pkt_size = pkt_size;
 865         pkt->hdr.src_port = 0;
 866         pkt->hdr.dest_port = 0;
 867         pkt->hdr.token = port->token;
 868         pkt->hdr.opcode = AFE_SVC_CMD_SET_PARAM;
 869 
 870         param->payload_size = sizeof(*pdata) + psize;
 871         param->payload_address_lsw = 0x00;
 872         param->payload_address_msw = 0x00;
 873         param->mem_map_handle = 0x00;
 874         pdata->module_id = module_id;
 875         pdata->param_id = param_id;
 876         pdata->param_size = psize;
 877 
 878         ret = afe_apr_send_pkt(afe, pkt, port);
 879         if (ret)
 880                 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
 881                        port_id, ret);
 882 
 883         kfree(pkt);
 884         return ret;
 885 }
 886 
 887 static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data,
 888                                    int param_id, int module_id, int psize)
 889 {
 890         struct afe_port_cmd_set_param_v2 *param;
 891         struct afe_port_param_data_v2 *pdata;
 892         struct q6afe *afe = port->afe;
 893         struct apr_pkt *pkt;
 894         u16 port_id = port->id;
 895         int ret, pkt_size;
 896         void *p, *pl;
 897 
 898         pkt_size = APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata) + psize;
 899         p = kzalloc(pkt_size, GFP_KERNEL);
 900         if (!p)
 901                 return -ENOMEM;
 902 
 903         pkt = p;
 904         param = p + APR_HDR_SIZE;
 905         pdata = p + APR_HDR_SIZE + sizeof(*param);
 906         pl = p + APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata);
 907         memcpy(pl, data, psize);
 908 
 909         pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 910                                            APR_HDR_LEN(APR_HDR_SIZE),
 911                                            APR_PKT_VER);
 912         pkt->hdr.pkt_size = pkt_size;
 913         pkt->hdr.src_port = 0;
 914         pkt->hdr.dest_port = 0;
 915         pkt->hdr.token = port->token;
 916         pkt->hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
 917 
 918         param->port_id = port_id;
 919         param->payload_size = sizeof(*pdata) + psize;
 920         param->payload_address_lsw = 0x00;
 921         param->payload_address_msw = 0x00;
 922         param->mem_map_handle = 0x00;
 923         pdata->module_id = module_id;
 924         pdata->param_id = param_id;
 925         pdata->param_size = psize;
 926 
 927         ret = afe_apr_send_pkt(afe, pkt, port);
 928         if (ret)
 929                 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
 930                        port_id, ret);
 931 
 932         kfree(pkt);
 933         return ret;
 934 }
 935 
 936 static int q6afe_set_lpass_clock(struct q6afe_port *port,
 937                                  struct afe_clk_cfg *cfg)
 938 {
 939         return q6afe_port_set_param_v2(port, cfg,
 940                                        AFE_PARAM_ID_LPAIF_CLK_CONFIG,
 941                                        AFE_MODULE_AUDIO_DEV_INTERFACE,
 942                                        sizeof(*cfg));
 943 }
 944 
 945 static int q6afe_set_lpass_clock_v2(struct q6afe_port *port,
 946                                  struct afe_clk_set *cfg)
 947 {
 948         return q6afe_port_set_param(port, cfg, AFE_PARAM_ID_CLOCK_SET,
 949                                     AFE_MODULE_CLOCK_SET, sizeof(*cfg));
 950 }
 951 
 952 static int q6afe_set_digital_codec_core_clock(struct q6afe_port *port,
 953                                               struct afe_digital_clk_cfg *cfg)
 954 {
 955         return q6afe_port_set_param_v2(port, cfg,
 956                                        AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG,
 957                                        AFE_MODULE_AUDIO_DEV_INTERFACE,
 958                                        sizeof(*cfg));
 959 }
 960 
 961 int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id,
 962                           int clk_src, int clk_root,
 963                           unsigned int freq, int dir)
 964 {
 965         struct afe_clk_cfg ccfg = {0,};
 966         struct afe_clk_set cset = {0,};
 967         struct afe_digital_clk_cfg dcfg = {0,};
 968         int ret;
 969 
 970         switch (clk_id) {
 971         case LPAIF_DIG_CLK:
 972                 dcfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
 973                 dcfg.clk_val = freq;
 974                 dcfg.clk_root = clk_root;
 975                 ret = q6afe_set_digital_codec_core_clock(port, &dcfg);
 976                 break;
 977         case LPAIF_BIT_CLK:
 978                 ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
 979                 ccfg.clk_val1 = freq;
 980                 ccfg.clk_src = clk_src;
 981                 ccfg.clk_root = clk_root;
 982                 ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID;
 983                 ret = q6afe_set_lpass_clock(port, &ccfg);
 984                 break;
 985 
 986         case LPAIF_OSR_CLK:
 987                 ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
 988                 ccfg.clk_val2 = freq;
 989                 ccfg.clk_src = clk_src;
 990                 ccfg.clk_root = clk_root;
 991                 ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID;
 992                 ret = q6afe_set_lpass_clock(port, &ccfg);
 993                 break;
 994         case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT ... Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR:
 995         case Q6AFE_LPASS_CLK_ID_MCLK_1 ... Q6AFE_LPASS_CLK_ID_INT_MCLK_1:
 996         case Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT ... Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT:
 997                 cset.clk_set_minor_version = AFE_API_VERSION_CLOCK_SET;
 998                 cset.clk_id = clk_id;
 999                 cset.clk_freq_in_hz = freq;
1000                 cset.clk_attri = clk_src;
1001                 cset.clk_root = clk_root;
1002                 cset.enable = !!freq;
1003                 ret = q6afe_set_lpass_clock_v2(port, &cset);
1004                 break;
1005         default:
1006                 ret = -EINVAL;
1007                 break;
1008         }
1009 
1010         return ret;
1011 }
1012 EXPORT_SYMBOL_GPL(q6afe_port_set_sysclk);
1013 
1014 /**
1015  * q6afe_port_stop() - Stop a afe port
1016  *
1017  * @port: Instance of port to stop
1018  *
1019  * Return: Will be an negative on packet size on success.
1020  */
1021 int q6afe_port_stop(struct q6afe_port *port)
1022 {
1023         struct afe_port_cmd_device_stop *stop;
1024         struct q6afe *afe = port->afe;
1025         struct apr_pkt *pkt;
1026         int port_id = port->id;
1027         int ret = 0;
1028         int index, pkt_size;
1029         void *p;
1030 
1031         port_id = port->id;
1032         index = port->token;
1033         if (index < 0 || index >= AFE_PORT_MAX) {
1034                 dev_err(afe->dev, "AFE port index[%d] invalid!\n", index);
1035                 return -EINVAL;
1036         }
1037 
1038         pkt_size = APR_HDR_SIZE + sizeof(*stop);
1039         p = kzalloc(pkt_size, GFP_KERNEL);
1040         if (!p)
1041                 return -ENOMEM;
1042 
1043         pkt = p;
1044         stop = p + APR_HDR_SIZE;
1045 
1046         pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1047                                            APR_HDR_LEN(APR_HDR_SIZE),
1048                                            APR_PKT_VER);
1049         pkt->hdr.pkt_size = pkt_size;
1050         pkt->hdr.src_port = 0;
1051         pkt->hdr.dest_port = 0;
1052         pkt->hdr.token = index;
1053         pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_STOP;
1054         stop->port_id = port_id;
1055         stop->reserved = 0;
1056 
1057         ret = afe_apr_send_pkt(afe, pkt, port);
1058         if (ret)
1059                 dev_err(afe->dev, "AFE close failed %d\n", ret);
1060 
1061         kfree(pkt);
1062         return ret;
1063 }
1064 EXPORT_SYMBOL_GPL(q6afe_port_stop);
1065 
1066 /**
1067  * q6afe_slim_port_prepare() - Prepare slim afe port.
1068  *
1069  * @port: Instance of afe port
1070  * @cfg: SLIM configuration for the afe port
1071  *
1072  */
1073 void q6afe_slim_port_prepare(struct q6afe_port *port,
1074                              struct q6afe_slim_cfg *cfg)
1075 {
1076         union afe_port_config *pcfg = &port->port_cfg;
1077 
1078         pcfg->slim_cfg.sb_cfg_minor_version = AFE_API_VERSION_SLIMBUS_CONFIG;
1079         pcfg->slim_cfg.sample_rate = cfg->sample_rate;
1080         pcfg->slim_cfg.bit_width = cfg->bit_width;
1081         pcfg->slim_cfg.num_channels = cfg->num_channels;
1082         pcfg->slim_cfg.data_format = cfg->data_format;
1083         pcfg->slim_cfg.shared_ch_mapping[0] = cfg->ch_mapping[0];
1084         pcfg->slim_cfg.shared_ch_mapping[1] = cfg->ch_mapping[1];
1085         pcfg->slim_cfg.shared_ch_mapping[2] = cfg->ch_mapping[2];
1086         pcfg->slim_cfg.shared_ch_mapping[3] = cfg->ch_mapping[3];
1087 
1088 }
1089 EXPORT_SYMBOL_GPL(q6afe_slim_port_prepare);
1090 
1091 /**
1092  * q6afe_tdm_port_prepare() - Prepare tdm afe port.
1093  *
1094  * @port: Instance of afe port
1095  * @cfg: TDM configuration for the afe port
1096  *
1097  */
1098 void q6afe_tdm_port_prepare(struct q6afe_port *port,
1099                              struct q6afe_tdm_cfg *cfg)
1100 {
1101         union afe_port_config *pcfg = &port->port_cfg;
1102 
1103         pcfg->tdm_cfg.tdm_cfg_minor_version = AFE_API_VERSION_TDM_CONFIG;
1104         pcfg->tdm_cfg.num_channels = cfg->num_channels;
1105         pcfg->tdm_cfg.sample_rate = cfg->sample_rate;
1106         pcfg->tdm_cfg.bit_width = cfg->bit_width;
1107         pcfg->tdm_cfg.data_format = cfg->data_format;
1108         pcfg->tdm_cfg.sync_mode = cfg->sync_mode;
1109         pcfg->tdm_cfg.sync_src = cfg->sync_src;
1110         pcfg->tdm_cfg.nslots_per_frame = cfg->nslots_per_frame;
1111 
1112         pcfg->tdm_cfg.slot_width = cfg->slot_width;
1113         pcfg->tdm_cfg.slot_mask = cfg->slot_mask;
1114         port->scfg = kzalloc(sizeof(*port->scfg), GFP_KERNEL);
1115         if (!port->scfg)
1116                 return;
1117 
1118         port->scfg->minor_version = AFE_API_VERSION_SLOT_MAPPING_CONFIG;
1119         port->scfg->num_channels = cfg->num_channels;
1120         port->scfg->bitwidth = cfg->bit_width;
1121         port->scfg->data_align_type = cfg->data_align_type;
1122         memcpy(port->scfg->ch_mapping, cfg->ch_mapping,
1123                         sizeof(u16) * AFE_PORT_MAX_AUDIO_CHAN_CNT);
1124 }
1125 EXPORT_SYMBOL_GPL(q6afe_tdm_port_prepare);
1126 
1127 /**
1128  * q6afe_hdmi_port_prepare() - Prepare hdmi afe port.
1129  *
1130  * @port: Instance of afe port
1131  * @cfg: HDMI configuration for the afe port
1132  *
1133  */
1134 void q6afe_hdmi_port_prepare(struct q6afe_port *port,
1135                              struct q6afe_hdmi_cfg *cfg)
1136 {
1137         union afe_port_config *pcfg = &port->port_cfg;
1138 
1139         pcfg->hdmi_multi_ch.hdmi_cfg_minor_version =
1140                                         AFE_API_VERSION_HDMI_CONFIG;
1141         pcfg->hdmi_multi_ch.datatype = cfg->datatype;
1142         pcfg->hdmi_multi_ch.channel_allocation = cfg->channel_allocation;
1143         pcfg->hdmi_multi_ch.sample_rate = cfg->sample_rate;
1144         pcfg->hdmi_multi_ch.bit_width = cfg->bit_width;
1145 }
1146 EXPORT_SYMBOL_GPL(q6afe_hdmi_port_prepare);
1147 
1148 /**
1149  * q6afe_i2s_port_prepare() - Prepare i2s afe port.
1150  *
1151  * @port: Instance of afe port
1152  * @cfg: I2S configuration for the afe port
1153  * Return: Will be an negative on error and zero on success.
1154  */
1155 int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg)
1156 {
1157         union afe_port_config *pcfg = &port->port_cfg;
1158         struct device *dev = port->afe->dev;
1159         int num_sd_lines;
1160 
1161         pcfg->i2s_cfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
1162         pcfg->i2s_cfg.sample_rate = cfg->sample_rate;
1163         pcfg->i2s_cfg.bit_width = cfg->bit_width;
1164         pcfg->i2s_cfg.data_format = AFE_LINEAR_PCM_DATA;
1165 
1166         switch (cfg->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1167         case SND_SOC_DAIFMT_CBS_CFS:
1168                 pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL;
1169                 break;
1170         case SND_SOC_DAIFMT_CBM_CFM:
1171                 /* CPU is slave */
1172                 pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL;
1173                 break;
1174         default:
1175                 break;
1176         }
1177 
1178         num_sd_lines = hweight_long(cfg->sd_line_mask);
1179 
1180         switch (num_sd_lines) {
1181         case 0:
1182                 dev_err(dev, "no line is assigned\n");
1183                 return -EINVAL;
1184         case 1:
1185                 switch (cfg->sd_line_mask) {
1186                 case AFE_PORT_I2S_SD0_MASK:
1187                         pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0;
1188                         break;
1189                 case AFE_PORT_I2S_SD1_MASK:
1190                         pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD1;
1191                         break;
1192                 case AFE_PORT_I2S_SD2_MASK:
1193                         pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2;
1194                         break;
1195                 case AFE_PORT_I2S_SD3_MASK:
1196                         pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD3;
1197                         break;
1198                 default:
1199                         dev_err(dev, "Invalid SD lines\n");
1200                         return -EINVAL;
1201                 }
1202                 break;
1203         case 2:
1204                 switch (cfg->sd_line_mask) {
1205                 case AFE_PORT_I2S_SD0_1_MASK:
1206                         pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD01;
1207                         break;
1208                 case AFE_PORT_I2S_SD2_3_MASK:
1209                         pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD23;
1210                         break;
1211                 default:
1212                         dev_err(dev, "Invalid SD lines\n");
1213                         return -EINVAL;
1214                 }
1215                 break;
1216         case 3:
1217                 switch (cfg->sd_line_mask) {
1218                 case AFE_PORT_I2S_SD0_1_2_MASK:
1219                         pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_6CHS;
1220                         break;
1221                 default:
1222                         dev_err(dev, "Invalid SD lines\n");
1223                         return -EINVAL;
1224                 }
1225                 break;
1226         case 4:
1227                 switch (cfg->sd_line_mask) {
1228                 case AFE_PORT_I2S_SD0_1_2_3_MASK:
1229                         pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_8CHS;
1230 
1231                         break;
1232                 default:
1233                         dev_err(dev, "Invalid SD lines\n");
1234                         return -EINVAL;
1235                 }
1236                 break;
1237         default:
1238                 dev_err(dev, "Invalid SD lines\n");
1239                 return -EINVAL;
1240         }
1241 
1242         switch (cfg->num_channels) {
1243         case 1:
1244         case 2:
1245                 switch (pcfg->i2s_cfg.channel_mode) {
1246                 case AFE_PORT_I2S_QUAD01:
1247                 case AFE_PORT_I2S_6CHS:
1248                 case AFE_PORT_I2S_8CHS:
1249                         pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0;
1250                         break;
1251                 case AFE_PORT_I2S_QUAD23:
1252                                 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2;
1253                         break;
1254                 }
1255 
1256                 if (cfg->num_channels == 2)
1257                         pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_STEREO;
1258                 else
1259                         pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_MONO;
1260 
1261                 break;
1262         case 3:
1263         case 4:
1264                 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_QUAD01) {
1265                         dev_err(dev, "Invalid Channel mode\n");
1266                         return -EINVAL;
1267                 }
1268                 break;
1269         case 5:
1270         case 6:
1271                 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_6CHS) {
1272                         dev_err(dev, "Invalid Channel mode\n");
1273                         return -EINVAL;
1274                 }
1275                 break;
1276         case 7:
1277         case 8:
1278                 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_8CHS) {
1279                         dev_err(dev, "Invalid Channel mode\n");
1280                         return -EINVAL;
1281                 }
1282                 break;
1283         default:
1284                 break;
1285         }
1286 
1287         return 0;
1288 }
1289 EXPORT_SYMBOL_GPL(q6afe_i2s_port_prepare);
1290 
1291 /**
1292  * q6afe_port_start() - Start a afe port
1293  *
1294  * @port: Instance of port to start
1295  *
1296  * Return: Will be an negative on packet size on success.
1297  */
1298 int q6afe_port_start(struct q6afe_port *port)
1299 {
1300         struct afe_port_cmd_device_start *start;
1301         struct q6afe *afe = port->afe;
1302         int port_id = port->id;
1303         int ret, param_id = port->cfg_type;
1304         struct apr_pkt *pkt;
1305         int pkt_size;
1306         void *p;
1307 
1308         ret  = q6afe_port_set_param_v2(port, &port->port_cfg, param_id,
1309                                        AFE_MODULE_AUDIO_DEV_INTERFACE,
1310                                        sizeof(port->port_cfg));
1311         if (ret) {
1312                 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1313                         port_id, ret);
1314                 return ret;
1315         }
1316 
1317         if (port->scfg) {
1318                 ret  = q6afe_port_set_param_v2(port, port->scfg,
1319                                         AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG,
1320                                         AFE_MODULE_TDM, sizeof(*port->scfg));
1321                 if (ret) {
1322                         dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1323                         port_id, ret);
1324                         return ret;
1325                 }
1326         }
1327 
1328         pkt_size = APR_HDR_SIZE + sizeof(*start);
1329         p = kzalloc(pkt_size, GFP_KERNEL);
1330         if (!p)
1331                 return -ENOMEM;
1332 
1333         pkt = p;
1334         start = p + APR_HDR_SIZE;
1335 
1336         pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1337                                             APR_HDR_LEN(APR_HDR_SIZE),
1338                                             APR_PKT_VER);
1339         pkt->hdr.pkt_size = pkt_size;
1340         pkt->hdr.src_port = 0;
1341         pkt->hdr.dest_port = 0;
1342         pkt->hdr.token = port->token;
1343         pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_START;
1344 
1345         start->port_id = port_id;
1346 
1347         ret = afe_apr_send_pkt(afe, pkt, port);
1348         if (ret)
1349                 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1350                         port_id, ret);
1351 
1352         kfree(pkt);
1353         return ret;
1354 }
1355 EXPORT_SYMBOL_GPL(q6afe_port_start);
1356 
1357 /**
1358  * q6afe_port_get_from_id() - Get port instance from a port id
1359  *
1360  * @dev: Pointer to afe child device.
1361  * @id: port id
1362  *
1363  * Return: Will be an error pointer on error or a valid afe port
1364  * on success.
1365  */
1366 struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id)
1367 {
1368         int port_id;
1369         struct q6afe *afe = dev_get_drvdata(dev->parent);
1370         struct q6afe_port *port;
1371         unsigned long flags;
1372         int cfg_type;
1373 
1374         if (id < 0 || id >= AFE_PORT_MAX) {
1375                 dev_err(dev, "AFE port token[%d] invalid!\n", id);
1376                 return ERR_PTR(-EINVAL);
1377         }
1378 
1379         /* if port is multiple times bind/unbind before callback finishes */
1380         port = q6afe_find_port(afe, id);
1381         if (port) {
1382                 dev_err(dev, "AFE Port already open\n");
1383                 return port;
1384         }
1385 
1386         port_id = port_maps[id].port_id;
1387 
1388         switch (port_id) {
1389         case AFE_PORT_ID_MULTICHAN_HDMI_RX:
1390         case AFE_PORT_ID_HDMI_OVER_DP_RX:
1391                 cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
1392                 break;
1393         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX:
1394         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX:
1395         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX:
1396         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX:
1397         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX:
1398         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX:
1399         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX:
1400         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX:
1401         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX:
1402         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX:
1403         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX:
1404         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX:
1405         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX:
1406         case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX:
1407                 cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG;
1408                 break;
1409 
1410         case AFE_PORT_ID_PRIMARY_MI2S_RX:
1411         case AFE_PORT_ID_PRIMARY_MI2S_TX:
1412         case AFE_PORT_ID_SECONDARY_MI2S_RX:
1413         case AFE_PORT_ID_SECONDARY_MI2S_TX:
1414         case AFE_PORT_ID_TERTIARY_MI2S_RX:
1415         case AFE_PORT_ID_TERTIARY_MI2S_TX:
1416         case AFE_PORT_ID_QUATERNARY_MI2S_RX:
1417         case AFE_PORT_ID_QUATERNARY_MI2S_TX:
1418                 cfg_type = AFE_PARAM_ID_I2S_CONFIG;
1419                 break;
1420         case AFE_PORT_ID_PRIMARY_TDM_RX ... AFE_PORT_ID_QUINARY_TDM_TX_7:
1421                 cfg_type = AFE_PARAM_ID_TDM_CONFIG;
1422                 break;
1423 
1424         default:
1425                 dev_err(dev, "Invalid port id 0x%x\n", port_id);
1426                 return ERR_PTR(-EINVAL);
1427         }
1428 
1429         port = kzalloc(sizeof(*port), GFP_KERNEL);
1430         if (!port)
1431                 return ERR_PTR(-ENOMEM);
1432 
1433         init_waitqueue_head(&port->wait);
1434 
1435         port->token = id;
1436         port->id = port_id;
1437         port->afe = afe;
1438         port->cfg_type = cfg_type;
1439         kref_init(&port->refcount);
1440 
1441         spin_lock_irqsave(&afe->port_list_lock, flags);
1442         list_add_tail(&port->node, &afe->port_list);
1443         spin_unlock_irqrestore(&afe->port_list_lock, flags);
1444 
1445         return port;
1446 
1447 }
1448 EXPORT_SYMBOL_GPL(q6afe_port_get_from_id);
1449 
1450 /**
1451  * q6afe_port_put() - Release port reference
1452  *
1453  * @port: Instance of port to put
1454  */
1455 void q6afe_port_put(struct q6afe_port *port)
1456 {
1457         kref_put(&port->refcount, q6afe_port_free);
1458 }
1459 EXPORT_SYMBOL_GPL(q6afe_port_put);
1460 
1461 static int q6afe_probe(struct apr_device *adev)
1462 {
1463         struct q6afe *afe;
1464         struct device *dev = &adev->dev;
1465 
1466         afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL);
1467         if (!afe)
1468                 return -ENOMEM;
1469 
1470         q6core_get_svc_api_info(adev->svc_id, &afe->ainfo);
1471         afe->apr = adev;
1472         mutex_init(&afe->lock);
1473         afe->dev = dev;
1474         INIT_LIST_HEAD(&afe->port_list);
1475         spin_lock_init(&afe->port_list_lock);
1476 
1477         dev_set_drvdata(dev, afe);
1478 
1479         return of_platform_populate(dev->of_node, NULL, NULL, dev);
1480 }
1481 
1482 static int q6afe_remove(struct apr_device *adev)
1483 {
1484         of_platform_depopulate(&adev->dev);
1485 
1486         return 0;
1487 }
1488 
1489 static const struct of_device_id q6afe_device_id[]  = {
1490         { .compatible = "qcom,q6afe" },
1491         {},
1492 };
1493 MODULE_DEVICE_TABLE(of, q6afe_device_id);
1494 
1495 static struct apr_driver qcom_q6afe_driver = {
1496         .probe = q6afe_probe,
1497         .remove = q6afe_remove,
1498         .callback = q6afe_callback,
1499         .driver = {
1500                 .name = "qcom-q6afe",
1501                 .of_match_table = of_match_ptr(q6afe_device_id),
1502 
1503         },
1504 };
1505 
1506 module_apr_driver(qcom_q6afe_driver);
1507 MODULE_DESCRIPTION("Q6 Audio Front End");
1508 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */