#define MAX_FREQ_NUM 1
#define TIMEOUT_MS 100
#define QCOM_SWRM_MAX_RD_LEN 0x1
-#define QCOM_SDW_MAX_PORTS 14
#define DEFAULT_CLK_FREQ 9600000
#define SWRM_MAX_DAIS 0xF
#define SWR_INVALID_PARAM 0xFF
int wake_irq;
int num_din_ports;
int num_dout_ports;
+ int nports;
int cols_index;
int rows_index;
unsigned long port_mask;
u8 rcmd_id;
u8 wcmd_id;
/* Port numbers are 1 - 14 */
- struct qcom_swrm_port_config pconfig[QCOM_SDW_MAX_PORTS + 1];
+ struct qcom_swrm_port_config *pconfig;
struct sdw_stream_runtime *sruntime[SWRM_MAX_DAIS];
enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
int (*reg_read)(struct qcom_swrm_ctrl *ctrl, int reg, u32 *val);
struct snd_pcm_hw_params *params,
int direction)
{
- struct sdw_port_config pconfig[QCOM_SDW_MAX_PORTS];
struct sdw_stream_config sconfig;
struct sdw_master_runtime *m_rt;
struct sdw_slave_runtime *s_rt;
unsigned long *port_mask;
int maxport, pn, nports = 0, ret = 0;
unsigned int m_port;
+ struct sdw_port_config *pconfig __free(kfree) = kcalloc(ctrl->nports,
+ sizeof(*pconfig), GFP_KERNEL);
+ if (!pconfig)
+ return -ENOMEM;
if (direction == SNDRV_PCM_STREAM_CAPTURE)
sconfig.direction = SDW_DATA_DIR_TX;
continue;
port_mask = &ctrl->port_mask;
- maxport = ctrl->num_dout_ports + ctrl->num_din_ports;
-
+ maxport = ctrl->nports;
list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
slave = s_rt->slave;
static int qcom_swrm_get_port_config(struct qcom_swrm_ctrl *ctrl)
{
struct device_node *np = ctrl->dev->of_node;
- u8 off1[QCOM_SDW_MAX_PORTS];
- u8 off2[QCOM_SDW_MAX_PORTS];
- u16 si[QCOM_SDW_MAX_PORTS];
- u8 bp_mode[QCOM_SDW_MAX_PORTS] = { 0, };
- u8 hstart[QCOM_SDW_MAX_PORTS];
- u8 hstop[QCOM_SDW_MAX_PORTS];
- u8 word_length[QCOM_SDW_MAX_PORTS];
- u8 blk_group_count[QCOM_SDW_MAX_PORTS];
- u8 lane_control[QCOM_SDW_MAX_PORTS];
- int i, ret, nports, val;
- bool si_16 = false;
+ struct qcom_swrm_port_config *pcfg;
+ int i, ret, val;
ctrl->reg_read(ctrl, SWRM_COMP_PARAMS, &val);
ctrl->num_din_ports = FIELD_GET(SWRM_COMP_PARAMS_DIN_PORTS_MASK, val);
ret = of_property_read_u32(np, "qcom,din-ports", &val);
- if (ret)
- return ret;
-
- if (val > ctrl->num_din_ports)
- return -EINVAL;
+ if (!ret) { /* only if present */
+ if (val != ctrl->num_din_ports) {
+ dev_err(ctrl->dev, "din-ports (%d) mismatch with controller (%d)",
+ val, ctrl->num_din_ports);
+ }
- ctrl->num_din_ports = val;
+ ctrl->num_din_ports = val;
+ }
ret = of_property_read_u32(np, "qcom,dout-ports", &val);
- if (ret)
- return ret;
+ if (!ret) { /* only if present */
+ if (val != ctrl->num_dout_ports) {
+ dev_err(ctrl->dev, "dout-ports (%d) mismatch with controller (%d)",
+ val, ctrl->num_dout_ports);
+ }
- if (val > ctrl->num_dout_ports)
- return -EINVAL;
+ ctrl->num_dout_ports = val;
+ }
- ctrl->num_dout_ports = val;
+ ctrl->nports = ctrl->num_dout_ports + ctrl->num_din_ports;
- nports = ctrl->num_dout_ports + ctrl->num_din_ports;
- if (nports > QCOM_SDW_MAX_PORTS)
- return -EINVAL;
+ ctrl->pconfig = devm_kcalloc(ctrl->dev, ctrl->nports + 1,
+ sizeof(*ctrl->pconfig), GFP_KERNEL);
+ if (!ctrl->pconfig)
+ return -ENOMEM;
- /* Valid port numbers are from 1-14, so mask out port 0 explicitly */
set_bit(0, &ctrl->port_mask);
+ /* Valid port numbers are from 1, so mask out port 0 explicitly */
+ for (i = 0; i < ctrl->nports; i++) {
+ pcfg = &ctrl->pconfig[i + 1];
- ret = of_property_read_u8_array(np, "qcom,ports-offset1",
- off1, nports);
- if (ret)
- return ret;
-
- ret = of_property_read_u8_array(np, "qcom,ports-offset2",
- off2, nports);
- if (ret)
- return ret;
-
- ret = of_property_read_u8_array(np, "qcom,ports-sinterval-low",
- (u8 *)si, nports);
- if (ret) {
- ret = of_property_read_u16_array(np, "qcom,ports-sinterval",
- si, nports);
+ ret = of_property_read_u8_index(np, "qcom,ports-offset1", i, &pcfg->off1);
if (ret)
return ret;
- si_16 = true;
- }
- ret = of_property_read_u8_array(np, "qcom,ports-block-pack-mode",
- bp_mode, nports);
- if (ret) {
- if (ctrl->version <= SWRM_VERSION_1_3_0)
- memset(bp_mode, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS);
- else
+ ret = of_property_read_u8_index(np, "qcom,ports-offset2", i, &pcfg->off2);
+ if (ret)
return ret;
- }
- memset(hstart, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS);
- of_property_read_u8_array(np, "qcom,ports-hstart", hstart, nports);
+ ret = of_property_read_u8_index(np, "qcom,ports-sinterval-low", i, (u8 *)&pcfg->si);
+ if (ret) {
+ ret = of_property_read_u16_index(np, "qcom,ports-sinterval", i, &pcfg->si);
+ if (ret)
+ return ret;
+ }
+
+ ret = of_property_read_u8_index(np, "qcom,ports-block-pack-mode",
+ i, &pcfg->bp_mode);
+ if (ret) {
+ if (ctrl->version <= SWRM_VERSION_1_3_0)
+ pcfg->bp_mode = SWR_INVALID_PARAM;
+ else
+ return ret;
+ }
- memset(hstop, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS);
- of_property_read_u8_array(np, "qcom,ports-hstop", hstop, nports);
+ /* Optional properties */
+ pcfg->hstart = SWR_INVALID_PARAM;
+ pcfg->hstop = SWR_INVALID_PARAM;
+ pcfg->word_length = SWR_INVALID_PARAM;
+ pcfg->blk_group_count = SWR_INVALID_PARAM;
+ pcfg->lane_control = SWR_INVALID_PARAM;
- memset(word_length, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS);
- of_property_read_u8_array(np, "qcom,ports-word-length", word_length, nports);
+ of_property_read_u8_index(np, "qcom,ports-hstart", i, &pcfg->hstart);
- memset(blk_group_count, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS);
- of_property_read_u8_array(np, "qcom,ports-block-group-count", blk_group_count, nports);
+ of_property_read_u8_index(np, "qcom,ports-hstop", i, &pcfg->hstop);
- memset(lane_control, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS);
- of_property_read_u8_array(np, "qcom,ports-lane-control", lane_control, nports);
+ of_property_read_u8_index(np, "qcom,ports-word-length", i, &pcfg->word_length);
- for (i = 0; i < nports; i++) {
- /* Valid port number range is from 1-14 */
- if (si_16)
- ctrl->pconfig[i + 1].si = si[i];
- else
- ctrl->pconfig[i + 1].si = ((u8 *)si)[i];
- ctrl->pconfig[i + 1].off1 = off1[i];
- ctrl->pconfig[i + 1].off2 = off2[i];
- ctrl->pconfig[i + 1].bp_mode = bp_mode[i];
- ctrl->pconfig[i + 1].hstart = hstart[i];
- ctrl->pconfig[i + 1].hstop = hstop[i];
- ctrl->pconfig[i + 1].word_length = word_length[i];
- ctrl->pconfig[i + 1].blk_group_count = blk_group_count[i];
- ctrl->pconfig[i + 1].lane_control = lane_control[i];
+ of_property_read_u8_index(np, "qcom,ports-block-group-count",
+ i, &pcfg->blk_group_count);
+
+ of_property_read_u8_index(np, "qcom,ports-lane-control", i, &pcfg->lane_control);
}
return 0;