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.
5 #include <dt-bindings/sound/qcom,q6afe.h>
20 #include <sound/soc-dai.h>
23 #include "q6dsp-errno.h"
61 #define AFE_PORT_I2S_SD0_1_MASK GENMASK(1, 0)
76 /* Port IDs */
83 #define AFE_API_VERSION_CLOCK_SET 1
88 /* SLIMbus Rx port on channel 0. */
90 /* SLIMbus Tx port on channel 0. */
92 /* SLIMbus Rx port on channel 1. */
94 /* SLIMbus Tx port on channel 1. */
96 /* SLIMbus Rx port on channel 2. */
98 /* SLIMbus Tx port on channel 2. */
100 /* SLIMbus Rx port on channel 3. */
102 /* SLIMbus Tx port on channel 3. */
104 /* SLIMbus Rx port on channel 4. */
106 /* SLIMbus Tx port on channel 4. */
108 /* SLIMbus Rx port on channel 5. */
110 /* SLIMbus Tx port on channel 5. */
112 /* SLIMbus Rx port on channel 6. */
114 /* SLIMbus Tx port on channel 6. */
127 /* Start of the range of port IDs for TDM devices. */
130 /* End of the range of port IDs for TDM devices. */
132 (AFE_PORT_ID_TDM_PORT_RANGE_START+0x50-1)
134 /* Size of the range of port IDs for TDM ports. */
136 (AFE_PORT_ID_TDM_PORT_RANGE_END - \
137 AFE_PORT_ID_TDM_PORT_RANGE_START+1)
309 /* AFE WSA Codec DMA Rx port 0 */
311 /* AFE WSA Codec DMA Tx port 0 */
313 /* AFE WSA Codec DMA Rx port 1 */
315 /* AFE WSA Codec DMA Tx port 1 */
317 /* AFE WSA Codec DMA Tx port 2 */
319 /* AFE VA Codec DMA Tx port 0 */
321 /* AFE VA Codec DMA Tx port 1 */
323 /* AFE VA Codec DMA Tx port 2 */
325 /* AFE Rx Codec DMA Rx port 0 */
327 /* AFE Tx Codec DMA Tx port 0 */
329 /* AFE Rx Codec DMA Rx port 1 */
331 /* AFE Tx Codec DMA Tx port 1 */
333 /* AFE Rx Codec DMA Rx port 2 */
335 /* AFE Tx Codec DMA Tx port 2 */
337 /* AFE Rx Codec DMA Rx port 3 */
339 /* AFE Tx Codec DMA Tx port 3 */
341 /* AFE Rx Codec DMA Rx port 4 */
343 /* AFE Tx Codec DMA Tx port 4 */
345 /* AFE Rx Codec DMA Rx port 5 */
347 /* AFE Tx Codec DMA Tx port 5 */
349 /* AFE Rx Codec DMA Rx port 6 */
351 /* AFE Rx Codec DMA Rx port 7 */
354 #define Q6AFE_LPASS_MODE_CLK1_VALID 1
356 #define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
358 #define AFE_API_VERSION_TDM_CONFIG 1
359 #define AFE_API_VERSION_SLOT_MAPPING_CONFIG 1
360 #define AFE_API_VERSION_CODEC_DMA_CONFIG 1
364 #define AFE_CMD_RESP_NONE 1
386 /* Reserved for 32-bit alignment. This field must be set to 0.*/
430 * Supported values: - #AFE_SLIMBUS_DEVICE_1 - #AFE_SLIMBUS_DEVICE_2
444 * Supported values: 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT
448 * master port is to be connected.
453 /* Sampling rate of the port.
455 * - #AFE_PORT_SAMPLE_RATE_8K
456 * - #AFE_PORT_SAMPLE_RATE_16K
457 * - #AFE_PORT_SAMPLE_RATE_48K
458 * - #AFE_PORT_SAMPLE_RATE_96K
459 * - #AFE_PORT_SAMPLE_RATE_192K
575 * Mapping between Virtual Port IDs to DSP AFE Port ID
576 * On B Family SoCs DSP Port IDs are consistent across multiple SoCs
577 * on A Family SoCs DSP port IDs are same as virtual Port IDs.
581 [HDMI_RX] = { AFE_PORT_ID_MULTICHAN_HDMI_RX, HDMI_RX, 1, 1},
583 SLIMBUS_0_RX, 1, 1},
585 SLIMBUS_1_RX, 1, 1},
587 SLIMBUS_2_RX, 1, 1},
589 SLIMBUS_3_RX, 1, 1},
591 SLIMBUS_4_RX, 1, 1},
593 SLIMBUS_5_RX, 1, 1},
595 SLIMBUS_6_RX, 1, 1},
597 SLIMBUS_0_TX, 0, 1},
599 SLIMBUS_1_TX, 0, 1},
601 SLIMBUS_2_TX, 0, 1},
603 SLIMBUS_3_TX, 0, 1},
605 SLIMBUS_4_TX, 0, 1},
607 SLIMBUS_5_TX, 0, 1},
609 SLIMBUS_6_TX, 0, 1},
611 PRIMARY_MI2S_RX, 1, 1},
613 PRIMARY_MI2S_RX, 0, 1},
615 SECONDARY_MI2S_RX, 1, 1},
617 SECONDARY_MI2S_TX, 0, 1},
619 TERTIARY_MI2S_RX, 1, 1},
621 TERTIARY_MI2S_TX, 0, 1},
623 QUATERNARY_MI2S_RX, 1, 1},
625 QUATERNARY_MI2S_TX, 0, 1},
627 QUINARY_MI2S_RX, 1, 1},
629 QUINARY_MI2S_TX, 0, 1},
631 PRIMARY_TDM_RX_0, 1, 1},
633 PRIMARY_TDM_TX_0, 0, 1},
635 PRIMARY_TDM_RX_1, 1, 1},
637 PRIMARY_TDM_TX_1, 0, 1},
639 PRIMARY_TDM_RX_2, 1, 1},
641 PRIMARY_TDM_TX_2, 0, 1},
643 PRIMARY_TDM_RX_3, 1, 1},
645 PRIMARY_TDM_TX_3, 0, 1},
647 PRIMARY_TDM_RX_4, 1, 1},
649 PRIMARY_TDM_TX_4, 0, 1},
651 PRIMARY_TDM_RX_5, 1, 1},
653 PRIMARY_TDM_TX_5, 0, 1},
655 PRIMARY_TDM_RX_6, 1, 1},
657 PRIMARY_TDM_TX_6, 0, 1},
659 PRIMARY_TDM_RX_7, 1, 1},
661 PRIMARY_TDM_TX_7, 0, 1},
663 SECONDARY_TDM_RX_0, 1, 1},
665 SECONDARY_TDM_TX_0, 0, 1},
667 SECONDARY_TDM_RX_1, 1, 1},
669 SECONDARY_TDM_TX_1, 0, 1},
671 SECONDARY_TDM_RX_2, 1, 1},
673 SECONDARY_TDM_TX_2, 0, 1},
675 SECONDARY_TDM_RX_3, 1, 1},
677 SECONDARY_TDM_TX_3, 0, 1},
679 SECONDARY_TDM_RX_4, 1, 1},
681 SECONDARY_TDM_TX_4, 0, 1},
683 SECONDARY_TDM_RX_5, 1, 1},
685 SECONDARY_TDM_TX_5, 0, 1},
687 SECONDARY_TDM_RX_6, 1, 1},
689 SECONDARY_TDM_TX_6, 0, 1},
691 SECONDARY_TDM_RX_7, 1, 1},
693 SECONDARY_TDM_TX_7, 0, 1},
695 TERTIARY_TDM_RX_0, 1, 1},
697 TERTIARY_TDM_TX_0, 0, 1},
699 TERTIARY_TDM_RX_1, 1, 1},
701 TERTIARY_TDM_TX_1, 0, 1},
703 TERTIARY_TDM_RX_2, 1, 1},
705 TERTIARY_TDM_TX_2, 0, 1},
707 TERTIARY_TDM_RX_3, 1, 1},
709 TERTIARY_TDM_TX_3, 0, 1},
711 TERTIARY_TDM_RX_4, 1, 1},
713 TERTIARY_TDM_TX_4, 0, 1},
715 TERTIARY_TDM_RX_5, 1, 1},
717 TERTIARY_TDM_TX_5, 0, 1},
719 TERTIARY_TDM_RX_6, 1, 1},
721 TERTIARY_TDM_TX_6, 0, 1},
723 TERTIARY_TDM_RX_7, 1, 1},
725 TERTIARY_TDM_TX_7, 0, 1},
727 QUATERNARY_TDM_RX_0, 1, 1},
729 QUATERNARY_TDM_TX_0, 0, 1},
731 QUATERNARY_TDM_RX_1, 1, 1},
733 QUATERNARY_TDM_TX_1, 0, 1},
735 QUATERNARY_TDM_RX_2, 1, 1},
737 QUATERNARY_TDM_TX_2, 0, 1},
739 QUATERNARY_TDM_RX_3, 1, 1},
741 QUATERNARY_TDM_TX_3, 0, 1},
743 QUATERNARY_TDM_RX_4, 1, 1},
745 QUATERNARY_TDM_TX_4, 0, 1},
747 QUATERNARY_TDM_RX_5, 1, 1},
749 QUATERNARY_TDM_TX_5, 0, 1},
751 QUATERNARY_TDM_RX_6, 1, 1},
753 QUATERNARY_TDM_TX_6, 0, 1},
755 QUATERNARY_TDM_RX_7, 1, 1},
757 QUATERNARY_TDM_TX_7, 0, 1},
759 QUINARY_TDM_RX_0, 1, 1},
761 QUINARY_TDM_TX_0, 0, 1},
763 QUINARY_TDM_RX_1, 1, 1},
765 QUINARY_TDM_TX_1, 0, 1},
767 QUINARY_TDM_RX_2, 1, 1},
769 QUINARY_TDM_TX_2, 0, 1},
771 QUINARY_TDM_RX_3, 1, 1},
773 QUINARY_TDM_TX_3, 0, 1},
775 QUINARY_TDM_RX_4, 1, 1},
777 QUINARY_TDM_TX_4, 0, 1},
779 QUINARY_TDM_RX_5, 1, 1},
781 QUINARY_TDM_TX_5, 0, 1},
783 QUINARY_TDM_RX_6, 1, 1},
785 QUINARY_TDM_TX_6, 0, 1},
787 QUINARY_TDM_RX_7, 1, 1},
789 QUINARY_TDM_TX_7, 0, 1},
791 DISPLAY_PORT_RX, 1, 1},
793 WSA_CODEC_DMA_RX_0, 1, 1},
795 WSA_CODEC_DMA_TX_0, 0, 1},
797 WSA_CODEC_DMA_RX_1, 1, 1},
799 WSA_CODEC_DMA_TX_1, 0, 1},
801 WSA_CODEC_DMA_TX_2, 0, 1},
803 VA_CODEC_DMA_TX_0, 0, 1},
805 VA_CODEC_DMA_TX_1, 0, 1},
807 VA_CODEC_DMA_TX_2, 0, 1},
809 RX_CODEC_DMA_RX_0, 1, 1},
811 TX_CODEC_DMA_TX_0, 0, 1},
813 RX_CODEC_DMA_RX_1, 1, 1},
815 TX_CODEC_DMA_TX_1, 0, 1},
817 RX_CODEC_DMA_RX_2, 1, 1},
819 TX_CODEC_DMA_TX_2, 0, 1},
821 RX_CODEC_DMA_RX_3, 1, 1},
823 TX_CODEC_DMA_TX_3, 0, 1},
825 RX_CODEC_DMA_RX_4, 1, 1},
827 TX_CODEC_DMA_TX_4, 0, 1},
829 RX_CODEC_DMA_RX_5, 1, 1},
831 TX_CODEC_DMA_TX_5, 0, 1},
833 RX_CODEC_DMA_RX_6, 1, 1},
835 RX_CODEC_DMA_RX_7, 1, 1},
840 struct q6afe_port *port; in q6afe_port_free() local
844 port = container_of(ref, struct q6afe_port, refcount); in q6afe_port_free()
845 afe = port->afe; in q6afe_port_free()
846 spin_lock_irqsave(&afe->port_list_lock, flags); in q6afe_port_free()
847 list_del(&port->node); in q6afe_port_free()
848 spin_unlock_irqrestore(&afe->port_list_lock, flags); in q6afe_port_free()
849 kfree(port->scfg); in q6afe_port_free()
850 kfree(port); in q6afe_port_free()
859 spin_lock_irqsave(&afe->port_list_lock, flags); in q6afe_find_port()
860 list_for_each_entry(p, &afe->port_list, node) in q6afe_find_port()
861 if (p->token == token) { in q6afe_find_port()
863 kref_get(&p->refcount); in q6afe_find_port()
867 spin_unlock_irqrestore(&afe->port_list_lock, flags); in q6afe_find_port()
873 struct q6afe *afe = dev_get_drvdata(&adev->dev); in q6afe_callback()
875 struct apr_hdr *hdr = &data->hdr; in q6afe_callback()
876 struct q6afe_port *port; in q6afe_callback() local
878 if (!data->payload_size) in q6afe_callback()
881 res = data->payload; in q6afe_callback()
882 switch (hdr->opcode) { in q6afe_callback()
884 if (res->status) { in q6afe_callback()
885 dev_err(afe->dev, "cmd = 0x%x returned error = 0x%x\n", in q6afe_callback()
886 res->opcode, res->status); in q6afe_callback()
888 switch (res->opcode) { in q6afe_callback()
893 port = q6afe_find_port(afe, hdr->token); in q6afe_callback()
894 if (port) { in q6afe_callback()
895 port->result = *res; in q6afe_callback()
896 wake_up(&port->wait); in q6afe_callback()
897 kref_put(&port->refcount, q6afe_port_free); in q6afe_callback()
898 } else if (hdr->token == AFE_CLK_TOKEN) { in q6afe_callback()
899 afe->result = *res; in q6afe_callback()
900 wake_up(&afe->wait); in q6afe_callback()
904 dev_err(afe->dev, "Unknown cmd 0x%x\n", res->opcode); in q6afe_callback()
910 afe->result.opcode = hdr->opcode; in q6afe_callback()
911 afe->result.status = res->status; in q6afe_callback()
912 wake_up(&afe->wait); in q6afe_callback()
922 * q6afe_get_port_id() - Get port id from a given port index
924 * @index: port index
931 return -EINVAL; in q6afe_get_port_id()
938 struct q6afe_port *port, uint32_t rsp_opcode) in afe_apr_send_pkt() argument
944 mutex_lock(&afe->lock); in afe_apr_send_pkt()
945 if (port) { in afe_apr_send_pkt()
946 wait = &port->wait; in afe_apr_send_pkt()
947 result = &port->result; in afe_apr_send_pkt()
949 result = &afe->result; in afe_apr_send_pkt()
950 wait = &afe->wait; in afe_apr_send_pkt()
953 result->opcode = 0; in afe_apr_send_pkt()
954 result->status = 0; in afe_apr_send_pkt()
956 ret = apr_send_pkt(afe->apr, pkt); in afe_apr_send_pkt()
958 dev_err(afe->dev, "packet not transmitted (%d)\n", ret); in afe_apr_send_pkt()
959 ret = -EINVAL; in afe_apr_send_pkt()
963 ret = wait_event_timeout(*wait, (result->opcode == rsp_opcode), in afe_apr_send_pkt()
966 ret = -ETIMEDOUT; in afe_apr_send_pkt()
967 } else if (result->status > 0) { in afe_apr_send_pkt()
968 dev_err(afe->dev, "DSP returned error[%x]\n", in afe_apr_send_pkt()
969 result->status); in afe_apr_send_pkt()
970 ret = -EINVAL; in afe_apr_send_pkt()
976 mutex_unlock(&afe->lock); in afe_apr_send_pkt()
981 static int q6afe_set_param(struct q6afe *afe, struct q6afe_port *port, in q6afe_set_param() argument
994 return -ENOMEM; in q6afe_set_param()
1002 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_set_param()
1005 pkt->hdr.pkt_size = pkt_size; in q6afe_set_param()
1006 pkt->hdr.src_port = 0; in q6afe_set_param()
1007 pkt->hdr.dest_port = 0; in q6afe_set_param()
1008 pkt->hdr.token = token; in q6afe_set_param()
1009 pkt->hdr.opcode = AFE_SVC_CMD_SET_PARAM; in q6afe_set_param()
1011 param->payload_size = sizeof(*pdata) + psize; in q6afe_set_param()
1012 param->payload_address_lsw = 0x00; in q6afe_set_param()
1013 param->payload_address_msw = 0x00; in q6afe_set_param()
1014 param->mem_map_handle = 0x00; in q6afe_set_param()
1015 pdata->module_id = module_id; in q6afe_set_param()
1016 pdata->param_id = param_id; in q6afe_set_param()
1017 pdata->param_size = psize; in q6afe_set_param()
1019 ret = afe_apr_send_pkt(afe, pkt, port, AFE_SVC_CMD_SET_PARAM); in q6afe_set_param()
1021 dev_err(afe->dev, "AFE set params failed %d\n", ret); in q6afe_set_param()
1027 static int q6afe_port_set_param(struct q6afe_port *port, void *data, in q6afe_port_set_param() argument
1030 return q6afe_set_param(port->afe, port, data, param_id, module_id, in q6afe_port_set_param()
1031 psize, port->token); in q6afe_port_set_param()
1034 static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data, in q6afe_port_set_param_v2() argument
1039 struct q6afe *afe = port->afe; in q6afe_port_set_param_v2()
1041 u16 port_id = port->id; in q6afe_port_set_param_v2()
1048 return -ENOMEM; in q6afe_port_set_param_v2()
1056 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_port_set_param_v2()
1059 pkt->hdr.pkt_size = pkt_size; in q6afe_port_set_param_v2()
1060 pkt->hdr.src_port = 0; in q6afe_port_set_param_v2()
1061 pkt->hdr.dest_port = 0; in q6afe_port_set_param_v2()
1062 pkt->hdr.token = port->token; in q6afe_port_set_param_v2()
1063 pkt->hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; in q6afe_port_set_param_v2()
1065 param->port_id = port_id; in q6afe_port_set_param_v2()
1066 param->payload_size = sizeof(*pdata) + psize; in q6afe_port_set_param_v2()
1067 param->payload_address_lsw = 0x00; in q6afe_port_set_param_v2()
1068 param->payload_address_msw = 0x00; in q6afe_port_set_param_v2()
1069 param->mem_map_handle = 0x00; in q6afe_port_set_param_v2()
1070 pdata->module_id = module_id; in q6afe_port_set_param_v2()
1071 pdata->param_id = param_id; in q6afe_port_set_param_v2()
1072 pdata->param_size = psize; in q6afe_port_set_param_v2()
1074 ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_SET_PARAM_V2); in q6afe_port_set_param_v2()
1076 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_set_param_v2()
1083 static int q6afe_port_set_lpass_clock(struct q6afe_port *port, in q6afe_port_set_lpass_clock() argument
1086 return q6afe_port_set_param_v2(port, cfg, in q6afe_port_set_lpass_clock()
1092 static int q6afe_set_lpass_clock_v2(struct q6afe_port *port, in q6afe_set_lpass_clock_v2() argument
1095 return q6afe_port_set_param(port, cfg, AFE_PARAM_ID_CLOCK_SET, in q6afe_set_lpass_clock_v2()
1099 static int q6afe_set_digital_codec_core_clock(struct q6afe_port *port, in q6afe_set_digital_codec_core_clock() argument
1102 return q6afe_port_set_param_v2(port, cfg, in q6afe_set_digital_codec_core_clock()
1111 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_set_lpass_clock()
1127 int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id, in q6afe_port_set_sysclk() argument
1141 ret = q6afe_set_digital_codec_core_clock(port, &dcfg); in q6afe_port_set_sysclk()
1149 ret = q6afe_port_set_lpass_clock(port, &ccfg); in q6afe_port_set_sysclk()
1158 ret = q6afe_port_set_lpass_clock(port, &ccfg); in q6afe_port_set_sysclk()
1170 ret = q6afe_set_lpass_clock_v2(port, &cset); in q6afe_port_set_sysclk()
1173 ret = -EINVAL; in q6afe_port_set_sysclk()
1182 * q6afe_port_stop() - Stop a afe port
1184 * @port: Instance of port to stop
1188 int q6afe_port_stop(struct q6afe_port *port) in q6afe_port_stop() argument
1191 struct q6afe *afe = port->afe; in q6afe_port_stop()
1193 int port_id = port->id; in q6afe_port_stop()
1198 index = port->token; in q6afe_port_stop()
1200 dev_err(afe->dev, "AFE port index[%d] invalid!\n", index); in q6afe_port_stop()
1201 return -EINVAL; in q6afe_port_stop()
1207 return -ENOMEM; in q6afe_port_stop()
1212 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_port_stop()
1215 pkt->hdr.pkt_size = pkt_size; in q6afe_port_stop()
1216 pkt->hdr.src_port = 0; in q6afe_port_stop()
1217 pkt->hdr.dest_port = 0; in q6afe_port_stop()
1218 pkt->hdr.token = index; in q6afe_port_stop()
1219 pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_STOP; in q6afe_port_stop()
1220 stop->port_id = port_id; in q6afe_port_stop()
1221 stop->reserved = 0; in q6afe_port_stop()
1223 ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_DEVICE_STOP); in q6afe_port_stop()
1225 dev_err(afe->dev, "AFE close failed %d\n", ret); in q6afe_port_stop()
1233 * q6afe_slim_port_prepare() - Prepare slim afe port.
1235 * @port: Instance of afe port
1236 * @cfg: SLIM configuration for the afe port
1239 void q6afe_slim_port_prepare(struct q6afe_port *port, in q6afe_slim_port_prepare() argument
1242 union afe_port_config *pcfg = &port->port_cfg; in q6afe_slim_port_prepare()
1244 pcfg->slim_cfg.sb_cfg_minor_version = AFE_API_VERSION_SLIMBUS_CONFIG; in q6afe_slim_port_prepare()
1245 pcfg->slim_cfg.sample_rate = cfg->sample_rate; in q6afe_slim_port_prepare()
1246 pcfg->slim_cfg.bit_width = cfg->bit_width; in q6afe_slim_port_prepare()
1247 pcfg->slim_cfg.num_channels = cfg->num_channels; in q6afe_slim_port_prepare()
1248 pcfg->slim_cfg.data_format = cfg->data_format; in q6afe_slim_port_prepare()
1249 pcfg->slim_cfg.shared_ch_mapping[0] = cfg->ch_mapping[0]; in q6afe_slim_port_prepare()
1250 pcfg->slim_cfg.shared_ch_mapping[1] = cfg->ch_mapping[1]; in q6afe_slim_port_prepare()
1251 pcfg->slim_cfg.shared_ch_mapping[2] = cfg->ch_mapping[2]; in q6afe_slim_port_prepare()
1252 pcfg->slim_cfg.shared_ch_mapping[3] = cfg->ch_mapping[3]; in q6afe_slim_port_prepare()
1258 * q6afe_tdm_port_prepare() - Prepare tdm afe port.
1260 * @port: Instance of afe port
1261 * @cfg: TDM configuration for the afe port
1264 void q6afe_tdm_port_prepare(struct q6afe_port *port, in q6afe_tdm_port_prepare() argument
1267 union afe_port_config *pcfg = &port->port_cfg; in q6afe_tdm_port_prepare()
1269 pcfg->tdm_cfg.tdm_cfg_minor_version = AFE_API_VERSION_TDM_CONFIG; in q6afe_tdm_port_prepare()
1270 pcfg->tdm_cfg.num_channels = cfg->num_channels; in q6afe_tdm_port_prepare()
1271 pcfg->tdm_cfg.sample_rate = cfg->sample_rate; in q6afe_tdm_port_prepare()
1272 pcfg->tdm_cfg.bit_width = cfg->bit_width; in q6afe_tdm_port_prepare()
1273 pcfg->tdm_cfg.data_format = cfg->data_format; in q6afe_tdm_port_prepare()
1274 pcfg->tdm_cfg.sync_mode = cfg->sync_mode; in q6afe_tdm_port_prepare()
1275 pcfg->tdm_cfg.sync_src = cfg->sync_src; in q6afe_tdm_port_prepare()
1276 pcfg->tdm_cfg.nslots_per_frame = cfg->nslots_per_frame; in q6afe_tdm_port_prepare()
1278 pcfg->tdm_cfg.slot_width = cfg->slot_width; in q6afe_tdm_port_prepare()
1279 pcfg->tdm_cfg.slot_mask = cfg->slot_mask; in q6afe_tdm_port_prepare()
1280 port->scfg = kzalloc(sizeof(*port->scfg), GFP_KERNEL); in q6afe_tdm_port_prepare()
1281 if (!port->scfg) in q6afe_tdm_port_prepare()
1284 port->scfg->minor_version = AFE_API_VERSION_SLOT_MAPPING_CONFIG; in q6afe_tdm_port_prepare()
1285 port->scfg->num_channels = cfg->num_channels; in q6afe_tdm_port_prepare()
1286 port->scfg->bitwidth = cfg->bit_width; in q6afe_tdm_port_prepare()
1287 port->scfg->data_align_type = cfg->data_align_type; in q6afe_tdm_port_prepare()
1288 memcpy(port->scfg->ch_mapping, cfg->ch_mapping, in q6afe_tdm_port_prepare()
1294 * q6afe_hdmi_port_prepare() - Prepare hdmi afe port.
1296 * @port: Instance of afe port
1297 * @cfg: HDMI configuration for the afe port
1300 void q6afe_hdmi_port_prepare(struct q6afe_port *port, in q6afe_hdmi_port_prepare() argument
1303 union afe_port_config *pcfg = &port->port_cfg; in q6afe_hdmi_port_prepare()
1305 pcfg->hdmi_multi_ch.hdmi_cfg_minor_version = in q6afe_hdmi_port_prepare()
1307 pcfg->hdmi_multi_ch.datatype = cfg->datatype; in q6afe_hdmi_port_prepare()
1308 pcfg->hdmi_multi_ch.channel_allocation = cfg->channel_allocation; in q6afe_hdmi_port_prepare()
1309 pcfg->hdmi_multi_ch.sample_rate = cfg->sample_rate; in q6afe_hdmi_port_prepare()
1310 pcfg->hdmi_multi_ch.bit_width = cfg->bit_width; in q6afe_hdmi_port_prepare()
1315 * q6afe_i2s_port_prepare() - Prepare i2s afe port.
1317 * @port: Instance of afe port
1318 * @cfg: I2S configuration for the afe port
1321 int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg) in q6afe_i2s_port_prepare() argument
1323 union afe_port_config *pcfg = &port->port_cfg; in q6afe_i2s_port_prepare()
1324 struct device *dev = port->afe->dev; in q6afe_i2s_port_prepare()
1327 pcfg->i2s_cfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG; in q6afe_i2s_port_prepare()
1328 pcfg->i2s_cfg.sample_rate = cfg->sample_rate; in q6afe_i2s_port_prepare()
1329 pcfg->i2s_cfg.bit_width = cfg->bit_width; in q6afe_i2s_port_prepare()
1330 pcfg->i2s_cfg.data_format = AFE_LINEAR_PCM_DATA; in q6afe_i2s_port_prepare()
1332 switch (cfg->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { in q6afe_i2s_port_prepare()
1334 pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL; in q6afe_i2s_port_prepare()
1338 pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL; in q6afe_i2s_port_prepare()
1344 num_sd_lines = hweight_long(cfg->sd_line_mask); in q6afe_i2s_port_prepare()
1349 return -EINVAL; in q6afe_i2s_port_prepare()
1350 case 1: in q6afe_i2s_port_prepare()
1351 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1353 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0; in q6afe_i2s_port_prepare()
1356 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD1; in q6afe_i2s_port_prepare()
1359 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2; in q6afe_i2s_port_prepare()
1362 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD3; in q6afe_i2s_port_prepare()
1366 return -EINVAL; in q6afe_i2s_port_prepare()
1370 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1372 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD01; in q6afe_i2s_port_prepare()
1375 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD23; in q6afe_i2s_port_prepare()
1379 return -EINVAL; in q6afe_i2s_port_prepare()
1383 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1385 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_6CHS; in q6afe_i2s_port_prepare()
1389 return -EINVAL; in q6afe_i2s_port_prepare()
1393 switch (cfg->sd_line_mask) { in q6afe_i2s_port_prepare()
1395 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_8CHS; in q6afe_i2s_port_prepare()
1400 return -EINVAL; in q6afe_i2s_port_prepare()
1405 return -EINVAL; in q6afe_i2s_port_prepare()
1408 switch (cfg->num_channels) { in q6afe_i2s_port_prepare()
1409 case 1: in q6afe_i2s_port_prepare()
1411 switch (pcfg->i2s_cfg.channel_mode) { in q6afe_i2s_port_prepare()
1415 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0; in q6afe_i2s_port_prepare()
1418 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2; in q6afe_i2s_port_prepare()
1422 if (cfg->num_channels == 2) in q6afe_i2s_port_prepare()
1423 pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_STEREO; in q6afe_i2s_port_prepare()
1425 pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_MONO; in q6afe_i2s_port_prepare()
1430 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_QUAD01) { in q6afe_i2s_port_prepare()
1432 return -EINVAL; in q6afe_i2s_port_prepare()
1437 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_6CHS) { in q6afe_i2s_port_prepare()
1439 return -EINVAL; in q6afe_i2s_port_prepare()
1444 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_8CHS) { in q6afe_i2s_port_prepare()
1446 return -EINVAL; in q6afe_i2s_port_prepare()
1458 * q6afe_cdc_dma_port_prepare() - Prepare dma afe port.
1460 * @port: Instance of afe port
1461 * @cfg: DMA configuration for the afe port
1464 void q6afe_cdc_dma_port_prepare(struct q6afe_port *port, in q6afe_cdc_dma_port_prepare() argument
1467 union afe_port_config *pcfg = &port->port_cfg; in q6afe_cdc_dma_port_prepare()
1468 struct afe_param_id_cdc_dma_cfg *dma_cfg = &pcfg->dma_cfg; in q6afe_cdc_dma_port_prepare()
1470 dma_cfg->cdc_dma_cfg_minor_version = AFE_API_VERSION_CODEC_DMA_CONFIG; in q6afe_cdc_dma_port_prepare()
1471 dma_cfg->sample_rate = cfg->sample_rate; in q6afe_cdc_dma_port_prepare()
1472 dma_cfg->bit_width = cfg->bit_width; in q6afe_cdc_dma_port_prepare()
1473 dma_cfg->data_format = cfg->data_format; in q6afe_cdc_dma_port_prepare()
1474 dma_cfg->num_channels = cfg->num_channels; in q6afe_cdc_dma_port_prepare()
1475 if (!cfg->active_channels_mask) in q6afe_cdc_dma_port_prepare()
1476 dma_cfg->active_channels_mask = (1 << cfg->num_channels) - 1; in q6afe_cdc_dma_port_prepare()
1480 * q6afe_port_start() - Start a afe port
1482 * @port: Instance of port to start
1486 int q6afe_port_start(struct q6afe_port *port) in q6afe_port_start() argument
1489 struct q6afe *afe = port->afe; in q6afe_port_start()
1490 int port_id = port->id; in q6afe_port_start()
1491 int ret, param_id = port->cfg_type; in q6afe_port_start()
1496 ret = q6afe_port_set_param_v2(port, &port->port_cfg, param_id, in q6afe_port_start()
1498 sizeof(port->port_cfg)); in q6afe_port_start()
1500 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_start()
1505 if (port->scfg) { in q6afe_port_start()
1506 ret = q6afe_port_set_param_v2(port, port->scfg, in q6afe_port_start()
1508 AFE_MODULE_TDM, sizeof(*port->scfg)); in q6afe_port_start()
1510 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_start()
1519 return -ENOMEM; in q6afe_port_start()
1524 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_port_start()
1527 pkt->hdr.pkt_size = pkt_size; in q6afe_port_start()
1528 pkt->hdr.src_port = 0; in q6afe_port_start()
1529 pkt->hdr.dest_port = 0; in q6afe_port_start()
1530 pkt->hdr.token = port->token; in q6afe_port_start()
1531 pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_START; in q6afe_port_start()
1533 start->port_id = port_id; in q6afe_port_start()
1535 ret = afe_apr_send_pkt(afe, pkt, port, AFE_PORT_CMD_DEVICE_START); in q6afe_port_start()
1537 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", in q6afe_port_start()
1546 * q6afe_port_get_from_id() - Get port instance from a port id
1549 * @id: port id
1551 * Return: Will be an error pointer on error or a valid afe port
1557 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_port_get_from_id()
1558 struct q6afe_port *port; in q6afe_port_get_from_id() local
1563 dev_err(dev, "AFE port token[%d] invalid!\n", id); in q6afe_port_get_from_id()
1564 return ERR_PTR(-EINVAL); in q6afe_port_get_from_id()
1567 /* if port is multiple times bind/unbind before callback finishes */ in q6afe_port_get_from_id()
1568 port = q6afe_find_port(afe, id); in q6afe_port_get_from_id()
1569 if (port) { in q6afe_port_get_from_id()
1570 dev_err(dev, "AFE Port already open\n"); in q6afe_port_get_from_id()
1571 return port; in q6afe_port_get_from_id()
1617 dev_err(dev, "Invalid port id 0x%x\n", port_id); in q6afe_port_get_from_id()
1618 return ERR_PTR(-EINVAL); in q6afe_port_get_from_id()
1621 port = kzalloc(sizeof(*port), GFP_KERNEL); in q6afe_port_get_from_id()
1622 if (!port) in q6afe_port_get_from_id()
1623 return ERR_PTR(-ENOMEM); in q6afe_port_get_from_id()
1625 init_waitqueue_head(&port->wait); in q6afe_port_get_from_id()
1627 port->token = id; in q6afe_port_get_from_id()
1628 port->id = port_id; in q6afe_port_get_from_id()
1629 port->afe = afe; in q6afe_port_get_from_id()
1630 port->cfg_type = cfg_type; in q6afe_port_get_from_id()
1631 kref_init(&port->refcount); in q6afe_port_get_from_id()
1633 spin_lock_irqsave(&afe->port_list_lock, flags); in q6afe_port_get_from_id()
1634 list_add_tail(&port->node, &afe->port_list); in q6afe_port_get_from_id()
1635 spin_unlock_irqrestore(&afe->port_list_lock, flags); in q6afe_port_get_from_id()
1637 return port; in q6afe_port_get_from_id()
1643 * q6afe_port_put() - Release port reference
1645 * @port: Instance of port to put
1647 void q6afe_port_put(struct q6afe_port *port) in q6afe_port_put() argument
1649 kref_put(&port->refcount, q6afe_port_free); in q6afe_port_put()
1656 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_unvote_lpass_core_hw()
1666 return -ENOMEM; in q6afe_unvote_lpass_core_hw()
1671 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_unvote_lpass_core_hw()
1674 pkt->hdr.pkt_size = pkt_size; in q6afe_unvote_lpass_core_hw()
1675 pkt->hdr.src_port = 0; in q6afe_unvote_lpass_core_hw()
1676 pkt->hdr.dest_port = 0; in q6afe_unvote_lpass_core_hw()
1677 pkt->hdr.token = hw_block_id; in q6afe_unvote_lpass_core_hw()
1678 pkt->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST; in q6afe_unvote_lpass_core_hw()
1679 vote_cfg->hw_block_id = hw_block_id; in q6afe_unvote_lpass_core_hw()
1680 vote_cfg->client_handle = client_handle; in q6afe_unvote_lpass_core_hw()
1682 ret = apr_send_pkt(afe->apr, pkt); in q6afe_unvote_lpass_core_hw()
1684 dev_err(afe->dev, "AFE failed to unvote (%d)\n", hw_block_id); in q6afe_unvote_lpass_core_hw()
1694 struct q6afe *afe = dev_get_drvdata(dev->parent); in q6afe_vote_lpass_core_hw()
1704 return -ENOMEM; in q6afe_vote_lpass_core_hw()
1709 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, in q6afe_vote_lpass_core_hw()
1712 pkt->hdr.pkt_size = pkt_size; in q6afe_vote_lpass_core_hw()
1713 pkt->hdr.src_port = 0; in q6afe_vote_lpass_core_hw()
1714 pkt->hdr.dest_port = 0; in q6afe_vote_lpass_core_hw()
1715 pkt->hdr.token = hw_block_id; in q6afe_vote_lpass_core_hw()
1716 pkt->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST; in q6afe_vote_lpass_core_hw()
1717 vote_cfg->hw_block_id = hw_block_id; in q6afe_vote_lpass_core_hw()
1718 strscpy(vote_cfg->client_name, client_name, in q6afe_vote_lpass_core_hw()
1719 sizeof(vote_cfg->client_name)); in q6afe_vote_lpass_core_hw()
1724 dev_err(afe->dev, "AFE failed to vote (%d)\n", hw_block_id); in q6afe_vote_lpass_core_hw()
1735 struct device *dev = &adev->dev; in q6afe_probe()
1739 return -ENOMEM; in q6afe_probe()
1741 q6core_get_svc_api_info(adev->svc_id, &afe->ainfo); in q6afe_probe()
1742 afe->apr = adev; in q6afe_probe()
1743 mutex_init(&afe->lock); in q6afe_probe()
1744 init_waitqueue_head(&afe->wait); in q6afe_probe()
1745 afe->dev = dev; in q6afe_probe()
1746 INIT_LIST_HEAD(&afe->port_list); in q6afe_probe()
1747 spin_lock_init(&afe->port_list_lock); in q6afe_probe()
1766 .name = "qcom-q6afe",