Lines Matching +full:port +full:- +full:1
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
19 #include <sound/soc-dai.h>
22 #include "q6dsp-errno.h"
60 #define AFE_PORT_I2S_SD0_1_MASK GENMASK(1, 0)
75 /* Port IDs */
82 #define AFE_API_VERSION_CLOCK_SET 1
87 /* SLIMbus Rx port on channel 0. */
89 /* SLIMbus Tx port on channel 0. */
91 /* SLIMbus Rx port on channel 1. */
93 /* SLIMbus Tx port on channel 1. */
95 /* SLIMbus Rx port on channel 2. */
97 /* SLIMbus Tx port on channel 2. */
99 /* SLIMbus Rx port on channel 3. */
101 /* SLIMbus Tx port on channel 3. */
103 /* SLIMbus Rx port on channel 4. */
105 /* SLIMbus Tx port on channel 4. */
107 /* SLIMbus Rx port on channel 5. */
109 /* SLIMbus Tx port on channel 5. */
111 /* SLIMbus Rx port on channel 6. */
113 /* SLIMbus Tx port on channel 6. */
124 /* Start of the range of port IDs for TDM devices. */
127 /* End of the range of port IDs for TDM devices. */
129 (AFE_PORT_ID_TDM_PORT_RANGE_START+0x50-1)
131 /* Size of the range of port IDs for TDM ports. */
133 (AFE_PORT_ID_TDM_PORT_RANGE_END - \
134 AFE_PORT_ID_TDM_PORT_RANGE_START+1)
306 /* AFE WSA Codec DMA Rx port 0 */
308 /* AFE WSA Codec DMA Tx port 0 */
310 /* AFE WSA Codec DMA Rx port 1 */
312 /* AFE WSA Codec DMA Tx port 1 */
314 /* AFE WSA Codec DMA Tx port 2 */
316 /* AFE VA Codec DMA Tx port 0 */
318 /* AFE VA Codec DMA Tx port 1 */
320 /* AFE VA Codec DMA Tx port 2 */
322 /* AFE Rx Codec DMA Rx port 0 */
324 /* AFE Tx Codec DMA Tx port 0 */
326 /* AFE Rx Codec DMA Rx port 1 */
328 /* AFE Tx Codec DMA Tx port 1 */
330 /* AFE Rx Codec DMA Rx port 2 */
332 /* AFE Tx Codec DMA Tx port 2 */
334 /* AFE Rx Codec DMA Rx port 3 */
336 /* AFE Tx Codec DMA Tx port 3 */
338 /* AFE Rx Codec DMA Rx port 4 */
340 /* AFE Tx Codec DMA Tx port 4 */
342 /* AFE Rx Codec DMA Rx port 5 */
344 /* AFE Tx Codec DMA Tx port 5 */
346 /* AFE Rx Codec DMA Rx port 6 */
348 /* AFE Rx Codec DMA Rx port 7 */
351 #define Q6AFE_LPASS_MODE_CLK1_VALID 1
353 #define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
355 #define AFE_API_VERSION_TDM_CONFIG 1
356 #define AFE_API_VERSION_SLOT_MAPPING_CONFIG 1
357 #define AFE_API_VERSION_CODEC_DMA_CONFIG 1
361 #define AFE_CMD_RESP_NONE 1
383 /* Reserved for 32-bit alignment. This field must be set to 0.*/
427 * Supported values: - #AFE_SLIMBUS_DEVICE_1 - #AFE_SLIMBUS_DEVICE_2
441 * Supported values: 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT
445 * master port is to be connected.
450 /* Sampling rate of the port.
452 * - #AFE_PORT_SAMPLE_RATE_8K
453 * - #AFE_PORT_SAMPLE_RATE_16K
454 * - #AFE_PORT_SAMPLE_RATE_48K
455 * - #AFE_PORT_SAMPLE_RATE_96K
456 * - #AFE_PORT_SAMPLE_RATE_192K
572 * Mapping between Virtual Port IDs to DSP AFE Port ID
573 * On B Family SoCs DSP Port IDs are consistent across multiple SoCs
574 * on A Family SoCs DSP port IDs are same as virtual Port IDs.
578 [HDMI_RX] = { AFE_PORT_ID_MULTICHAN_HDMI_RX, HDMI_RX, 1, 1},
580 SLIMBUS_0_RX, 1, 1},
582 SLIMBUS_1_RX, 1, 1},
584 SLIMBUS_2_RX, 1, 1},
586 SLIMBUS_3_RX, 1, 1},
588 SLIMBUS_4_RX, 1, 1},
590 SLIMBUS_5_RX, 1, 1},
592 SLIMBUS_6_RX, 1, 1},
594 SLIMBUS_0_TX, 0, 1},
596 SLIMBUS_1_TX, 0, 1},
598 SLIMBUS_2_TX, 0, 1},
600 SLIMBUS_3_TX, 0, 1},
602 SLIMBUS_4_TX, 0, 1},
604 SLIMBUS_5_TX, 0, 1},
606 SLIMBUS_6_TX, 0, 1},
608 PRIMARY_MI2S_RX, 1, 1},
610 PRIMARY_MI2S_RX, 0, 1},
612 SECONDARY_MI2S_RX, 1, 1},
614 SECONDARY_MI2S_TX, 0, 1},
616 TERTIARY_MI2S_RX, 1, 1},
618 TERTIARY_MI2S_TX, 0, 1},
620 QUATERNARY_MI2S_RX, 1, 1},
622 QUATERNARY_MI2S_TX, 0, 1},
624 PRIMARY_TDM_RX_0, 1, 1},
626 PRIMARY_TDM_TX_0, 0, 1},
628 PRIMARY_TDM_RX_1, 1, 1},
630 PRIMARY_TDM_TX_1, 0, 1},
632 PRIMARY_TDM_RX_2, 1, 1},
634 PRIMARY_TDM_TX_2, 0, 1},
636 PRIMARY_TDM_RX_3, 1, 1},
638 PRIMARY_TDM_TX_3, 0, 1},
640 PRIMARY_TDM_RX_4, 1, 1},
642 PRIMARY_TDM_TX_4, 0, 1},
644 PRIMARY_TDM_RX_5, 1, 1},
646 PRIMARY_TDM_TX_5, 0, 1},
648 PRIMARY_TDM_RX_6, 1, 1},
650 PRIMARY_TDM_TX_6, 0, 1},
652 PRIMARY_TDM_RX_7, 1, 1},
654 PRIMARY_TDM_TX_7, 0, 1},
656 SECONDARY_TDM_RX_0, 1, 1},
658 SECONDARY_TDM_TX_0, 0, 1},
660 SECONDARY_TDM_RX_1, 1, 1},
662 SECONDARY_TDM_TX_1, 0, 1},
664 SECONDARY_TDM_RX_2, 1, 1},
666 SECONDARY_TDM_TX_2, 0, 1},
668 SECONDARY_TDM_RX_3, 1, 1},
670 SECONDARY_TDM_TX_3, 0, 1},
672 SECONDARY_TDM_RX_4, 1, 1},
674 SECONDARY_TDM_TX_4, 0, 1},
676 SECONDARY_TDM_RX_5, 1, 1},
678 SECONDARY_TDM_TX_5, 0, 1},
680 SECONDARY_TDM_RX_6, 1, 1},
682 SECONDARY_TDM_TX_6, 0, 1},
684 SECONDARY_TDM_RX_7, 1, 1},
686 SECONDARY_TDM_TX_7, 0, 1},
688 TERTIARY_TDM_RX_0, 1, 1},
690 TERTIARY_TDM_TX_0, 0, 1},
692 TERTIARY_TDM_RX_1, 1, 1},
694 TERTIARY_TDM_TX_1, 0, 1},
696 TERTIARY_TDM_RX_2, 1, 1},
698 TERTIARY_TDM_TX_2, 0, 1},
700 TERTIARY_TDM_RX_3, 1, 1},
702 TERTIARY_TDM_TX_3, 0, 1},
704 TERTIARY_TDM_RX_4, 1, 1},
706 TERTIARY_TDM_TX_4, 0, 1},
708 TERTIARY_TDM_RX_5, 1, 1},
710 TERTIARY_TDM_TX_5, 0, 1},
712 TERTIARY_TDM_RX_6, 1, 1},
714 TERTIARY_TDM_TX_6, 0, 1},
716 TERTIARY_TDM_RX_7, 1, 1},
718 TERTIARY_TDM_TX_7, 0, 1},
720 QUATERNARY_TDM_RX_0, 1, 1},
722 QUATERNARY_TDM_TX_0, 0, 1},
724 QUATERNARY_TDM_RX_1, 1, 1},
726 QUATERNARY_TDM_TX_1, 0, 1},
728 QUATERNARY_TDM_RX_2, 1, 1},
730 QUATERNARY_TDM_TX_2, 0, 1},
732 QUATERNARY_TDM_RX_3, 1, 1},
734 QUATERNARY_TDM_TX_3, 0, 1},
736 QUATERNARY_TDM_RX_4, 1, 1},
738 QUATERNARY_TDM_TX_4, 0, 1},
740 QUATERNARY_TDM_RX_5, 1, 1},
742 QUATERNARY_TDM_TX_5, 0, 1},
744 QUATERNARY_TDM_RX_6, 1, 1},
746 QUATERNARY_TDM_TX_6, 0, 1},
748 QUATERNARY_TDM_RX_7, 1, 1},
750 QUATERNARY_TDM_TX_7, 0, 1},
752 QUINARY_TDM_RX_0, 1, 1},
754 QUINARY_TDM_TX_0, 0, 1},
756 QUINARY_TDM_RX_1, 1, 1},
758 QUINARY_TDM_TX_1, 0, 1},
760 QUINARY_TDM_RX_2, 1, 1},
762 QUINARY_TDM_TX_2, 0, 1},
764 QUINARY_TDM_RX_3, 1, 1},
766 QUINARY_TDM_TX_3, 0, 1},
768 QUINARY_TDM_RX_4, 1, 1},
770 QUINARY_TDM_TX_4, 0, 1},
772 QUINARY_TDM_RX_5, 1, 1},
774 QUINARY_TDM_TX_5, 0, 1},
776 QUINARY_TDM_RX_6, 1, 1},
778 QUINARY_TDM_TX_6, 0, 1},
780 QUINARY_TDM_RX_7, 1, 1},
782 QUINARY_TDM_TX_7, 0, 1},
784 DISPLAY_PORT_RX, 1, 1},
786 WSA_CODEC_DMA_RX_0, 1, 1},
788 WSA_CODEC_DMA_TX_0, 0, 1},
790 WSA_CODEC_DMA_RX_1, 1, 1},
792 WSA_CODEC_DMA_TX_1, 0, 1},
794 WSA_CODEC_DMA_TX_2, 0, 1},
796 VA_CODEC_DMA_TX_0, 0, 1},
798 VA_CODEC_DMA_TX_1, 0, 1},
800 VA_CODEC_DMA_TX_2, 0, 1},
802 RX_CODEC_DMA_RX_0, 1, 1},
804 TX_CODEC_DMA_TX_0, 0, 1},
806 RX_CODEC_DMA_RX_1, 1, 1},
808 TX_CODEC_DMA_TX_1, 0, 1},
810 RX_CODEC_DMA_RX_2, 1, 1},
812 TX_CODEC_DMA_TX_2, 0, 1},
814 RX_CODEC_DMA_RX_3, 1, 1},
816 TX_CODEC_DMA_TX_3, 0, 1},
818 RX_CODEC_DMA_RX_4, 1, 1},
820 TX_CODEC_DMA_TX_4, 0, 1},
822 RX_CODEC_DMA_RX_5, 1, 1},
824 TX_CODEC_DMA_TX_5, 0, 1},
826 RX_CODEC_DMA_RX_6, 1, 1},
828 RX_CODEC_DMA_RX_7, 1, 1},
833 struct q6afe_port *port; in q6afe_port_free() local
837 port = container_of(ref, struct q6afe_port, refcount); in q6afe_port_free()
838 afe = port->afe; in q6afe_port_free()
839 spin_lock_irqsave(&afe->port_list_lock, flags); in q6afe_port_free()
840 list_del(&port->node); in q6afe_port_free()
841 spin_unlock_irqrestore(&afe->port_list_lock, flags); in q6afe_port_free()
842 kfree(port->scfg); in q6afe_port_free()
843 kfree(port); in q6afe_port_free()
852 spin_lock_irqsave(&afe->port_list_lock, flags); in q6afe_find_port()
853 list_for_each_entry(p, &afe->port_list, node) in q6afe_find_port()
854 if (p->token == token) { in q6afe_find_port()
856 kref_get(&p->refcount); in q6afe_find_port()
860 spin_unlock_irqrestore(&afe->port_list_lock, flags); in q6afe_find_port()
866 struct q6afe *afe = dev_get_drvdata(&adev->dev); in q6afe_callback()
868 struct apr_hdr *hdr = &data->hdr; in q6afe_callback()
869 struct q6afe_port *port; in q6afe_callback() local
871 if (!data->payload_size) in q6afe_callback()
874 res = data->payload; in q6afe_callback()
875 switch (hdr->opcode) { in q6afe_callback()
877 if (res->status) { in q6afe_callback()
878 dev_err(afe->dev, "cmd = 0x%x returned error = 0x%x\n", in q6afe_callback()
879 res->opcode, res->status); in q6afe_callback()
881 switch (res->opcode) { in q6afe_callback()
886 port = q6afe_find_port(afe, hdr->token); in q6afe_callback()
887 if (port) { in q6afe_callback()
888 port->result = *res; in q6afe_callback()
889 wake_up(&port->wait); in q6afe_callback()
890 kref_put(&port->refcount, q6afe_port_free); in q6afe_callback()
891 } else if (hdr->token == AFE_CLK_TOKEN) { in q6afe_callback()
892 afe->result = *res; in q6afe_callback()
893 wake_up(&afe->wait); in q6afe_callback()
897 dev_err(afe->dev, "Unknown cmd 0x%x\n", res->opcode); in q6afe_callback()
903 afe->result.opcode = hdr->opcode; in q6afe_callback()
904 afe->result.status = res->status; in q6afe_callback()
905 wake_up(&afe->wait); in q6afe_callback()
915 * q6afe_get_port_id() - Get port id from a given port index
917 * @index: port index
924 return -EINVAL; in q6afe_get_port_id()
931 struct q6afe_port *port, uint32_t rsp_opcode) in afe_apr_send_pkt() argument
933 wait_queue_head_t *wait = &port->wait; in afe_apr_send_pkt()
937 mutex_lock(&afe->lock); in afe_apr_send_pkt()
938 if (port) { in afe_apr_send_pkt()
939 wait = &port->wait; in afe_apr_send_pkt()
940 result = &port->result; in afe_apr_send_pkt()
942 result = &afe->result; in afe_apr_send_pkt()
943 wait = &afe->wait; in afe_apr_send_pkt()
946 result->opcode = 0; in afe_apr_send_pkt()
947 result->status = 0; in afe_apr_send_pkt()
949 ret = apr_send_pkt(afe->apr, pkt); in afe_apr_send_pkt()
951 dev_err(afe->dev, "packet not transmitted (%d)\n", ret); in afe_apr_send_pkt()
952 ret = -EINVAL; in afe_apr_send_pkt()
956 ret = wait_event_timeout(*wait, (result->opcode == rsp_opcode), in afe_apr_send_pkt()
959 ret = -ETIMEDOUT; in afe_apr_send_pkt()
960 } else if (result->status > 0) { in afe_apr_send_pkt()
961 dev_err(afe->dev, "DSP returned error[%x]\n", in afe_apr_send_pkt()
962 result->status); in afe_apr_send_pkt()
963 ret = -EINVAL; in afe_apr_send_pkt()
969 mutex_unlock(&afe->lock); in afe_apr_send_pkt()
974 static int q6afe_set_param(struct q6afe *afe, struct q6afe_port *port, in q6afe_set_param() argument
987 return -ENOMEM; in q6afe_set_param()
995 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_set_param()
998 pkt->hdr.pkt_size = pkt_size; in q6afe_set_param()
999 pkt->hdr.src_port = 0; in q6afe_set_param()
1000 pkt->hdr.dest_port = 0; in q6afe_set_param()
1001 pkt->hdr.token = token; in q6afe_set_param()
1002 pkt->hdr.opcode = AFE_SVC_CMD_SET_PARAM; in q6afe_set_param()
1004 param->payload_size = sizeof(*pdata) + psize; in q6afe_set_param()
1005 param->payload_address_lsw = 0x00; in q6afe_set_param()
1006 param->payload_address_msw = 0x00; in q6afe_set_param()
1007 param->mem_map_handle = 0x00; in q6afe_set_param()
1008 pdata->module_id = module_id; in q6afe_set_param()
1009 pdata->param_id = param_id; in q6afe_set_param()
1010 pdata->param_size = psize; in q6afe_set_param()
1012 ret = afe_apr_send_pkt(afe, pkt, port, AFE_SVC_CMD_SET_PARAM); in q6afe_set_param()
1014 dev_err(afe->dev, "AFE set params failed %d\n", ret); in q6afe_set_param()
1020 static int q6afe_port_set_param(struct q6afe_port *port, void *data, in q6afe_port_set_param() argument
1023 return q6afe_set_param(port->afe, port, data, param_id, module_id, in q6afe_port_set_param()
1024 psize, port->token); in q6afe_port_set_param()
1027 static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data, in q6afe_port_set_param_v2() argument
1032 struct q6afe *afe = port->afe; in q6afe_port_set_param_v2()
1034 u16 port_id = port->id; in q6afe_port_set_param_v2()
1041 return -ENOMEM; in q6afe_port_set_param_v2()
1049 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_port_set_param_v2()
1052 pkt->hdr.pkt_size = pkt_size; in q6afe_port_set_param_v2()
1053 pkt->hdr.src_port = 0; in q6afe_port_set_param_v2()
1054 pkt->hdr.dest_port = 0; in q6afe_port_set_param_v2()
1055 pkt->hdr.token = port->token; in q6afe_port_set_param_v2()
1056 pkt->hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; in q6afe_port_set_param_v2()
1058 param->port_id = port_id; in q6afe_port_set_param_v2()
1059 param->payload_size = sizeof(*pdata) + psize; in q6afe_port_set_param_v2()
1060 param->payload_address_lsw = 0x00; in q6afe_port_set_param_v2()
1061 param->payload_address_msw = 0x00; in q6afe_port_set_param_v2()
1062 param->mem_map_handle = 0x00; in q6afe_port_set_param_v2()
1063 pdata->module_id = module_id; in q6afe_port_set_param_v2()
1064 pdata->param_id = param_id; in q6afe_port_set_param_v2()
1065 pdata->param_size = psize; in q6afe_port_set_param_v2()
1067 ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_SET_PARAM_V2); in q6afe_port_set_param_v2()
1069 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_set_param_v2()
1076 static int q6afe_port_set_lpass_clock(struct q6afe_port *port, in q6afe_port_set_lpass_clock() argument
1079 return q6afe_port_set_param_v2(port, cfg, in q6afe_port_set_lpass_clock()
1085 static int q6afe_set_lpass_clock_v2(struct q6afe_port *port, in q6afe_set_lpass_clock_v2() argument
1088 return q6afe_port_set_param(port, cfg, AFE_PARAM_ID_CLOCK_SET, in q6afe_set_lpass_clock_v2()
1092 static int q6afe_set_digital_codec_core_clock(struct q6afe_port *port, in q6afe_set_digital_codec_core_clock() argument
1095 return q6afe_port_set_param_v2(port, cfg, in q6afe_set_digital_codec_core_clock()
1104 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_set_lpass_clock()
1120 int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id, in q6afe_port_set_sysclk() argument
1134 ret = q6afe_set_digital_codec_core_clock(port, &dcfg); in q6afe_port_set_sysclk()
1142 ret = q6afe_port_set_lpass_clock(port, &ccfg); in q6afe_port_set_sysclk()
1151 ret = q6afe_port_set_lpass_clock(port, &ccfg); in q6afe_port_set_sysclk()
1163 ret = q6afe_set_lpass_clock_v2(port, &cset); in q6afe_port_set_sysclk()
1166 ret = -EINVAL; in q6afe_port_set_sysclk()
1175 * q6afe_port_stop() - Stop a afe port
1177 * @port: Instance of port to stop
1181 int q6afe_port_stop(struct q6afe_port *port) in q6afe_port_stop() argument
1184 struct q6afe *afe = port->afe; in q6afe_port_stop()
1186 int port_id = port->id; in q6afe_port_stop()
1191 port_id = port->id; in q6afe_port_stop()
1192 index = port->token; in q6afe_port_stop()
1194 dev_err(afe->dev, "AFE port index[%d] invalid!\n", index); in q6afe_port_stop()
1195 return -EINVAL; in q6afe_port_stop()
1201 return -ENOMEM; in q6afe_port_stop()
1206 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_port_stop()
1209 pkt->hdr.pkt_size = pkt_size; in q6afe_port_stop()
1210 pkt->hdr.src_port = 0; in q6afe_port_stop()
1211 pkt->hdr.dest_port = 0; in q6afe_port_stop()
1212 pkt->hdr.token = index; in q6afe_port_stop()
1213 pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_STOP; in q6afe_port_stop()
1214 stop->port_id = port_id; in q6afe_port_stop()
1215 stop->reserved = 0; in q6afe_port_stop()
1217 ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_DEVICE_STOP); in q6afe_port_stop()
1219 dev_err(afe->dev, "AFE close failed %d\n", ret); in q6afe_port_stop()
1227 * q6afe_slim_port_prepare() - Prepare slim afe port.
1229 * @port: Instance of afe port
1230 * @cfg: SLIM configuration for the afe port
1233 void q6afe_slim_port_prepare(struct q6afe_port *port, in q6afe_slim_port_prepare() argument
1236 union afe_port_config *pcfg = &port->port_cfg; in q6afe_slim_port_prepare()
1238 pcfg->slim_cfg.sb_cfg_minor_version = AFE_API_VERSION_SLIMBUS_CONFIG; in q6afe_slim_port_prepare()
1239 pcfg->slim_cfg.sample_rate = cfg->sample_rate; in q6afe_slim_port_prepare()
1240 pcfg->slim_cfg.bit_width = cfg->bit_width; in q6afe_slim_port_prepare()
1241 pcfg->slim_cfg.num_channels = cfg->num_channels; in q6afe_slim_port_prepare()
1242 pcfg->slim_cfg.data_format = cfg->data_format; in q6afe_slim_port_prepare()
1243 pcfg->slim_cfg.shared_ch_mapping[0] = cfg->ch_mapping[0]; in q6afe_slim_port_prepare()
1244 pcfg->slim_cfg.shared_ch_mapping[1] = cfg->ch_mapping[1]; in q6afe_slim_port_prepare()
1245 pcfg->slim_cfg.shared_ch_mapping[2] = cfg->ch_mapping[2]; in q6afe_slim_port_prepare()
1246 pcfg->slim_cfg.shared_ch_mapping[3] = cfg->ch_mapping[3]; in q6afe_slim_port_prepare()
1252 * q6afe_tdm_port_prepare() - Prepare tdm afe port.
1254 * @port: Instance of afe port
1255 * @cfg: TDM configuration for the afe port
1258 void q6afe_tdm_port_prepare(struct q6afe_port *port, in q6afe_tdm_port_prepare() argument
1261 union afe_port_config *pcfg = &port->port_cfg; in q6afe_tdm_port_prepare()
1263 pcfg->tdm_cfg.tdm_cfg_minor_version = AFE_API_VERSION_TDM_CONFIG; in q6afe_tdm_port_prepare()
1264 pcfg->tdm_cfg.num_channels = cfg->num_channels; in q6afe_tdm_port_prepare()
1265 pcfg->tdm_cfg.sample_rate = cfg->sample_rate; in q6afe_tdm_port_prepare()
1266 pcfg->tdm_cfg.bit_width = cfg->bit_width; in q6afe_tdm_port_prepare()
1267 pcfg->tdm_cfg.data_format = cfg->data_format; in q6afe_tdm_port_prepare()
1268 pcfg->tdm_cfg.sync_mode = cfg->sync_mode; in q6afe_tdm_port_prepare()
1269 pcfg->tdm_cfg.sync_src = cfg->sync_src; in q6afe_tdm_port_prepare()
1270 pcfg->tdm_cfg.nslots_per_frame = cfg->nslots_per_frame; in q6afe_tdm_port_prepare()
1272 pcfg->tdm_cfg.slot_width = cfg->slot_width; in q6afe_tdm_port_prepare()
1273 pcfg->tdm_cfg.slot_mask = cfg->slot_mask; in q6afe_tdm_port_prepare()
1274 port->scfg = kzalloc(sizeof(*port->scfg), GFP_KERNEL); in q6afe_tdm_port_prepare()
1275 if (!port->scfg) in q6afe_tdm_port_prepare()
1278 port->scfg->minor_version = AFE_API_VERSION_SLOT_MAPPING_CONFIG; in q6afe_tdm_port_prepare()
1279 port->scfg->num_channels = cfg->num_channels; in q6afe_tdm_port_prepare()
1280 port->scfg->bitwidth = cfg->bit_width; in q6afe_tdm_port_prepare()
1281 port->scfg->data_align_type = cfg->data_align_type; in q6afe_tdm_port_prepare()
1282 memcpy(port->scfg->ch_mapping, cfg->ch_mapping, in q6afe_tdm_port_prepare()
1288 * q6afe_hdmi_port_prepare() - Prepare hdmi afe port.
1290 * @port: Instance of afe port
1291 * @cfg: HDMI configuration for the afe port
1294 void q6afe_hdmi_port_prepare(struct q6afe_port *port, in q6afe_hdmi_port_prepare() argument
1297 union afe_port_config *pcfg = &port->port_cfg; in q6afe_hdmi_port_prepare()
1299 pcfg->hdmi_multi_ch.hdmi_cfg_minor_version = in q6afe_hdmi_port_prepare()
1301 pcfg->hdmi_multi_ch.datatype = cfg->datatype; in q6afe_hdmi_port_prepare()
1302 pcfg->hdmi_multi_ch.channel_allocation = cfg->channel_allocation; in q6afe_hdmi_port_prepare()
1303 pcfg->hdmi_multi_ch.sample_rate = cfg->sample_rate; in q6afe_hdmi_port_prepare()
1304 pcfg->hdmi_multi_ch.bit_width = cfg->bit_width; in q6afe_hdmi_port_prepare()
1309 * q6afe_i2s_port_prepare() - Prepare i2s afe port.
1311 * @port: Instance of afe port
1312 * @cfg: I2S configuration for the afe port
1315 int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg) in q6afe_i2s_port_prepare() argument
1317 union afe_port_config *pcfg = &port->port_cfg; in q6afe_i2s_port_prepare()
1318 struct device *dev = port->afe->dev; in q6afe_i2s_port_prepare()
1321 pcfg->i2s_cfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG; in q6afe_i2s_port_prepare()
1322 pcfg->i2s_cfg.sample_rate = cfg->sample_rate; in q6afe_i2s_port_prepare()
1323 pcfg->i2s_cfg.bit_width = cfg->bit_width; in q6afe_i2s_port_prepare()
1324 pcfg->i2s_cfg.data_format = AFE_LINEAR_PCM_DATA; in q6afe_i2s_port_prepare()
1326 switch (cfg->fmt & SND_SOC_DAIFMT_MASTER_MASK) { in q6afe_i2s_port_prepare()
1328 pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL; in q6afe_i2s_port_prepare()
1332 pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL; in q6afe_i2s_port_prepare()
1338 num_sd_lines = hweight_long(cfg->sd_line_mask); in q6afe_i2s_port_prepare()
1343 return -EINVAL; in q6afe_i2s_port_prepare()
1344 case 1: in q6afe_i2s_port_prepare()
1345 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1347 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0; in q6afe_i2s_port_prepare()
1350 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD1; in q6afe_i2s_port_prepare()
1353 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2; in q6afe_i2s_port_prepare()
1356 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD3; in q6afe_i2s_port_prepare()
1360 return -EINVAL; in q6afe_i2s_port_prepare()
1364 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1366 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD01; in q6afe_i2s_port_prepare()
1369 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD23; in q6afe_i2s_port_prepare()
1373 return -EINVAL; in q6afe_i2s_port_prepare()
1377 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1379 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_6CHS; in q6afe_i2s_port_prepare()
1383 return -EINVAL; in q6afe_i2s_port_prepare()
1387 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1389 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_8CHS; in q6afe_i2s_port_prepare()
1394 return -EINVAL; in q6afe_i2s_port_prepare()
1399 return -EINVAL; in q6afe_i2s_port_prepare()
1402 switch (cfg->num_channels) { in q6afe_i2s_port_prepare()
1403 case 1: in q6afe_i2s_port_prepare()
1405 switch (pcfg->i2s_cfg.channel_mode) { in q6afe_i2s_port_prepare()
1409 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0; in q6afe_i2s_port_prepare()
1412 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2; in q6afe_i2s_port_prepare()
1416 if (cfg->num_channels == 2) in q6afe_i2s_port_prepare()
1417 pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_STEREO; in q6afe_i2s_port_prepare()
1419 pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_MONO; in q6afe_i2s_port_prepare()
1424 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_QUAD01) { in q6afe_i2s_port_prepare()
1426 return -EINVAL; in q6afe_i2s_port_prepare()
1431 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_6CHS) { in q6afe_i2s_port_prepare()
1433 return -EINVAL; in q6afe_i2s_port_prepare()
1438 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_8CHS) { in q6afe_i2s_port_prepare()
1440 return -EINVAL; in q6afe_i2s_port_prepare()
1452 * q6afe_dam_port_prepare() - Prepare dma afe port.
1454 * @port: Instance of afe port
1455 * @cfg: DMA configuration for the afe port
1458 void q6afe_cdc_dma_port_prepare(struct q6afe_port *port, in q6afe_cdc_dma_port_prepare() argument
1461 union afe_port_config *pcfg = &port->port_cfg; in q6afe_cdc_dma_port_prepare()
1462 struct afe_param_id_cdc_dma_cfg *dma_cfg = &pcfg->dma_cfg; in q6afe_cdc_dma_port_prepare()
1464 dma_cfg->cdc_dma_cfg_minor_version = AFE_API_VERSION_CODEC_DMA_CONFIG; in q6afe_cdc_dma_port_prepare()
1465 dma_cfg->sample_rate = cfg->sample_rate; in q6afe_cdc_dma_port_prepare()
1466 dma_cfg->bit_width = cfg->bit_width; in q6afe_cdc_dma_port_prepare()
1467 dma_cfg->data_format = cfg->data_format; in q6afe_cdc_dma_port_prepare()
1468 dma_cfg->num_channels = cfg->num_channels; in q6afe_cdc_dma_port_prepare()
1469 if (!cfg->active_channels_mask) in q6afe_cdc_dma_port_prepare()
1470 dma_cfg->active_channels_mask = (1 << cfg->num_channels) - 1; in q6afe_cdc_dma_port_prepare()
1474 * q6afe_port_start() - Start a afe port
1476 * @port: Instance of port to start
1480 int q6afe_port_start(struct q6afe_port *port) in q6afe_port_start() argument
1483 struct q6afe *afe = port->afe; in q6afe_port_start()
1484 int port_id = port->id; in q6afe_port_start()
1485 int ret, param_id = port->cfg_type; in q6afe_port_start()
1490 ret = q6afe_port_set_param_v2(port, &port->port_cfg, param_id, in q6afe_port_start()
1492 sizeof(port->port_cfg)); in q6afe_port_start()
1494 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_start()
1499 if (port->scfg) { in q6afe_port_start()
1500 ret = q6afe_port_set_param_v2(port, port->scfg, in q6afe_port_start()
1502 AFE_MODULE_TDM, sizeof(*port->scfg)); in q6afe_port_start()
1504 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_start()
1513 return -ENOMEM; in q6afe_port_start()
1518 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_port_start()
1521 pkt->hdr.pkt_size = pkt_size; in q6afe_port_start()
1522 pkt->hdr.src_port = 0; in q6afe_port_start()
1523 pkt->hdr.dest_port = 0; in q6afe_port_start()
1524 pkt->hdr.token = port->token; in q6afe_port_start()
1525 pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_START; in q6afe_port_start()
1527 start->port_id = port_id; in q6afe_port_start()
1529 ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_DEVICE_START); in q6afe_port_start()
1531 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_start()
1540 * q6afe_port_get_from_id() - Get port instance from a port id
1543 * @id: port id
1545 * Return: Will be an error pointer on error or a valid afe port
1551 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_port_get_from_id()
1552 struct q6afe_port *port; in q6afe_port_get_from_id() local
1557 dev_err(dev, "AFE port token[%d] invalid!\n", id); in q6afe_port_get_from_id()
1558 return ERR_PTR(-EINVAL); in q6afe_port_get_from_id()
1561 /* if port is multiple times bind/unbind before callback finishes */ in q6afe_port_get_from_id()
1562 port = q6afe_find_port(afe, id); in q6afe_port_get_from_id()
1563 if (port) { in q6afe_port_get_from_id()
1564 dev_err(dev, "AFE Port already open\n"); in q6afe_port_get_from_id()
1565 return port; in q6afe_port_get_from_id()
1609 dev_err(dev, "Invalid port id 0x%x\n", port_id); in q6afe_port_get_from_id()
1610 return ERR_PTR(-EINVAL); in q6afe_port_get_from_id()
1613 port = kzalloc(sizeof(*port), GFP_KERNEL); in q6afe_port_get_from_id()
1614 if (!port) in q6afe_port_get_from_id()
1615 return ERR_PTR(-ENOMEM); in q6afe_port_get_from_id()
1617 init_waitqueue_head(&port->wait); in q6afe_port_get_from_id()
1619 port->token = id; in q6afe_port_get_from_id()
1620 port->id = port_id; in q6afe_port_get_from_id()
1621 port->afe = afe; in q6afe_port_get_from_id()
1622 port->cfg_type = cfg_type; in q6afe_port_get_from_id()
1623 kref_init(&port->refcount); in q6afe_port_get_from_id()
1625 spin_lock_irqsave(&afe->port_list_lock, flags); in q6afe_port_get_from_id()
1626 list_add_tail(&port->node, &afe->port_list); in q6afe_port_get_from_id()
1627 spin_unlock_irqrestore(&afe->port_list_lock, flags); in q6afe_port_get_from_id()
1629 return port; in q6afe_port_get_from_id()
1635 * q6afe_port_put() - Release port reference
1637 * @port: Instance of port to put
1639 void q6afe_port_put(struct q6afe_port *port) in q6afe_port_put() argument
1641 kref_put(&port->refcount, q6afe_port_free); in q6afe_port_put()
1648 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_unvote_lpass_core_hw()
1658 return -ENOMEM; in q6afe_unvote_lpass_core_hw()
1663 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_unvote_lpass_core_hw()
1666 pkt->hdr.pkt_size = pkt_size; in q6afe_unvote_lpass_core_hw()
1667 pkt->hdr.src_port = 0; in q6afe_unvote_lpass_core_hw()
1668 pkt->hdr.dest_port = 0; in q6afe_unvote_lpass_core_hw()
1669 pkt->hdr.token = hw_block_id; in q6afe_unvote_lpass_core_hw()
1670 pkt->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST; in q6afe_unvote_lpass_core_hw()
1671 vote_cfg->hw_block_id = hw_block_id; in q6afe_unvote_lpass_core_hw()
1672 vote_cfg->client_handle = client_handle; in q6afe_unvote_lpass_core_hw()
1674 ret = apr_send_pkt(afe->apr, pkt); in q6afe_unvote_lpass_core_hw()
1676 dev_err(afe->dev, "AFE failed to unvote (%d)\n", hw_block_id); in q6afe_unvote_lpass_core_hw()
1686 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_vote_lpass_core_hw()
1696 return -ENOMEM; in q6afe_vote_lpass_core_hw()
1701 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_vote_lpass_core_hw()
1704 pkt->hdr.pkt_size = pkt_size; in q6afe_vote_lpass_core_hw()
1705 pkt->hdr.src_port = 0; in q6afe_vote_lpass_core_hw()
1706 pkt->hdr.dest_port = 0; in q6afe_vote_lpass_core_hw()
1707 pkt->hdr.token = hw_block_id; in q6afe_vote_lpass_core_hw()
1708 pkt->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST; in q6afe_vote_lpass_core_hw()
1709 vote_cfg->hw_block_id = hw_block_id; in q6afe_vote_lpass_core_hw()
1710 strlcpy(vote_cfg->client_name, client_name, in q6afe_vote_lpass_core_hw()
1711 sizeof(vote_cfg->client_name)); in q6afe_vote_lpass_core_hw()
1716 dev_err(afe->dev, "AFE failed to vote (%d)\n", hw_block_id); in q6afe_vote_lpass_core_hw()
1727 struct device *dev = &adev->dev; in q6afe_probe()
1731 return -ENOMEM; in q6afe_probe()
1733 q6core_get_svc_api_info(adev->svc_id, &afe->ainfo); in q6afe_probe()
1734 afe->apr = adev; in q6afe_probe()
1735 mutex_init(&afe->lock); in q6afe_probe()
1736 init_waitqueue_head(&afe->wait); in q6afe_probe()
1737 afe->dev = dev; in q6afe_probe()
1738 INIT_LIST_HEAD(&afe->port_list); in q6afe_probe()
1739 spin_lock_init(&afe->port_list_lock); in q6afe_probe()
1743 return of_platform_populate(dev->of_node, NULL, NULL, dev); in q6afe_probe()
1748 of_platform_depopulate(&adev->dev); in q6afe_remove()
1766 .name = "qcom-q6afe",