soundwire: stream: reuse existing code for BPT stream
DP0 (Data Port 0) is very similar to regular data ports, with minor tweaks we can reuse the same code. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Tested-by: shumingf@realtek.com Link: https://lore.kernel.org/r/20250227140615.8147-7-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
committed by
Vinod Koul
parent
00f57195f1
commit
b422b7237e
+73
-31
@@ -88,11 +88,14 @@ static int _sdw_program_slave_port_params(struct sdw_bus *bus,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Program DPN_BlockCtrl3 register */
|
||||
ret = sdw_write_no_pm(slave, addr2, t_params->blk_pkg_mode);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev, "DPN_BlockCtrl3 register write failed\n");
|
||||
return ret;
|
||||
/* DP0 does not implement BlockCtrl3 */
|
||||
if (t_params->port_num) {
|
||||
/* Program DPN_BlockCtrl3 register */
|
||||
ret = sdw_write_no_pm(slave, addr2, t_params->blk_pkg_mode);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev, "DPN_BlockCtrl3 register write failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -131,18 +134,28 @@ static int sdw_program_slave_port_params(struct sdw_bus *bus,
|
||||
struct sdw_port_params *p_params = &p_rt->port_params;
|
||||
struct sdw_slave_prop *slave_prop = &s_rt->slave->prop;
|
||||
u32 addr1, addr2, addr3, addr4, addr5, addr6;
|
||||
struct sdw_dpn_prop *dpn_prop;
|
||||
enum sdw_dpn_type port_type;
|
||||
bool read_only_wordlength;
|
||||
int ret;
|
||||
u8 wbuf;
|
||||
|
||||
if (s_rt->slave->is_mockup_device)
|
||||
return 0;
|
||||
|
||||
dpn_prop = sdw_get_slave_dpn_prop(s_rt->slave,
|
||||
s_rt->direction,
|
||||
t_params->port_num);
|
||||
if (!dpn_prop)
|
||||
return -EINVAL;
|
||||
if (t_params->port_num) {
|
||||
struct sdw_dpn_prop *dpn_prop;
|
||||
|
||||
dpn_prop = sdw_get_slave_dpn_prop(s_rt->slave, s_rt->direction,
|
||||
t_params->port_num);
|
||||
if (!dpn_prop)
|
||||
return -EINVAL;
|
||||
|
||||
read_only_wordlength = dpn_prop->read_only_wordlength;
|
||||
port_type = dpn_prop->type;
|
||||
} else {
|
||||
read_only_wordlength = false;
|
||||
port_type = SDW_DPN_FULL;
|
||||
}
|
||||
|
||||
addr1 = SDW_DPN_PORTCTRL(t_params->port_num);
|
||||
addr2 = SDW_DPN_BLOCKCTRL1(t_params->port_num);
|
||||
@@ -172,7 +185,7 @@ static int sdw_program_slave_port_params(struct sdw_bus *bus,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!dpn_prop->read_only_wordlength) {
|
||||
if (!read_only_wordlength) {
|
||||
/* Program DPN_BlockCtrl1 register */
|
||||
ret = sdw_write_no_pm(s_rt->slave, addr2, (p_params->bps - 1));
|
||||
if (ret < 0) {
|
||||
@@ -224,9 +237,9 @@ static int sdw_program_slave_port_params(struct sdw_bus *bus,
|
||||
}
|
||||
}
|
||||
|
||||
if (dpn_prop->type != SDW_DPN_SIMPLE) {
|
||||
if (port_type != SDW_DPN_SIMPLE) {
|
||||
ret = _sdw_program_slave_port_params(bus, s_rt->slave,
|
||||
t_params, dpn_prop->type);
|
||||
t_params, port_type);
|
||||
if (ret < 0)
|
||||
dev_err(&s_rt->slave->dev,
|
||||
"Transport reg write failed for port: %d\n",
|
||||
@@ -433,6 +446,9 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
|
||||
struct completion *port_ready;
|
||||
struct sdw_dpn_prop *dpn_prop;
|
||||
struct sdw_prepare_ch prep_ch;
|
||||
u32 imp_def_interrupts;
|
||||
bool simple_ch_prep_sm;
|
||||
u32 ch_prep_timeout;
|
||||
bool intr = false;
|
||||
int ret = 0, val;
|
||||
u32 addr;
|
||||
@@ -440,20 +456,35 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
|
||||
prep_ch.num = p_rt->num;
|
||||
prep_ch.ch_mask = p_rt->ch_mask;
|
||||
|
||||
dpn_prop = sdw_get_slave_dpn_prop(s_rt->slave,
|
||||
s_rt->direction,
|
||||
prep_ch.num);
|
||||
if (!dpn_prop) {
|
||||
dev_err(bus->dev,
|
||||
"Slave Port:%d properties not found\n", prep_ch.num);
|
||||
return -EINVAL;
|
||||
if (p_rt->num) {
|
||||
dpn_prop = sdw_get_slave_dpn_prop(s_rt->slave, s_rt->direction, prep_ch.num);
|
||||
if (!dpn_prop) {
|
||||
dev_err(bus->dev,
|
||||
"Slave Port:%d properties not found\n", prep_ch.num);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
imp_def_interrupts = dpn_prop->imp_def_interrupts;
|
||||
simple_ch_prep_sm = dpn_prop->simple_ch_prep_sm;
|
||||
ch_prep_timeout = dpn_prop->ch_prep_timeout;
|
||||
} else {
|
||||
struct sdw_dp0_prop *dp0_prop = s_rt->slave->prop.dp0_prop;
|
||||
|
||||
if (!dp0_prop) {
|
||||
dev_err(bus->dev,
|
||||
"Slave DP0 properties not found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
imp_def_interrupts = dp0_prop->imp_def_interrupts;
|
||||
simple_ch_prep_sm = dp0_prop->simple_ch_prep_sm;
|
||||
ch_prep_timeout = dp0_prop->ch_prep_timeout;
|
||||
}
|
||||
|
||||
prep_ch.prepare = prep;
|
||||
|
||||
prep_ch.bank = bus->params.next_bank;
|
||||
|
||||
if (dpn_prop->imp_def_interrupts || !dpn_prop->simple_ch_prep_sm ||
|
||||
if (imp_def_interrupts || !simple_ch_prep_sm ||
|
||||
bus->params.s_data_mode != SDW_PORT_DATA_MODE_NORMAL)
|
||||
intr = true;
|
||||
|
||||
@@ -464,7 +495,7 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
|
||||
*/
|
||||
if (prep && intr) {
|
||||
ret = sdw_configure_dpn_intr(s_rt->slave, p_rt->num, prep,
|
||||
dpn_prop->imp_def_interrupts);
|
||||
imp_def_interrupts);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -473,7 +504,7 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
|
||||
sdw_do_port_prep(s_rt, prep_ch, prep ? SDW_OPS_PORT_PRE_PREP : SDW_OPS_PORT_PRE_DEPREP);
|
||||
|
||||
/* Prepare Slave port implementing CP_SM */
|
||||
if (!dpn_prop->simple_ch_prep_sm) {
|
||||
if (!simple_ch_prep_sm) {
|
||||
addr = SDW_DPN_PREPARECTRL(p_rt->num);
|
||||
|
||||
if (prep)
|
||||
@@ -490,7 +521,7 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
|
||||
/* Wait for completion on port ready */
|
||||
port_ready = &s_rt->slave->port_ready[prep_ch.num];
|
||||
wait_for_completion_timeout(port_ready,
|
||||
msecs_to_jiffies(dpn_prop->ch_prep_timeout));
|
||||
msecs_to_jiffies(ch_prep_timeout));
|
||||
|
||||
val = sdw_read_no_pm(s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num));
|
||||
if ((val < 0) || (val & p_rt->ch_mask)) {
|
||||
@@ -507,7 +538,7 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
|
||||
/* Disable interrupt after Port de-prepare */
|
||||
if (!prep && intr)
|
||||
ret = sdw_configure_dpn_intr(s_rt->slave, p_rt->num, prep,
|
||||
dpn_prop->imp_def_interrupts);
|
||||
imp_def_interrupts);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1008,7 +1039,8 @@ static int sdw_slave_port_is_valid_range(struct device *dev, int num)
|
||||
|
||||
static int sdw_slave_port_config(struct sdw_slave *slave,
|
||||
struct sdw_slave_runtime *s_rt,
|
||||
const struct sdw_port_config *port_config)
|
||||
const struct sdw_port_config *port_config,
|
||||
bool is_bpt_stream)
|
||||
{
|
||||
struct sdw_port_runtime *p_rt;
|
||||
int ret;
|
||||
@@ -1020,9 +1052,13 @@ static int sdw_slave_port_config(struct sdw_slave *slave,
|
||||
* TODO: Check valid port range as defined by DisCo/
|
||||
* slave
|
||||
*/
|
||||
ret = sdw_slave_port_is_valid_range(&slave->dev, port_config[i].num);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!is_bpt_stream) {
|
||||
ret = sdw_slave_port_is_valid_range(&slave->dev, port_config[i].num);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else if (port_config[i].num) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = sdw_port_config(p_rt, port_config, i);
|
||||
if (ret < 0)
|
||||
@@ -1331,6 +1367,11 @@ struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave,
|
||||
u8 num_ports;
|
||||
int i;
|
||||
|
||||
if (!port_num) {
|
||||
dev_err(&slave->dev, "%s: port_num is zero\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (direction == SDW_DATA_DIR_TX) {
|
||||
num_ports = hweight32(slave->prop.source_ports);
|
||||
dpn_prop = slave->prop.src_dpn_prop;
|
||||
@@ -2116,7 +2157,8 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
ret = sdw_slave_port_config(slave, s_rt, port_config);
|
||||
ret = sdw_slave_port_config(slave, s_rt, port_config,
|
||||
stream->type == SDW_STREAM_BPT);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user