Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) // Copyright(c) 2015-18 Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *  stream.c - SoundWire Bus stream operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/soundwire/sdw_registers.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/soundwire/sdw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include "bus.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  * Array of supported rows and columns as per MIPI SoundWire Specification 1.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  * The rows are arranged as per the array index value programmed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  * in register. The index 15 has dummy value 0 in order to fill hole.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) int sdw_rows[SDW_FRAME_ROWS] = {48, 50, 60, 64, 75, 80, 125, 147,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 			96, 100, 120, 128, 150, 160, 250, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 			192, 200, 240, 256, 72, 144, 90, 180};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) EXPORT_SYMBOL(sdw_rows);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) int sdw_cols[SDW_FRAME_COLS] = {2, 4, 6, 8, 10, 12, 14, 16};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) EXPORT_SYMBOL(sdw_cols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) int sdw_find_col_index(int col)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	for (i = 0; i < SDW_FRAME_COLS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 		if (sdw_cols[i] == col)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	pr_warn("Requested column not found, selecting lowest column no: 2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) EXPORT_SYMBOL(sdw_find_col_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) int sdw_find_row_index(int row)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	for (i = 0; i < SDW_FRAME_ROWS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 		if (sdw_rows[i] == row)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	pr_warn("Requested row not found, selecting lowest row no: 48\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) EXPORT_SYMBOL(sdw_find_row_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) static int _sdw_program_slave_port_params(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 					  struct sdw_slave *slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 					  struct sdw_transport_params *t_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 					  enum sdw_dpn_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	u32 addr1, addr2, addr3, addr4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	u16 wbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	if (bus->params.next_bank) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 		addr1 = SDW_DPN_OFFSETCTRL2_B1(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 		addr2 = SDW_DPN_BLOCKCTRL3_B1(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 		addr3 = SDW_DPN_SAMPLECTRL2_B1(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 		addr4 = SDW_DPN_HCTRL_B1(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 		addr1 = SDW_DPN_OFFSETCTRL2_B0(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 		addr2 = SDW_DPN_BLOCKCTRL3_B0(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 		addr3 = SDW_DPN_SAMPLECTRL2_B0(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 		addr4 = SDW_DPN_HCTRL_B0(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	/* Program DPN_OffsetCtrl2 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	ret = sdw_write(slave, addr1, t_params->offset2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 		dev_err(bus->dev, "DPN_OffsetCtrl2 register write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	/* Program DPN_BlockCtrl3 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	ret = sdw_write(slave, addr2, t_params->blk_pkg_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		dev_err(bus->dev, "DPN_BlockCtrl3 register write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	 * Data ports are FULL, SIMPLE and REDUCED. This function handles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	 * FULL and REDUCED only and beyond this point only FULL is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	 * handled, so bail out if we are not FULL data port type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	if (type != SDW_DPN_FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	/* Program DPN_SampleCtrl2 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	wbuf = FIELD_GET(SDW_DPN_SAMPLECTRL_HIGH, t_params->sample_interval - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	ret = sdw_write(slave, addr3, wbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 		dev_err(bus->dev, "DPN_SampleCtrl2 register write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	/* Program DPN_HCtrl register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	wbuf = FIELD_PREP(SDW_DPN_HCTRL_HSTART, t_params->hstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	wbuf |= FIELD_PREP(SDW_DPN_HCTRL_HSTOP, t_params->hstop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	ret = sdw_write(slave, addr4, wbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		dev_err(bus->dev, "DPN_HCtrl register write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) static int sdw_program_slave_port_params(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 					 struct sdw_slave_runtime *s_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 					 struct sdw_port_runtime *p_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	struct sdw_transport_params *t_params = &p_rt->transport_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	struct sdw_port_params *p_params = &p_rt->port_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	struct sdw_slave_prop *slave_prop = &s_rt->slave->prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	u32 addr1, addr2, addr3, addr4, addr5, addr6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	struct sdw_dpn_prop *dpn_prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	u8 wbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	dpn_prop = sdw_get_slave_dpn_prop(s_rt->slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 					  s_rt->direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 					  t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	if (!dpn_prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	addr1 = SDW_DPN_PORTCTRL(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	addr2 = SDW_DPN_BLOCKCTRL1(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	if (bus->params.next_bank) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 		addr3 = SDW_DPN_SAMPLECTRL1_B1(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		addr4 = SDW_DPN_OFFSETCTRL1_B1(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		addr5 = SDW_DPN_BLOCKCTRL2_B1(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		addr6 = SDW_DPN_LANECTRL_B1(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 		addr3 = SDW_DPN_SAMPLECTRL1_B0(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 		addr4 = SDW_DPN_OFFSETCTRL1_B0(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 		addr5 = SDW_DPN_BLOCKCTRL2_B0(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 		addr6 = SDW_DPN_LANECTRL_B0(t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	/* Program DPN_PortCtrl register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	wbuf = FIELD_PREP(SDW_DPN_PORTCTRL_DATAMODE, p_params->data_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	wbuf |= FIELD_PREP(SDW_DPN_PORTCTRL_FLOWMODE, p_params->flow_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	ret = sdw_update(s_rt->slave, addr1, 0xF, wbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		dev_err(&s_rt->slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 			"DPN_PortCtrl register write failed for port %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 			t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	if (!dpn_prop->read_only_wordlength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		/* Program DPN_BlockCtrl1 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 		ret = sdw_write(s_rt->slave, addr2, (p_params->bps - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 			dev_err(&s_rt->slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 				"DPN_BlockCtrl1 register write failed for port %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 				t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	/* Program DPN_SampleCtrl1 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	wbuf = (t_params->sample_interval - 1) & SDW_DPN_SAMPLECTRL_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	ret = sdw_write(s_rt->slave, addr3, wbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		dev_err(&s_rt->slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 			"DPN_SampleCtrl1 register write failed for port %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 			t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	/* Program DPN_OffsetCtrl1 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	ret = sdw_write(s_rt->slave, addr4, t_params->offset1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		dev_err(&s_rt->slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 			"DPN_OffsetCtrl1 register write failed for port %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 			t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	/* Program DPN_BlockCtrl2 register*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	if (t_params->blk_grp_ctrl_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		ret = sdw_write(s_rt->slave, addr5, t_params->blk_grp_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 			dev_err(&s_rt->slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 				"DPN_BlockCtrl2 reg write failed for port %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 				t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	/* program DPN_LaneCtrl register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	if (slave_prop->lane_control_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 		ret = sdw_write(s_rt->slave, addr6, t_params->lane_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 			dev_err(&s_rt->slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 				"DPN_LaneCtrl register write failed for port %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 				t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	if (dpn_prop->type != SDW_DPN_SIMPLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		ret = _sdw_program_slave_port_params(bus, s_rt->slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 						     t_params, dpn_prop->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 			dev_err(&s_rt->slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 				"Transport reg write failed for port: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 				t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) static int sdw_program_master_port_params(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 					  struct sdw_port_runtime *p_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	 * we need to set transport and port parameters for the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	 * Transport parameters refers to the sample interval, offsets and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	 * hstart/stop etc of the data. Port parameters refers to word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	 * length, flow mode etc of the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	ret = bus->port_ops->dpn_set_port_transport_params(bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 					&p_rt->transport_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 					bus->params.next_bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	return bus->port_ops->dpn_set_port_params(bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 						  &p_rt->port_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 						  bus->params.next_bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257)  * sdw_program_port_params() - Programs transport parameters of Master(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258)  * and Slave(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260)  * @m_rt: Master stream runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) static int sdw_program_port_params(struct sdw_master_runtime *m_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	struct sdw_slave_runtime *s_rt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	struct sdw_bus *bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	struct sdw_port_runtime *p_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	/* Program transport & port parameters for Slave(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		list_for_each_entry(p_rt, &s_rt->port_list, port_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 			ret = sdw_program_slave_port_params(bus, s_rt, p_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	/* Program transport & port parameters for Master(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		ret = sdw_program_master_port_params(bus, p_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289)  * sdw_enable_disable_slave_ports: Enable/disable slave data port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291)  * @bus: bus instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292)  * @s_rt: slave runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293)  * @p_rt: port runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294)  * @en: enable or disable operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296)  * This function only sets the enable/disable bits in the relevant bank, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297)  * actual enable/disable is done with a bank switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) static int sdw_enable_disable_slave_ports(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 					  struct sdw_slave_runtime *s_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 					  struct sdw_port_runtime *p_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 					  bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	struct sdw_transport_params *t_params = &p_rt->transport_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	if (bus->params.next_bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		addr = SDW_DPN_CHANNELEN_B1(p_rt->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		addr = SDW_DPN_CHANNELEN_B0(p_rt->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	 * Since bus doesn't support sharing a port across two streams,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	 * it is safe to reset this register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	if (en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		ret = sdw_write(s_rt->slave, addr, p_rt->ch_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		ret = sdw_write(s_rt->slave, addr, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		dev_err(&s_rt->slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 			"Slave chn_en reg write failed:%d port:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 			ret, t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) static int sdw_enable_disable_master_ports(struct sdw_master_runtime *m_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 					   struct sdw_port_runtime *p_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 					   bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	struct sdw_transport_params *t_params = &p_rt->transport_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	struct sdw_bus *bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	struct sdw_enable_ch enable_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	enable_ch.port_num = p_rt->num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	enable_ch.ch_mask = p_rt->ch_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	enable_ch.enable = en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	/* Perform Master port channel(s) enable/disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	if (bus->port_ops->dpn_port_enable_ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		ret = bus->port_ops->dpn_port_enable_ch(bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 							&enable_ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 							bus->params.next_bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 			dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 				"Master chn_en write failed:%d port:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 				ret, t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 			"dpn_port_enable_ch not supported, %s failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 			en ? "enable" : "disable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365)  * sdw_enable_disable_ports() - Enable/disable port(s) for Master and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366)  * Slave(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368)  * @m_rt: Master stream runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369)  * @en: mode (enable/disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) static int sdw_enable_disable_ports(struct sdw_master_runtime *m_rt, bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	struct sdw_port_runtime *s_port, *m_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	struct sdw_slave_runtime *s_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	/* Enable/Disable Slave port(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		list_for_each_entry(s_port, &s_rt->port_list, port_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 			ret = sdw_enable_disable_slave_ports(m_rt->bus, s_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 							     s_port, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	/* Enable/Disable Master port(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	list_for_each_entry(m_port, &m_rt->port_list, port_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		ret = sdw_enable_disable_master_ports(m_rt, m_port, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) static int sdw_do_port_prep(struct sdw_slave_runtime *s_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			    struct sdw_prepare_ch prep_ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 			    enum sdw_port_prep_ops cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	const struct sdw_slave_ops *ops = s_rt->slave->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	if (ops->port_prep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		ret = ops->port_prep(s_rt->slave, &prep_ch, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			dev_err(&s_rt->slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 				"Slave Port Prep cmd %d failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 				cmd, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 				       struct sdw_slave_runtime *s_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 				       struct sdw_port_runtime *p_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 				       bool prep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	struct completion *port_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	struct sdw_dpn_prop *dpn_prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	struct sdw_prepare_ch prep_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	bool intr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	int ret = 0, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	prep_ch.num = p_rt->num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	prep_ch.ch_mask = p_rt->ch_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	dpn_prop = sdw_get_slave_dpn_prop(s_rt->slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 					  s_rt->direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 					  prep_ch.num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	if (!dpn_prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			"Slave Port:%d properties not found\n", prep_ch.num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	prep_ch.prepare = prep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	prep_ch.bank = bus->params.next_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	if (dpn_prop->imp_def_interrupts || !dpn_prop->simple_ch_prep_sm ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	    bus->params.s_data_mode != SDW_PORT_DATA_MODE_NORMAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		intr = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	 * Enable interrupt before Port prepare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	 * For Port de-prepare, it is assumed that port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	 * was prepared earlier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	if (prep && intr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		ret = sdw_configure_dpn_intr(s_rt->slave, p_rt->num, prep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 					     dpn_prop->imp_def_interrupts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	/* Inform slave about the impending port prepare */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	sdw_do_port_prep(s_rt, prep_ch, SDW_OPS_PORT_PRE_PREP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	/* Prepare Slave port implementing CP_SM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	if (!dpn_prop->simple_ch_prep_sm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		addr = SDW_DPN_PREPARECTRL(p_rt->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		if (prep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 			ret = sdw_write(s_rt->slave, addr, p_rt->ch_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			ret = sdw_write(s_rt->slave, addr, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 			dev_err(&s_rt->slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 				"Slave prep_ctrl reg write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		/* Wait for completion on port ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		port_ready = &s_rt->slave->port_ready[prep_ch.num];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		wait_for_completion_timeout(port_ready,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 			msecs_to_jiffies(dpn_prop->ch_prep_timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		val = sdw_read(s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		if ((val < 0) || (val & p_rt->ch_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 			ret = (val < 0) ? val : -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 			dev_err(&s_rt->slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 				"Chn prep failed for port %d: %d\n", prep_ch.num, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	/* Inform slaves about ports prepared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	sdw_do_port_prep(s_rt, prep_ch, SDW_OPS_PORT_POST_PREP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	/* Disable interrupt after Port de-prepare */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	if (!prep && intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		ret = sdw_configure_dpn_intr(s_rt->slave, p_rt->num, prep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 					     dpn_prop->imp_def_interrupts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) static int sdw_prep_deprep_master_ports(struct sdw_master_runtime *m_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 					struct sdw_port_runtime *p_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 					bool prep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	struct sdw_transport_params *t_params = &p_rt->transport_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	struct sdw_bus *bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	const struct sdw_master_port_ops *ops = bus->port_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	struct sdw_prepare_ch prep_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	prep_ch.num = p_rt->num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	prep_ch.ch_mask = p_rt->ch_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	prep_ch.prepare = prep; /* Prepare/De-prepare */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	prep_ch.bank = bus->params.next_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	/* Pre-prepare/Pre-deprepare port(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	if (ops->dpn_port_prep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		ret = ops->dpn_port_prep(bus, &prep_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 			dev_err(bus->dev, "Port prepare failed for port:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 				t_params->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533)  * sdw_prep_deprep_ports() - Prepare/De-prepare port(s) for Master(s) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534)  * Slave(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536)  * @m_rt: Master runtime handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537)  * @prep: Prepare or De-prepare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) static int sdw_prep_deprep_ports(struct sdw_master_runtime *m_rt, bool prep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	struct sdw_slave_runtime *s_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	struct sdw_port_runtime *p_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	/* Prepare/De-prepare Slave port(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		list_for_each_entry(p_rt, &s_rt->port_list, port_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 			ret = sdw_prep_deprep_slave_ports(m_rt->bus, s_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 							  p_rt, prep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	/* Prepare/De-prepare Master port(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		ret = sdw_prep_deprep_master_ports(m_rt, p_rt, prep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566)  * sdw_notify_config() - Notify bus configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568)  * @m_rt: Master runtime handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570)  * This function notifies the Master(s) and Slave(s) of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571)  * new bus configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) static int sdw_notify_config(struct sdw_master_runtime *m_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	struct sdw_slave_runtime *s_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	struct sdw_bus *bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	struct sdw_slave *slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	if (bus->ops->set_bus_conf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		ret = bus->ops->set_bus_conf(bus, &bus->params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		slave = s_rt->slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		if (slave->ops->bus_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 			ret = slave->ops->bus_config(slave, &bus->params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 				dev_err(bus->dev, "Notify Slave: %d failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 					slave->dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603)  * sdw_program_params() - Program transport and port parameters for Master(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604)  * and Slave(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606)  * @bus: SDW bus instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607)  * @prepare: true if sdw_program_params() is called by _prepare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) static int sdw_program_params(struct sdw_bus *bus, bool prepare)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		 * this loop walks through all master runtimes for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		 * bus, but the ports can only be configured while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 		 * explicitly preparing a stream or handling an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		 * already-prepared stream otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		if (!prepare &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		    m_rt->stream->state == SDW_STREAM_CONFIGURED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		ret = sdw_program_port_params(m_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 			dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 				"Program transport params failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		ret = sdw_notify_config(m_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 			dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 				"Notify bus config failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		/* Enable port(s) on alternate bank for all active streams */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		if (m_rt->stream->state != SDW_STREAM_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		ret = sdw_enable_disable_ports(m_rt, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			dev_err(bus->dev, "Enable channel failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) static int sdw_bank_switch(struct sdw_bus *bus, int m_rt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	int col_index, row_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	bool multi_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	struct sdw_msg *wr_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	u8 *wbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	u16 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	wr_msg = kzalloc(sizeof(*wr_msg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	if (!wr_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	bus->defer_msg.msg = wr_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	wbuf = kzalloc(sizeof(*wbuf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	if (!wbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		goto error_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	/* Get row and column index to program register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	col_index = sdw_find_col_index(bus->params.col);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	row_index = sdw_find_row_index(bus->params.row);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	wbuf[0] = col_index | (row_index << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	if (bus->params.next_bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		addr = SDW_SCP_FRAMECTRL_B1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		addr = SDW_SCP_FRAMECTRL_B0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	sdw_fill_msg(wr_msg, NULL, addr, 1, SDW_BROADCAST_DEV_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		     SDW_MSG_FLAG_WRITE, wbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	wr_msg->ssp_sync = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	 * Set the multi_link flag only when both the hardware supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	 * and hardware-based sync is required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	multi_link = bus->multi_link && (m_rt_count >= bus->hw_sync_min_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	if (multi_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		ret = sdw_transfer_defer(bus, wr_msg, &bus->defer_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		ret = sdw_transfer(bus, wr_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		dev_err(bus->dev, "Slave frame_ctrl reg write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	if (!multi_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		kfree(wr_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		kfree(wbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		bus->defer_msg.msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		bus->params.curr_bank = !bus->params.curr_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		bus->params.next_bank = !bus->params.next_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	kfree(wbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) error_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	kfree(wr_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	bus->defer_msg.msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724)  * sdw_ml_sync_bank_switch: Multilink register bank switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726)  * @bus: SDW bus instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728)  * Caller function should free the buffers on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) static int sdw_ml_sync_bank_switch(struct sdw_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	unsigned long time_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	if (!bus->multi_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	/* Wait for completion of transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	time_left = wait_for_completion_timeout(&bus->defer_msg.complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 						bus->bank_switch_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	if (!time_left) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		dev_err(bus->dev, "Controller Timed out on bank switch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	bus->params.curr_bank = !bus->params.curr_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	bus->params.next_bank = !bus->params.next_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	if (bus->defer_msg.msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		kfree(bus->defer_msg.msg->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		kfree(bus->defer_msg.msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) static int do_bank_switch(struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	const struct sdw_master_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	struct sdw_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	bool multi_link = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	int m_rt_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	m_rt_count = stream->m_rt_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		ops = bus->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		if (bus->multi_link && m_rt_count >= bus->hw_sync_min_links) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			multi_link = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			mutex_lock(&bus->msg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		/* Pre-bank switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		if (ops->pre_bank_switch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 			ret = ops->pre_bank_switch(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 				dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 					"Pre bank switch op failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 				goto msg_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		 * Perform Bank switch operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		 * For multi link cases, the actual bank switch is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		 * synchronized across all Masters and happens later as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		 * part of post_bank_switch ops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		ret = sdw_bank_switch(bus, m_rt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 			dev_err(bus->dev, "Bank switch failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	 * For multi link cases, it is expected that the bank switch is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	 * triggered by the post_bank_switch for the first Master in the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	 * and for the other Masters the post_bank_switch() should return doing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	 * nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		ops = bus->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		/* Post-bank switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		if (ops->post_bank_switch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 			ret = ops->post_bank_switch(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 				dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 					"Post bank switch op failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 					ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		} else if (multi_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 			dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 				"Post bank switch ops not implemented\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		/* Set the bank switch timeout to default, if not set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		if (!bus->bank_switch_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 			bus->bank_switch_timeout = DEFAULT_BANK_SWITCH_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		/* Check if bank switch was successful */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		ret = sdw_ml_sync_bank_switch(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 				"multi link bank switch failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		if (multi_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 			mutex_unlock(&bus->msg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		if (bus->defer_msg.msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 			kfree(bus->defer_msg.msg->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 			kfree(bus->defer_msg.msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) msg_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	if (multi_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 			if (mutex_is_locked(&bus->msg_lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 				mutex_unlock(&bus->msg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866)  * sdw_release_stream() - Free the assigned stream runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868)  * @stream: SoundWire stream runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870)  * sdw_release_stream should be called only once per stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) void sdw_release_stream(struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	kfree(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) EXPORT_SYMBOL(sdw_release_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879)  * sdw_alloc_stream() - Allocate and return stream runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881)  * @stream_name: SoundWire stream name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883)  * Allocates a SoundWire stream runtime instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884)  * sdw_alloc_stream should be called only once per stream. Typically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885)  * invoked from ALSA/ASoC machine/platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) struct sdw_stream_runtime *sdw_alloc_stream(const char *stream_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	struct sdw_stream_runtime *stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	if (!stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	stream->name = stream_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	INIT_LIST_HEAD(&stream->master_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	stream->state = SDW_STREAM_ALLOCATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	stream->m_rt_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	return stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) EXPORT_SYMBOL(sdw_alloc_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) static struct sdw_master_runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) *sdw_find_master_rt(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		    struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	/* Retrieve Bus handle if already available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		if (m_rt->bus == bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 			return m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920)  * sdw_alloc_master_rt() - Allocates and initialize Master runtime handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922)  * @bus: SDW bus instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923)  * @stream_config: Stream configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924)  * @stream: Stream runtime handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926)  * This function is to be called with bus_lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) static struct sdw_master_runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) *sdw_alloc_master_rt(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		     struct sdw_stream_config *stream_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		     struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	 * check if Master is already allocated (as a result of Slave adding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	 * it first), if so skip allocation and go to configure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	m_rt = sdw_find_master_rt(bus, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	if (m_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		goto stream_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	m_rt = kzalloc(sizeof(*m_rt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	if (!m_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	/* Initialization of Master runtime handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	INIT_LIST_HEAD(&m_rt->port_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	INIT_LIST_HEAD(&m_rt->slave_rt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	list_add_tail(&m_rt->stream_node, &stream->master_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	list_add_tail(&m_rt->bus_node, &bus->m_rt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) stream_config:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	m_rt->ch_count = stream_config->ch_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	m_rt->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	m_rt->stream = stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	m_rt->direction = stream_config->direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	return m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964)  * sdw_alloc_slave_rt() - Allocate and initialize Slave runtime handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966)  * @slave: Slave handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967)  * @stream_config: Stream configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968)  * @stream: Stream runtime handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970)  * This function is to be called with bus_lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) static struct sdw_slave_runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) *sdw_alloc_slave_rt(struct sdw_slave *slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		    struct sdw_stream_config *stream_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		    struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	struct sdw_slave_runtime *s_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	s_rt = kzalloc(sizeof(*s_rt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	if (!s_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	INIT_LIST_HEAD(&s_rt->port_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	s_rt->ch_count = stream_config->ch_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	s_rt->direction = stream_config->direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	s_rt->slave = slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	return s_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) static void sdw_master_port_release(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 				    struct sdw_master_runtime *m_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	struct sdw_port_runtime *p_rt, *_p_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	list_for_each_entry_safe(p_rt, _p_rt, &m_rt->port_list, port_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		list_del(&p_rt->port_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		kfree(p_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static void sdw_slave_port_release(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 				   struct sdw_slave *slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 				   struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	struct sdw_port_runtime *p_rt, *_p_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	struct sdw_slave_runtime *s_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 			if (s_rt->slave != slave)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 			list_for_each_entry_safe(p_rt, _p_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 						 &s_rt->port_list, port_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 				list_del(&p_rt->port_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 				kfree(p_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)  * sdw_release_slave_stream() - Free Slave(s) runtime handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)  * @slave: Slave handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)  * @stream: Stream runtime handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)  * This function is to be called with bus_lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static void sdw_release_slave_stream(struct sdw_slave *slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 				     struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	struct sdw_slave_runtime *s_rt, *_s_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		/* Retrieve Slave runtime handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		list_for_each_entry_safe(s_rt, _s_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 					 &m_rt->slave_rt_list, m_rt_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 			if (s_rt->slave == slave) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 				list_del(&s_rt->m_rt_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 				kfree(s_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)  * sdw_release_master_stream() - Free Master runtime handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)  * @m_rt: Master runtime node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)  * @stream: Stream runtime handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)  * This function is to be called with bus_lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)  * It frees the Master runtime handle and associated Slave(s) runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)  * handle. If this is called first then sdw_release_slave_stream() will have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)  * no effect as Slave(s) runtime handle would already be freed up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static void sdw_release_master_stream(struct sdw_master_runtime *m_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 				      struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	struct sdw_slave_runtime *s_rt, *_s_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	list_for_each_entry_safe(s_rt, _s_rt, &m_rt->slave_rt_list, m_rt_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		sdw_slave_port_release(s_rt->slave->bus, s_rt->slave, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		sdw_release_slave_stream(s_rt->slave, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	list_del(&m_rt->stream_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	list_del(&m_rt->bus_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	kfree(m_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)  * sdw_stream_remove_master() - Remove master from sdw_stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)  * @bus: SDW Bus instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)  * @stream: SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)  * This removes and frees port_rt and master_rt from a stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) int sdw_stream_remove_master(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 			     struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	struct sdw_master_runtime *m_rt, *_m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	mutex_lock(&bus->bus_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	list_for_each_entry_safe(m_rt, _m_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 				 &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		if (m_rt->bus != bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		sdw_master_port_release(bus, m_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		sdw_release_master_stream(m_rt, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		stream->m_rt_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	if (list_empty(&stream->master_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		stream->state = SDW_STREAM_RELEASED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	mutex_unlock(&bus->bus_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) EXPORT_SYMBOL(sdw_stream_remove_master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)  * sdw_stream_remove_slave() - Remove slave from sdw_stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)  * @slave: SDW Slave instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)  * @stream: SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)  * This removes and frees port_rt and slave_rt from a stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) int sdw_stream_remove_slave(struct sdw_slave *slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 			    struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	mutex_lock(&slave->bus->bus_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	sdw_slave_port_release(slave->bus, slave, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	sdw_release_slave_stream(slave, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	mutex_unlock(&slave->bus->bus_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) EXPORT_SYMBOL(sdw_stream_remove_slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)  * sdw_config_stream() - Configure the allocated stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)  * @dev: SDW device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)  * @stream: SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)  * @stream_config: Stream configuration for audio stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)  * @is_slave: is API called from Slave or Master
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)  * This function is to be called with bus_lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) static int sdw_config_stream(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 			     struct sdw_stream_runtime *stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 			     struct sdw_stream_config *stream_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			     bool is_slave)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	 * Update the stream rate, channel and bps based on data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	 * source. For more than one data source (multilink),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	 * match the rate, bps, stream type and increment number of channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	 * If rate/bps is zero, it means the values are not set, so skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	 * comparison and allow the value to be set and stored in stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	if (stream->params.rate &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	    stream->params.rate != stream_config->frame_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		dev_err(dev, "rate not matching, stream:%s\n", stream->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	if (stream->params.bps &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	    stream->params.bps != stream_config->bps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		dev_err(dev, "bps not matching, stream:%s\n", stream->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	stream->type = stream_config->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	stream->params.rate = stream_config->frame_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	stream->params.bps = stream_config->bps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	/* TODO: Update this check during Device-device support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	if (is_slave)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		stream->params.ch_count += stream_config->ch_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) static int sdw_is_valid_port_range(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 				   struct sdw_port_runtime *p_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	if (!SDW_VALID_PORT_RANGE(p_rt->num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 			"SoundWire: Invalid port number :%d\n", p_rt->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) static struct sdw_port_runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) *sdw_port_alloc(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		struct sdw_port_config *port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		int port_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	struct sdw_port_runtime *p_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	p_rt = kzalloc(sizeof(*p_rt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	if (!p_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	p_rt->ch_mask = port_config[port_index].ch_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	p_rt->num = port_config[port_index].num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	return p_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) static int sdw_master_port_config(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 				  struct sdw_master_runtime *m_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 				  struct sdw_port_config *port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 				  unsigned int num_ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	struct sdw_port_runtime *p_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	/* Iterate for number of ports to perform initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	for (i = 0; i < num_ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 		p_rt = sdw_port_alloc(bus->dev, port_config, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		if (!p_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		 * TODO: Check port capabilities for requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		 * configuration (audio mode support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		list_add_tail(&p_rt->port_node, &m_rt->port_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) static int sdw_slave_port_config(struct sdw_slave *slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 				 struct sdw_slave_runtime *s_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 				 struct sdw_port_config *port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 				 unsigned int num_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	struct sdw_port_runtime *p_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	/* Iterate for number of ports to perform initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	for (i = 0; i < num_config; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		p_rt = sdw_port_alloc(&slave->dev, port_config, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		if (!p_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 		 * TODO: Check valid port range as defined by DisCo/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		 * slave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		ret = sdw_is_valid_port_range(&slave->dev, p_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 			kfree(p_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		 * TODO: Check port capabilities for requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 		 * configuration (audio mode support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 		list_add_tail(&p_rt->port_node, &s_rt->port_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)  * sdw_stream_add_master() - Allocate and add master runtime to a stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)  * @bus: SDW Bus instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)  * @stream_config: Stream configuration for audio stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)  * @port_config: Port configuration for audio stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)  * @num_ports: Number of ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)  * @stream: SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) int sdw_stream_add_master(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 			  struct sdw_stream_config *stream_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 			  struct sdw_port_config *port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 			  unsigned int num_ports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 			  struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	mutex_lock(&bus->bus_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	 * For multi link streams, add the second master only if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	 * the bus supports it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	 * Check if bus->multi_link is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	if (!bus->multi_link && stream->m_rt_count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 			"Multilink not supported, link %d\n", bus->link_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	m_rt = sdw_alloc_master_rt(bus, stream_config, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	if (!m_rt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 			"Master runtime config failed for stream:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 			stream->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	ret = sdw_config_stream(bus->dev, stream, stream_config, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 		goto stream_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	ret = sdw_master_port_config(bus, m_rt, port_config, num_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		goto stream_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	stream->m_rt_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) stream_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	sdw_release_master_stream(m_rt, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	mutex_unlock(&bus->bus_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) EXPORT_SYMBOL(sdw_stream_add_master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)  * sdw_stream_add_slave() - Allocate and add master/slave runtime to a stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)  * @slave: SDW Slave instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)  * @stream_config: Stream configuration for audio stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)  * @stream: SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)  * @port_config: Port configuration for audio stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)  * @num_ports: Number of ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)  * It is expected that Slave is added before adding Master
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)  * to the Stream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) int sdw_stream_add_slave(struct sdw_slave *slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 			 struct sdw_stream_config *stream_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 			 struct sdw_port_config *port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 			 unsigned int num_ports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 			 struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	struct sdw_slave_runtime *s_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	mutex_lock(&slave->bus->bus_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	 * If this API is invoked by Slave first then m_rt is not valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	 * So, allocate m_rt and add Slave to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	m_rt = sdw_alloc_master_rt(slave->bus, stream_config, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	if (!m_rt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		dev_err(&slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 			"alloc master runtime failed for stream:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 			stream->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	s_rt = sdw_alloc_slave_rt(slave, stream_config, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	if (!s_rt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		dev_err(&slave->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 			"Slave runtime config failed for stream:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 			stream->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		goto stream_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	ret = sdw_config_stream(&slave->dev, stream, stream_config, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		 * sdw_release_master_stream will release s_rt in slave_rt_list in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 		 * stream_error case, but s_rt is only added to slave_rt_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 		 * when sdw_config_stream is successful, so free s_rt explicitly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		 * when sdw_config_stream is failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		kfree(s_rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		goto stream_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	list_add_tail(&s_rt->m_rt_node, &m_rt->slave_rt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	ret = sdw_slave_port_config(slave, s_rt, port_config, num_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 		goto stream_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	 * Change stream state to CONFIGURED on first Slave add.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	 * Bus is not aware of number of Slave(s) in a stream at this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	 * point so cannot depend on all Slave(s) to be added in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	 * change stream state to CONFIGURED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	stream->state = SDW_STREAM_CONFIGURED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) stream_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	 * we hit error so cleanup the stream, release all Slave(s) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	 * Master runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	sdw_release_master_stream(m_rt, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	mutex_unlock(&slave->bus->bus_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) EXPORT_SYMBOL(sdw_stream_add_slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)  * sdw_get_slave_dpn_prop() - Get Slave port capabilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)  * @slave: Slave handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)  * @direction: Data direction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)  * @port_num: Port number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 					    enum sdw_data_direction direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 					    unsigned int port_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	struct sdw_dpn_prop *dpn_prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	u8 num_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	if (direction == SDW_DATA_DIR_TX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 		num_ports = hweight32(slave->prop.source_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 		dpn_prop = slave->prop.src_dpn_prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 		num_ports = hweight32(slave->prop.sink_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 		dpn_prop = slave->prop.sink_dpn_prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	for (i = 0; i < num_ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 		if (dpn_prop[i].num == port_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 			return &dpn_prop[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)  * sdw_acquire_bus_lock: Acquire bus lock for all Master runtime(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)  * @stream: SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)  * Acquire bus_lock for each of the master runtime(m_rt) part of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)  * stream to reconfigure the bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)  * NOTE: This function is called from SoundWire stream ops and is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)  * expected that a global lock is held before acquiring bus_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) static void sdw_acquire_bus_lock(struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	struct sdw_bus *bus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	/* Iterate for all Master(s) in Master list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		mutex_lock(&bus->bus_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)  * sdw_release_bus_lock: Release bus lock for all Master runtime(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)  * @stream: SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)  * Release the previously held bus_lock after reconfiguring the bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)  * NOTE: This function is called from SoundWire stream ops and is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)  * expected that a global lock is held before releasing bus_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) static void sdw_release_bus_lock(struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	struct sdw_master_runtime *m_rt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	struct sdw_bus *bus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	/* Iterate for all Master(s) in Master list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	list_for_each_entry_reverse(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		mutex_unlock(&bus->bus_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) static int _sdw_prepare_stream(struct sdw_stream_runtime *stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 			       bool update_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	struct sdw_bus *bus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	struct sdw_master_prop *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	struct sdw_bus_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	/* Prepare  Master(s) and Slave(s) port(s) associated with stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 		bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 		prop = &bus->prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 		memcpy(&params, &bus->params, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 		/* TODO: Support Asynchronous mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 		if ((prop->max_clk_freq % stream->params.rate) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 			dev_err(bus->dev, "Async mode not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 		if (!update_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 			goto program_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		/* Increment cumulative bus bandwidth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 		/* TODO: Update this during Device-Device support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 		bus->params.bandwidth += m_rt->stream->params.rate *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 			m_rt->ch_count * m_rt->stream->params.bps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		/* Compute params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 		if (bus->compute_params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 			ret = bus->compute_params(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 				dev_err(bus->dev, "Compute params failed: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 					ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) program_params:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 		/* Program params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 		ret = sdw_program_params(bus, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 			dev_err(bus->dev, "Program params failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 			goto restore_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	if (!bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 		pr_err("Configuration error in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	ret = do_bank_switch(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		dev_err(bus->dev, "Bank switch failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		goto restore_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 		bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 		/* Prepare port(s) on the new clock configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 		ret = sdw_prep_deprep_ports(m_rt, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 			dev_err(bus->dev, "Prepare port(s) failed ret = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 				ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	stream->state = SDW_STREAM_PREPARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) restore_params:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	memcpy(&bus->params, &params, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)  * sdw_prepare_stream() - Prepare SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)  * @stream: Soundwire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)  * Documentation/driver-api/soundwire/stream.rst explains this API in detail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) int sdw_prepare_stream(struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	bool update_params = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	if (!stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 		pr_err("SoundWire: Handle not found for stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	sdw_acquire_bus_lock(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	if (stream->state == SDW_STREAM_PREPARED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 		goto state_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	if (stream->state != SDW_STREAM_CONFIGURED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	    stream->state != SDW_STREAM_DEPREPARED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	    stream->state != SDW_STREAM_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 		pr_err("%s: %s: inconsistent state state %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 		       __func__, stream->name, stream->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		goto state_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	 * when the stream is DISABLED, this means sdw_prepare_stream()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	 * is called as a result of an underflow or a resume operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	 * In this case, the bus parameters shall not be recomputed, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	 * still need to be re-applied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	if (stream->state == SDW_STREAM_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 		update_params = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	ret = _sdw_prepare_stream(stream, update_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) state_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	sdw_release_bus_lock(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) EXPORT_SYMBOL(sdw_prepare_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) static int _sdw_enable_stream(struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	struct sdw_bus *bus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	/* Enable Master(s) and Slave(s) port(s) associated with stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 		/* Program params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		ret = sdw_program_params(bus, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 			dev_err(bus->dev, "Program params failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		/* Enable port(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 		ret = sdw_enable_disable_ports(m_rt, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 			dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 				"Enable port(s) failed ret: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	if (!bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		pr_err("Configuration error in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	ret = do_bank_switch(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 		dev_err(bus->dev, "Bank switch failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	stream->state = SDW_STREAM_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)  * sdw_enable_stream() - Enable SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)  * @stream: Soundwire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)  * Documentation/driver-api/soundwire/stream.rst explains this API in detail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) int sdw_enable_stream(struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	if (!stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 		pr_err("SoundWire: Handle not found for stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	sdw_acquire_bus_lock(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	if (stream->state != SDW_STREAM_PREPARED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	    stream->state != SDW_STREAM_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 		pr_err("%s: %s: inconsistent state state %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		       __func__, stream->name, stream->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		goto state_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	ret = _sdw_enable_stream(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) state_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	sdw_release_bus_lock(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) EXPORT_SYMBOL(sdw_enable_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) static int _sdw_disable_stream(struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 		struct sdw_bus *bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 		/* Disable port(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 		ret = sdw_enable_disable_ports(m_rt, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 			dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	stream->state = SDW_STREAM_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		struct sdw_bus *bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 		/* Program params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 		ret = sdw_program_params(bus, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 			dev_err(bus->dev, "Program params failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	ret = do_bank_switch(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 		pr_err("Bank switch failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	/* make sure alternate bank (previous current) is also disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 		struct sdw_bus *bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		/* Disable port(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 		ret = sdw_enable_disable_ports(m_rt, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 			dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)  * sdw_disable_stream() - Disable SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)  * @stream: Soundwire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)  * Documentation/driver-api/soundwire/stream.rst explains this API in detail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) int sdw_disable_stream(struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	if (!stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 		pr_err("SoundWire: Handle not found for stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	sdw_acquire_bus_lock(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	if (stream->state != SDW_STREAM_ENABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 		pr_err("%s: %s: inconsistent state state %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 		       __func__, stream->name, stream->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 		goto state_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	ret = _sdw_disable_stream(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) state_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	sdw_release_bus_lock(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) EXPORT_SYMBOL(sdw_disable_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) static int _sdw_deprepare_stream(struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	struct sdw_master_runtime *m_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 	struct sdw_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 		bus = m_rt->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 		/* De-prepare port(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 		ret = sdw_prep_deprep_ports(m_rt, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 			dev_err(bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 				"De-prepare port(s) failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 		/* TODO: Update this during Device-Device support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 		bus->params.bandwidth -= m_rt->stream->params.rate *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 			m_rt->ch_count * m_rt->stream->params.bps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 		/* Compute params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 		if (bus->compute_params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 			ret = bus->compute_params(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 				dev_err(bus->dev, "Compute params failed: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 					ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 		/* Program params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 		ret = sdw_program_params(bus, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 			dev_err(bus->dev, "Program params failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	stream->state = SDW_STREAM_DEPREPARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	return do_bank_switch(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)  * sdw_deprepare_stream() - Deprepare SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)  * @stream: Soundwire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)  * Documentation/driver-api/soundwire/stream.rst explains this API in detail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) int sdw_deprepare_stream(struct sdw_stream_runtime *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	if (!stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 		pr_err("SoundWire: Handle not found for stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	sdw_acquire_bus_lock(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 	if (stream->state != SDW_STREAM_PREPARED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	    stream->state != SDW_STREAM_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 		pr_err("%s: %s: inconsistent state state %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 		       __func__, stream->name, stream->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 		goto state_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	ret = _sdw_deprepare_stream(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) state_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	sdw_release_bus_lock(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) EXPORT_SYMBOL(sdw_deprepare_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) static int set_stream(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 		      struct sdw_stream_runtime *sdw_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	struct snd_soc_dai *dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	/* Set stream pointer on all DAIs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	for_each_rtd_dais(rtd, i, dai) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 		ret = snd_soc_dai_set_sdw_stream(dai, sdw_stream, substream->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 			dev_err(rtd->dev, "failed to set stream pointer on dai %s", dai->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)  * sdw_startup_stream() - Startup SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)  * @sdw_substream: Soundwire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)  * Documentation/driver-api/soundwire/stream.rst explains this API in detail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) int sdw_startup_stream(void *sdw_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	struct snd_pcm_substream *substream = sdw_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	struct sdw_stream_runtime *sdw_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 	char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 		name = kasprintf(GFP_KERNEL, "%s-Playback", substream->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 		name = kasprintf(GFP_KERNEL, "%s-Capture", substream->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	sdw_stream = sdw_alloc_stream(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	if (!sdw_stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 		dev_err(rtd->dev, "alloc stream failed for substream DAI %s", substream->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	ret = set_stream(substream, sdw_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 		goto release_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) release_stream:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	sdw_release_stream(sdw_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	set_stream(substream, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) EXPORT_SYMBOL(sdw_startup_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)  * sdw_shutdown_stream() - Shutdown SoundWire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)  * @sdw_substream: Soundwire stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)  * Documentation/driver-api/soundwire/stream.rst explains this API in detail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) void sdw_shutdown_stream(void *sdw_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	struct snd_pcm_substream *substream = sdw_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	struct sdw_stream_runtime *sdw_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	struct snd_soc_dai *dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 	/* Find stream from first CPU DAI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	if (IS_ERR(sdw_stream)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 		dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	/* release memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	kfree(sdw_stream->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	sdw_release_stream(sdw_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	/* clear DAI data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	set_stream(substream, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) EXPORT_SYMBOL(sdw_shutdown_stream);