^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(¶ms, &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, ¶ms, 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);