Lines Matching +full:usb +full:- +full:port +full:- +full:id

1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
5 #include <dt-bindings/sound/qcom,q6afe.h>
20 #include <sound/soc-dai.h>
23 #include "q6dsp-errno.h"
80 /* Port IDs */
85 /* USB AFE port */
95 /* SLIMbus Rx port on channel 0. */
97 /* SLIMbus Tx port on channel 0. */
99 /* SLIMbus Rx port on channel 1. */
101 /* SLIMbus Tx port on channel 1. */
103 /* SLIMbus Rx port on channel 2. */
105 /* SLIMbus Tx port on channel 2. */
107 /* SLIMbus Rx port on channel 3. */
109 /* SLIMbus Tx port on channel 3. */
111 /* SLIMbus Rx port on channel 4. */
113 /* SLIMbus Tx port on channel 4. */
115 /* SLIMbus Rx port on channel 5. */
117 /* SLIMbus Tx port on channel 5. */
119 /* SLIMbus Rx port on channel 6. */
121 /* SLIMbus Tx port on channel 6. */
134 /* Start of the range of port IDs for TDM devices. */
137 /* End of the range of port IDs for TDM devices. */
139 (AFE_PORT_ID_TDM_PORT_RANGE_START+0x50-1)
141 /* Size of the range of port IDs for TDM ports. */
143 (AFE_PORT_ID_TDM_PORT_RANGE_END - \
316 /* AFE WSA Codec DMA Rx port 0 */
318 /* AFE WSA Codec DMA Tx port 0 */
320 /* AFE WSA Codec DMA Rx port 1 */
322 /* AFE WSA Codec DMA Tx port 1 */
324 /* AFE WSA Codec DMA Tx port 2 */
326 /* AFE VA Codec DMA Tx port 0 */
328 /* AFE VA Codec DMA Tx port 1 */
330 /* AFE VA Codec DMA Tx port 2 */
332 /* AFE Rx Codec DMA Rx port 0 */
334 /* AFE Tx Codec DMA Tx port 0 */
336 /* AFE Rx Codec DMA Rx port 1 */
338 /* AFE Tx Codec DMA Tx port 1 */
340 /* AFE Rx Codec DMA Rx port 2 */
342 /* AFE Tx Codec DMA Tx port 2 */
344 /* AFE Rx Codec DMA Rx port 3 */
346 /* AFE Tx Codec DMA Tx port 3 */
348 /* AFE Rx Codec DMA Rx port 4 */
350 /* AFE Tx Codec DMA Tx port 4 */
352 /* AFE Rx Codec DMA Rx port 5 */
354 /* AFE Tx Codec DMA Tx port 5 */
356 /* AFE Rx Codec DMA Rx port 6 */
358 /* AFE Rx Codec DMA Rx port 7 */
393 /* Reserved for 32-bit alignment. This field must be set to 0.*/
435 /* SLIMbus hardware device ID, which is required to handle
437 * Supported values: - #AFE_SLIMBUS_DEVICE_1 - #AFE_SLIMBUS_DEVICE_2
455 * master port is to be connected.
460 /* Sampling rate of the port.
462 * - #AFE_PORT_SAMPLE_RATE_8K
463 * - #AFE_PORT_SAMPLE_RATE_16K
464 * - #AFE_PORT_SAMPLE_RATE_48K
465 * - #AFE_PORT_SAMPLE_RATE_96K
466 * - #AFE_PORT_SAMPLE_RATE_192K
524 /* Minor version used for tracking USB audio device configuration.
528 /* Sampling rate of the port.
530 * - AFE_PORT_SAMPLE_RATE_8K
531 * - AFE_PORT_SAMPLE_RATE_11025
532 * - AFE_PORT_SAMPLE_RATE_12K
533 * - AFE_PORT_SAMPLE_RATE_16K
534 * - AFE_PORT_SAMPLE_RATE_22050
535 * - AFE_PORT_SAMPLE_RATE_24K
536 * - AFE_PORT_SAMPLE_RATE_32K
537 * - AFE_PORT_SAMPLE_RATE_44P1K
538 * - AFE_PORT_SAMPLE_RATE_48K
539 * - AFE_PORT_SAMPLE_RATE_96K
540 * - AFE_PORT_SAMPLE_RATE_192K
551 /* Data format supported by the USB. The supported value is
557 /* device token of actual end USB audio device */
567 * @cfg_minor_version: Minor version used for tracking USB audio device
571 * @dev_token: device token of actual end USB audio device
580 * @cfg_minor_version: Minor version used for tracking USB audio device
595 * @cfg_minor_version: Minor version used for tracking USB audio device
639 int id; member
666 * Mapping between Virtual Port IDs to DSP AFE Port ID
667 * On B Family SoCs DSP Port IDs are consistent across multiple SoCs
668 * on A Family SoCs DSP port IDs are same as virtual Port IDs.
932 struct q6afe_port *port; in q6afe_port_free() local
936 port = container_of(ref, struct q6afe_port, refcount); in q6afe_port_free()
937 afe = port->afe; in q6afe_port_free()
938 spin_lock_irqsave(&afe->port_list_lock, flags); in q6afe_port_free()
939 list_del(&port->node); in q6afe_port_free()
940 spin_unlock_irqrestore(&afe->port_list_lock, flags); in q6afe_port_free()
941 kfree(port->scfg); in q6afe_port_free()
942 kfree(port); in q6afe_port_free()
951 spin_lock_irqsave(&afe->port_list_lock, flags); in q6afe_find_port()
952 list_for_each_entry(p, &afe->port_list, node) in q6afe_find_port()
953 if (p->token == token) { in q6afe_find_port()
955 kref_get(&p->refcount); in q6afe_find_port()
959 spin_unlock_irqrestore(&afe->port_list_lock, flags); in q6afe_find_port()
965 struct q6afe *afe = dev_get_drvdata(&adev->dev); in q6afe_callback()
967 struct apr_hdr *hdr = &data->hdr; in q6afe_callback()
968 struct q6afe_port *port; in q6afe_callback() local
970 if (!data->payload_size) in q6afe_callback()
973 res = data->payload; in q6afe_callback()
974 switch (hdr->opcode) { in q6afe_callback()
976 if (res->status) { in q6afe_callback()
977 dev_err(afe->dev, "cmd = 0x%x returned error = 0x%x\n", in q6afe_callback()
978 res->opcode, res->status); in q6afe_callback()
980 switch (res->opcode) { in q6afe_callback()
985 port = q6afe_find_port(afe, hdr->token); in q6afe_callback()
986 if (port) { in q6afe_callback()
987 port->result = *res; in q6afe_callback()
988 wake_up(&port->wait); in q6afe_callback()
989 kref_put(&port->refcount, q6afe_port_free); in q6afe_callback()
990 } else if (hdr->token == AFE_CLK_TOKEN) { in q6afe_callback()
991 afe->result = *res; in q6afe_callback()
992 wake_up(&afe->wait); in q6afe_callback()
996 dev_err(afe->dev, "Unknown cmd 0x%x\n", res->opcode); in q6afe_callback()
1002 afe->result.opcode = hdr->opcode; in q6afe_callback()
1003 afe->result.status = res->status; in q6afe_callback()
1004 wake_up(&afe->wait); in q6afe_callback()
1014 * q6afe_get_port_id() - Get port id from a given port index
1016 * @index: port index
1023 return -EINVAL; in q6afe_get_port_id()
1030 struct q6afe_port *port, uint32_t rsp_opcode) in afe_apr_send_pkt() argument
1036 mutex_lock(&afe->lock); in afe_apr_send_pkt()
1037 if (port) { in afe_apr_send_pkt()
1038 wait = &port->wait; in afe_apr_send_pkt()
1039 result = &port->result; in afe_apr_send_pkt()
1041 result = &afe->result; in afe_apr_send_pkt()
1042 wait = &afe->wait; in afe_apr_send_pkt()
1045 result->opcode = 0; in afe_apr_send_pkt()
1046 result->status = 0; in afe_apr_send_pkt()
1048 ret = apr_send_pkt(afe->apr, pkt); in afe_apr_send_pkt()
1050 dev_err(afe->dev, "packet not transmitted (%d)\n", ret); in afe_apr_send_pkt()
1051 ret = -EINVAL; in afe_apr_send_pkt()
1055 ret = wait_event_timeout(*wait, (result->opcode == rsp_opcode), in afe_apr_send_pkt()
1058 ret = -ETIMEDOUT; in afe_apr_send_pkt()
1059 } else if (result->status > 0) { in afe_apr_send_pkt()
1060 dev_err(afe->dev, "DSP returned error[%x]\n", in afe_apr_send_pkt()
1061 result->status); in afe_apr_send_pkt()
1062 ret = -EINVAL; in afe_apr_send_pkt()
1068 mutex_unlock(&afe->lock); in afe_apr_send_pkt()
1073 static int q6afe_set_param(struct q6afe *afe, struct q6afe_port *port, in q6afe_set_param() argument
1086 return -ENOMEM; in q6afe_set_param()
1094 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_set_param()
1097 pkt->hdr.pkt_size = pkt_size; in q6afe_set_param()
1098 pkt->hdr.src_port = 0; in q6afe_set_param()
1099 pkt->hdr.dest_port = 0; in q6afe_set_param()
1100 pkt->hdr.token = token; in q6afe_set_param()
1101 pkt->hdr.opcode = AFE_SVC_CMD_SET_PARAM; in q6afe_set_param()
1103 param->payload_size = sizeof(*pdata) + psize; in q6afe_set_param()
1104 param->payload_address_lsw = 0x00; in q6afe_set_param()
1105 param->payload_address_msw = 0x00; in q6afe_set_param()
1106 param->mem_map_handle = 0x00; in q6afe_set_param()
1107 pdata->module_id = module_id; in q6afe_set_param()
1108 pdata->param_id = param_id; in q6afe_set_param()
1109 pdata->param_size = psize; in q6afe_set_param()
1111 ret = afe_apr_send_pkt(afe, pkt, port, AFE_SVC_CMD_SET_PARAM); in q6afe_set_param()
1113 dev_err(afe->dev, "AFE set params failed %d\n", ret); in q6afe_set_param()
1119 static int q6afe_port_set_param(struct q6afe_port *port, void *data, in q6afe_port_set_param() argument
1122 return q6afe_set_param(port->afe, port, data, param_id, module_id, in q6afe_port_set_param()
1123 psize, port->token); in q6afe_port_set_param()
1126 static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data, in q6afe_port_set_param_v2() argument
1131 struct q6afe *afe = port->afe; in q6afe_port_set_param_v2()
1133 u16 port_id = port->id; in q6afe_port_set_param_v2()
1140 return -ENOMEM; in q6afe_port_set_param_v2()
1148 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_port_set_param_v2()
1151 pkt->hdr.pkt_size = pkt_size; in q6afe_port_set_param_v2()
1152 pkt->hdr.src_port = 0; in q6afe_port_set_param_v2()
1153 pkt->hdr.dest_port = 0; in q6afe_port_set_param_v2()
1154 pkt->hdr.token = port->token; in q6afe_port_set_param_v2()
1155 pkt->hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; in q6afe_port_set_param_v2()
1157 param->port_id = port_id; in q6afe_port_set_param_v2()
1158 param->payload_size = sizeof(*pdata) + psize; in q6afe_port_set_param_v2()
1159 param->payload_address_lsw = 0x00; in q6afe_port_set_param_v2()
1160 param->payload_address_msw = 0x00; in q6afe_port_set_param_v2()
1161 param->mem_map_handle = 0x00; in q6afe_port_set_param_v2()
1162 pdata->module_id = module_id; in q6afe_port_set_param_v2()
1163 pdata->param_id = param_id; in q6afe_port_set_param_v2()
1164 pdata->param_size = psize; in q6afe_port_set_param_v2()
1166 ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_SET_PARAM_V2); in q6afe_port_set_param_v2()
1168 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_set_param_v2()
1175 static int q6afe_port_set_lpass_clock(struct q6afe_port *port, in q6afe_port_set_lpass_clock() argument
1178 return q6afe_port_set_param_v2(port, cfg, in q6afe_port_set_lpass_clock()
1184 static int q6afe_set_lpass_clock_v2(struct q6afe_port *port, in q6afe_set_lpass_clock_v2() argument
1187 return q6afe_port_set_param(port, cfg, AFE_PARAM_ID_CLOCK_SET, in q6afe_set_lpass_clock_v2()
1191 static int q6afe_set_digital_codec_core_clock(struct q6afe_port *port, in q6afe_set_digital_codec_core_clock() argument
1194 return q6afe_port_set_param_v2(port, cfg, in q6afe_set_digital_codec_core_clock()
1203 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_set_lpass_clock()
1219 int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id, in q6afe_port_set_sysclk() argument
1233 ret = q6afe_set_digital_codec_core_clock(port, &dcfg); in q6afe_port_set_sysclk()
1241 ret = q6afe_port_set_lpass_clock(port, &ccfg); in q6afe_port_set_sysclk()
1250 ret = q6afe_port_set_lpass_clock(port, &ccfg); in q6afe_port_set_sysclk()
1262 ret = q6afe_set_lpass_clock_v2(port, &cset); in q6afe_port_set_sysclk()
1265 ret = -EINVAL; in q6afe_port_set_sysclk()
1274 * q6afe_port_stop() - Stop a afe port
1276 * @port: Instance of port to stop
1280 int q6afe_port_stop(struct q6afe_port *port) in q6afe_port_stop() argument
1283 struct q6afe *afe = port->afe; in q6afe_port_stop()
1285 int port_id = port->id; in q6afe_port_stop()
1290 index = port->token; in q6afe_port_stop()
1292 dev_err(afe->dev, "AFE port index[%d] invalid!\n", index); in q6afe_port_stop()
1293 return -EINVAL; in q6afe_port_stop()
1299 return -ENOMEM; in q6afe_port_stop()
1304 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_port_stop()
1307 pkt->hdr.pkt_size = pkt_size; in q6afe_port_stop()
1308 pkt->hdr.src_port = 0; in q6afe_port_stop()
1309 pkt->hdr.dest_port = 0; in q6afe_port_stop()
1310 pkt->hdr.token = index; in q6afe_port_stop()
1311 pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_STOP; in q6afe_port_stop()
1312 stop->port_id = port_id; in q6afe_port_stop()
1313 stop->reserved = 0; in q6afe_port_stop()
1315 ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_DEVICE_STOP); in q6afe_port_stop()
1317 dev_err(afe->dev, "AFE close failed %d\n", ret); in q6afe_port_stop()
1325 * q6afe_slim_port_prepare() - Prepare slim afe port.
1327 * @port: Instance of afe port
1328 * @cfg: SLIM configuration for the afe port
1331 void q6afe_slim_port_prepare(struct q6afe_port *port, in q6afe_slim_port_prepare() argument
1334 union afe_port_config *pcfg = &port->port_cfg; in q6afe_slim_port_prepare()
1336 pcfg->slim_cfg.sb_cfg_minor_version = AFE_API_VERSION_SLIMBUS_CONFIG; in q6afe_slim_port_prepare()
1337 pcfg->slim_cfg.sample_rate = cfg->sample_rate; in q6afe_slim_port_prepare()
1338 pcfg->slim_cfg.bit_width = cfg->bit_width; in q6afe_slim_port_prepare()
1339 pcfg->slim_cfg.num_channels = cfg->num_channels; in q6afe_slim_port_prepare()
1340 pcfg->slim_cfg.data_format = cfg->data_format; in q6afe_slim_port_prepare()
1341 pcfg->slim_cfg.shared_ch_mapping[0] = cfg->ch_mapping[0]; in q6afe_slim_port_prepare()
1342 pcfg->slim_cfg.shared_ch_mapping[1] = cfg->ch_mapping[1]; in q6afe_slim_port_prepare()
1343 pcfg->slim_cfg.shared_ch_mapping[2] = cfg->ch_mapping[2]; in q6afe_slim_port_prepare()
1344 pcfg->slim_cfg.shared_ch_mapping[3] = cfg->ch_mapping[3]; in q6afe_slim_port_prepare()
1350 * q6afe_tdm_port_prepare() - Prepare tdm afe port.
1352 * @port: Instance of afe port
1353 * @cfg: TDM configuration for the afe port
1356 void q6afe_tdm_port_prepare(struct q6afe_port *port, in q6afe_tdm_port_prepare() argument
1359 union afe_port_config *pcfg = &port->port_cfg; in q6afe_tdm_port_prepare()
1361 pcfg->tdm_cfg.tdm_cfg_minor_version = AFE_API_VERSION_TDM_CONFIG; in q6afe_tdm_port_prepare()
1362 pcfg->tdm_cfg.num_channels = cfg->num_channels; in q6afe_tdm_port_prepare()
1363 pcfg->tdm_cfg.sample_rate = cfg->sample_rate; in q6afe_tdm_port_prepare()
1364 pcfg->tdm_cfg.bit_width = cfg->bit_width; in q6afe_tdm_port_prepare()
1365 pcfg->tdm_cfg.data_format = cfg->data_format; in q6afe_tdm_port_prepare()
1366 pcfg->tdm_cfg.sync_mode = cfg->sync_mode; in q6afe_tdm_port_prepare()
1367 pcfg->tdm_cfg.sync_src = cfg->sync_src; in q6afe_tdm_port_prepare()
1368 pcfg->tdm_cfg.nslots_per_frame = cfg->nslots_per_frame; in q6afe_tdm_port_prepare()
1370 pcfg->tdm_cfg.slot_width = cfg->slot_width; in q6afe_tdm_port_prepare()
1371 pcfg->tdm_cfg.slot_mask = cfg->slot_mask; in q6afe_tdm_port_prepare()
1372 port->scfg = kzalloc(sizeof(*port->scfg), GFP_KERNEL); in q6afe_tdm_port_prepare()
1373 if (!port->scfg) in q6afe_tdm_port_prepare()
1376 port->scfg->minor_version = AFE_API_VERSION_SLOT_MAPPING_CONFIG; in q6afe_tdm_port_prepare()
1377 port->scfg->num_channels = cfg->num_channels; in q6afe_tdm_port_prepare()
1378 port->scfg->bitwidth = cfg->bit_width; in q6afe_tdm_port_prepare()
1379 port->scfg->data_align_type = cfg->data_align_type; in q6afe_tdm_port_prepare()
1380 memcpy(port->scfg->ch_mapping, cfg->ch_mapping, in q6afe_tdm_port_prepare()
1386 * afe_port_send_usb_dev_param() - Send USB dev token
1388 * @port: Instance of afe port
1389 * @cardidx: USB SND card index to reference
1390 * @pcmidx: USB SND PCM device index to reference
1392 * The USB dev token carries information about which USB SND card instance and
1395 * driver. The information is parsed to determine which USB device to query
1398 int afe_port_send_usb_dev_param(struct q6afe_port *port, int cardidx, int pcmidx) in afe_port_send_usb_dev_param() argument
1407 ret = q6afe_port_set_param_v2(port, &usb_dev, in afe_port_send_usb_dev_param()
1412 dev_err(port->afe->dev, "%s: AFE device param cmd failed %d\n", in afe_port_send_usb_dev_param()
1419 static int afe_port_send_usb_params(struct q6afe_port *port, struct q6afe_usb_cfg *cfg) in afe_port_send_usb_params() argument
1421 union afe_port_config *pcfg = &port->port_cfg; in afe_port_send_usb_params()
1427 dev_err(port->afe->dev, "%s: Error, no configuration data\n", __func__); in afe_port_send_usb_params()
1428 return -EINVAL; in afe_port_send_usb_params()
1435 lpcm_fmt.endian = pcfg->usb_cfg.endian; in afe_port_send_usb_params()
1436 ret = q6afe_port_set_param_v2(port, &lpcm_fmt, in afe_port_send_usb_params()
1440 dev_err(port->afe->dev, "%s: AFE device param cmd LPCM_FMT failed %d\n", in afe_port_send_usb_params()
1446 svc_int.svc_interval = pcfg->usb_cfg.service_interval; in afe_port_send_usb_params()
1447 ret = q6afe_port_set_param_v2(port, &svc_int, in afe_port_send_usb_params()
1451 dev_err(port->afe->dev, "%s: AFE device param cmd svc_interval failed %d\n", in afe_port_send_usb_params()
1458 * q6afe_usb_port_prepare() - Prepare usb afe port.
1460 * @port: Instance of afe port
1461 * @cfg: USB configuration for the afe port
1464 void q6afe_usb_port_prepare(struct q6afe_port *port, in q6afe_usb_port_prepare() argument
1467 union afe_port_config *pcfg = &port->port_cfg; in q6afe_usb_port_prepare()
1469 pcfg->usb_cfg.cfg_minor_version = AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG; in q6afe_usb_port_prepare()
1470 pcfg->usb_cfg.sample_rate = cfg->sample_rate; in q6afe_usb_port_prepare()
1471 pcfg->usb_cfg.num_channels = cfg->num_channels; in q6afe_usb_port_prepare()
1472 pcfg->usb_cfg.bit_width = cfg->bit_width; in q6afe_usb_port_prepare()
1474 afe_port_send_usb_params(port, cfg); in q6afe_usb_port_prepare()
1479 * q6afe_hdmi_port_prepare() - Prepare hdmi afe port.
1481 * @port: Instance of afe port
1482 * @cfg: HDMI configuration for the afe port
1485 void q6afe_hdmi_port_prepare(struct q6afe_port *port, in q6afe_hdmi_port_prepare() argument
1488 union afe_port_config *pcfg = &port->port_cfg; in q6afe_hdmi_port_prepare()
1490 pcfg->hdmi_multi_ch.hdmi_cfg_minor_version = in q6afe_hdmi_port_prepare()
1492 pcfg->hdmi_multi_ch.datatype = cfg->datatype; in q6afe_hdmi_port_prepare()
1493 pcfg->hdmi_multi_ch.channel_allocation = cfg->channel_allocation; in q6afe_hdmi_port_prepare()
1494 pcfg->hdmi_multi_ch.sample_rate = cfg->sample_rate; in q6afe_hdmi_port_prepare()
1495 pcfg->hdmi_multi_ch.bit_width = cfg->bit_width; in q6afe_hdmi_port_prepare()
1500 * q6afe_i2s_port_prepare() - Prepare i2s afe port.
1502 * @port: Instance of afe port
1503 * @cfg: I2S configuration for the afe port
1506 int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg) in q6afe_i2s_port_prepare() argument
1508 union afe_port_config *pcfg = &port->port_cfg; in q6afe_i2s_port_prepare()
1509 struct device *dev = port->afe->dev; in q6afe_i2s_port_prepare()
1512 pcfg->i2s_cfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG; in q6afe_i2s_port_prepare()
1513 pcfg->i2s_cfg.sample_rate = cfg->sample_rate; in q6afe_i2s_port_prepare()
1514 pcfg->i2s_cfg.bit_width = cfg->bit_width; in q6afe_i2s_port_prepare()
1515 pcfg->i2s_cfg.data_format = AFE_LINEAR_PCM_DATA; in q6afe_i2s_port_prepare()
1517 switch (cfg->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { in q6afe_i2s_port_prepare()
1519 pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL; in q6afe_i2s_port_prepare()
1523 pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL; in q6afe_i2s_port_prepare()
1529 num_sd_lines = hweight_long(cfg->sd_line_mask); in q6afe_i2s_port_prepare()
1534 return -EINVAL; in q6afe_i2s_port_prepare()
1536 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1538 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0; in q6afe_i2s_port_prepare()
1541 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD1; in q6afe_i2s_port_prepare()
1544 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2; in q6afe_i2s_port_prepare()
1547 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD3; in q6afe_i2s_port_prepare()
1551 return -EINVAL; in q6afe_i2s_port_prepare()
1555 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1557 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD01; in q6afe_i2s_port_prepare()
1560 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD23; in q6afe_i2s_port_prepare()
1564 return -EINVAL; in q6afe_i2s_port_prepare()
1568 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1570 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_6CHS; in q6afe_i2s_port_prepare()
1574 return -EINVAL; in q6afe_i2s_port_prepare()
1578 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1580 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_8CHS; in q6afe_i2s_port_prepare()
1585 return -EINVAL; in q6afe_i2s_port_prepare()
1590 return -EINVAL; in q6afe_i2s_port_prepare()
1593 switch (cfg->num_channels) { in q6afe_i2s_port_prepare()
1596 switch (pcfg->i2s_cfg.channel_mode) { in q6afe_i2s_port_prepare()
1600 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0; in q6afe_i2s_port_prepare()
1603 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2; in q6afe_i2s_port_prepare()
1607 if (cfg->num_channels == 2) in q6afe_i2s_port_prepare()
1608 pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_STEREO; in q6afe_i2s_port_prepare()
1610 pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_MONO; in q6afe_i2s_port_prepare()
1615 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_QUAD01) { in q6afe_i2s_port_prepare()
1617 return -EINVAL; in q6afe_i2s_port_prepare()
1622 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_6CHS) { in q6afe_i2s_port_prepare()
1624 return -EINVAL; in q6afe_i2s_port_prepare()
1629 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_8CHS) { in q6afe_i2s_port_prepare()
1631 return -EINVAL; in q6afe_i2s_port_prepare()
1643 * q6afe_cdc_dma_port_prepare() - Prepare dma afe port.
1645 * @port: Instance of afe port
1646 * @cfg: DMA configuration for the afe port
1649 void q6afe_cdc_dma_port_prepare(struct q6afe_port *port, in q6afe_cdc_dma_port_prepare() argument
1652 union afe_port_config *pcfg = &port->port_cfg; in q6afe_cdc_dma_port_prepare()
1653 struct afe_param_id_cdc_dma_cfg *dma_cfg = &pcfg->dma_cfg; in q6afe_cdc_dma_port_prepare()
1655 dma_cfg->cdc_dma_cfg_minor_version = AFE_API_VERSION_CODEC_DMA_CONFIG; in q6afe_cdc_dma_port_prepare()
1656 dma_cfg->sample_rate = cfg->sample_rate; in q6afe_cdc_dma_port_prepare()
1657 dma_cfg->bit_width = cfg->bit_width; in q6afe_cdc_dma_port_prepare()
1658 dma_cfg->data_format = cfg->data_format; in q6afe_cdc_dma_port_prepare()
1659 dma_cfg->num_channels = cfg->num_channels; in q6afe_cdc_dma_port_prepare()
1660 if (!cfg->active_channels_mask) in q6afe_cdc_dma_port_prepare()
1661 dma_cfg->active_channels_mask = (1 << cfg->num_channels) - 1; in q6afe_cdc_dma_port_prepare()
1665 * q6afe_port_start() - Start a afe port
1667 * @port: Instance of port to start
1671 int q6afe_port_start(struct q6afe_port *port) in q6afe_port_start() argument
1674 struct q6afe *afe = port->afe; in q6afe_port_start()
1675 int port_id = port->id; in q6afe_port_start()
1676 int ret, param_id = port->cfg_type; in q6afe_port_start()
1681 ret = q6afe_port_set_param_v2(port, &port->port_cfg, param_id, in q6afe_port_start()
1683 sizeof(port->port_cfg)); in q6afe_port_start()
1685 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_start()
1690 if (port->scfg) { in q6afe_port_start()
1691 ret = q6afe_port_set_param_v2(port, port->scfg, in q6afe_port_start()
1693 AFE_MODULE_TDM, sizeof(*port->scfg)); in q6afe_port_start()
1695 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_start()
1704 return -ENOMEM; in q6afe_port_start()
1709 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_port_start()
1712 pkt->hdr.pkt_size = pkt_size; in q6afe_port_start()
1713 pkt->hdr.src_port = 0; in q6afe_port_start()
1714 pkt->hdr.dest_port = 0; in q6afe_port_start()
1715 pkt->hdr.token = port->token; in q6afe_port_start()
1716 pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_START; in q6afe_port_start()
1718 start->port_id = port_id; in q6afe_port_start()
1720 ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_DEVICE_START); in q6afe_port_start()
1722 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_start()
1731 * q6afe_port_get_from_id() - Get port instance from a port id
1734 * @id: port id
1736 * Return: Will be an error pointer on error or a valid afe port
1739 struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id) in q6afe_port_get_from_id() argument
1742 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_port_get_from_id()
1743 struct q6afe_port *port; in q6afe_port_get_from_id() local
1747 if (id < 0 || id >= AFE_PORT_MAX) { in q6afe_port_get_from_id()
1748 dev_err(dev, "AFE port token[%d] invalid!\n", id); in q6afe_port_get_from_id()
1749 return ERR_PTR(-EINVAL); in q6afe_port_get_from_id()
1752 /* if port is multiple times bind/unbind before callback finishes */ in q6afe_port_get_from_id()
1753 port = q6afe_find_port(afe, id); in q6afe_port_get_from_id()
1754 if (port) { in q6afe_port_get_from_id()
1755 dev_err(dev, "AFE Port already open\n"); in q6afe_port_get_from_id()
1756 return port; in q6afe_port_get_from_id()
1759 port_id = port_maps[id].port_id; in q6afe_port_get_from_id()
1805 dev_err(dev, "Invalid port id 0x%x\n", port_id); in q6afe_port_get_from_id()
1806 return ERR_PTR(-EINVAL); in q6afe_port_get_from_id()
1809 port = kzalloc(sizeof(*port), GFP_KERNEL); in q6afe_port_get_from_id()
1810 if (!port) in q6afe_port_get_from_id()
1811 return ERR_PTR(-ENOMEM); in q6afe_port_get_from_id()
1813 init_waitqueue_head(&port->wait); in q6afe_port_get_from_id()
1815 port->token = id; in q6afe_port_get_from_id()
1816 port->id = port_id; in q6afe_port_get_from_id()
1817 port->afe = afe; in q6afe_port_get_from_id()
1818 port->cfg_type = cfg_type; in q6afe_port_get_from_id()
1819 kref_init(&port->refcount); in q6afe_port_get_from_id()
1821 spin_lock_irqsave(&afe->port_list_lock, flags); in q6afe_port_get_from_id()
1822 list_add_tail(&port->node, &afe->port_list); in q6afe_port_get_from_id()
1823 spin_unlock_irqrestore(&afe->port_list_lock, flags); in q6afe_port_get_from_id()
1825 return port; in q6afe_port_get_from_id()
1831 * q6afe_port_put() - Release port reference
1833 * @port: Instance of port to put
1835 void q6afe_port_put(struct q6afe_port *port) in q6afe_port_put() argument
1837 kref_put(&port->refcount, q6afe_port_free); in q6afe_port_put()
1844 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_unvote_lpass_core_hw()
1854 return -ENOMEM; in q6afe_unvote_lpass_core_hw()
1859 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_unvote_lpass_core_hw()
1862 pkt->hdr.pkt_size = pkt_size; in q6afe_unvote_lpass_core_hw()
1863 pkt->hdr.src_port = 0; in q6afe_unvote_lpass_core_hw()
1864 pkt->hdr.dest_port = 0; in q6afe_unvote_lpass_core_hw()
1865 pkt->hdr.token = hw_block_id; in q6afe_unvote_lpass_core_hw()
1866 pkt->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST; in q6afe_unvote_lpass_core_hw()
1867 vote_cfg->hw_block_id = hw_block_id; in q6afe_unvote_lpass_core_hw()
1868 vote_cfg->client_handle = client_handle; in q6afe_unvote_lpass_core_hw()
1870 ret = apr_send_pkt(afe->apr, pkt); in q6afe_unvote_lpass_core_hw()
1872 dev_err(afe->dev, "AFE failed to unvote (%d)\n", hw_block_id); in q6afe_unvote_lpass_core_hw()
1882 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_vote_lpass_core_hw()
1892 return -ENOMEM; in q6afe_vote_lpass_core_hw()
1897 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_vote_lpass_core_hw()
1900 pkt->hdr.pkt_size = pkt_size; in q6afe_vote_lpass_core_hw()
1901 pkt->hdr.src_port = 0; in q6afe_vote_lpass_core_hw()
1902 pkt->hdr.dest_port = 0; in q6afe_vote_lpass_core_hw()
1903 pkt->hdr.token = hw_block_id; in q6afe_vote_lpass_core_hw()
1904 pkt->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST; in q6afe_vote_lpass_core_hw()
1905 vote_cfg->hw_block_id = hw_block_id; in q6afe_vote_lpass_core_hw()
1906 strscpy(vote_cfg->client_name, client_name, in q6afe_vote_lpass_core_hw()
1907 sizeof(vote_cfg->client_name)); in q6afe_vote_lpass_core_hw()
1912 dev_err(afe->dev, "AFE failed to vote (%d)\n", hw_block_id); in q6afe_vote_lpass_core_hw()
1923 struct device *dev = &adev->dev; in q6afe_probe()
1927 return -ENOMEM; in q6afe_probe()
1929 q6core_get_svc_api_info(adev->svc_id, &afe->ainfo); in q6afe_probe()
1930 afe->apr = adev; in q6afe_probe()
1931 mutex_init(&afe->lock); in q6afe_probe()
1932 init_waitqueue_head(&afe->wait); in q6afe_probe()
1933 afe->dev = dev; in q6afe_probe()
1934 INIT_LIST_HEAD(&afe->port_list); in q6afe_probe()
1935 spin_lock_init(&afe->port_list_lock); in q6afe_probe()
1954 .name = "qcom-q6afe",