diff --git a/asoc/codecs/swr-dmic.c b/asoc/codecs/swr-dmic.c index 479e64c8e5..d0fc036d2d 100644 --- a/asoc/codecs/swr-dmic.c +++ b/asoc/codecs/swr-dmic.c @@ -68,6 +68,8 @@ struct swr_dmic_priv { bool is_wcd_supply; int is_en_supply; u8 tx_master_port_map[SWR_DMIC_MAX_PORTS]; + struct swr_port_params tx_port_params[SWR_UC_MAX][SWR_DMIC_MAX_PORTS]; + struct swr_dev_frame_config swr_tx_port_params[SWR_UC_MAX]; struct notifier_block nblock; }; @@ -256,6 +258,74 @@ static int dmic_swr_ctrl(struct snd_soc_dapm_widget *w, return ret; } +/* qcom,swr-tx-port-params = , , *UC0* + , , *UC1* + , , *UC2* + , , *UC3 */ +static int swr_dmic_parse_port_params(struct device *dev, + char *prop) +{ + int i, j; + u32 *dt_array, map_size, max_uc; + int ret = 0; + u32 cnt = 0; + struct swr_port_params (*map)[SWR_UC_MAX][SWR_DMIC_MAX_PORTS]; + struct swr_dev_frame_config (*map_uc)[SWR_UC_MAX]; + struct swr_dmic_priv *swr_dmic = dev_get_drvdata(dev); + + map = &swr_dmic->tx_port_params; + map_uc = &swr_dmic->swr_tx_port_params; + + if (!of_find_property(dev->of_node, prop, + &map_size)) { + dev_err(dev, "missing port mapping prop %s\n", prop); + ret = -EINVAL; + goto err_port_map; + } + + max_uc = map_size / (SWR_DMIC_MAX_PORTS * SWR_PORT_PARAMS * sizeof(u32)); + + if (max_uc != SWR_UC_MAX) { + dev_err(dev, + "%s:port params not provided for all usecases\n", + __func__); + ret = -EINVAL; + goto err_port_map; + } + dt_array = kzalloc(map_size, GFP_KERNEL); + + if (!dt_array) { + ret = -ENOMEM; + goto err_alloc; + } + ret = of_property_read_u32_array(dev->of_node, prop, dt_array, + SWR_DMIC_MAX_PORTS * SWR_PORT_PARAMS * max_uc); + if (ret) { + dev_err(dev, "%s: Failed to read port mapping from prop %s\n", + __func__, prop); + goto err_pdata_fail; + } + + for (i = 0; i < max_uc; i++) { + for (j = 0; j < SWR_DMIC_MAX_PORTS; j++) { + cnt = (i * SWR_DMIC_MAX_PORTS + j) * SWR_PORT_PARAMS; + (*map)[i][j].offset1 = dt_array[cnt]; + (*map)[i][j].lane_ctrl = dt_array[cnt + 1]; + dev_err(dev, "%s: port %d, uc: %d, offset1:%d, lane: %d\n", + __func__, j, i, dt_array[cnt], dt_array[cnt + 1]); + } + (*map_uc)[i].pp = &(*map)[i][0]; + } + kfree(dt_array); + return 0; + +err_pdata_fail: + kfree(dt_array); +err_alloc: +err_port_map: + return ret; +} + static const char * const tx_master_port_text[] = { "ZERO", "SWRM_TX1_CH1", "SWRM_TX1_CH2", "SWRM_TX1_CH3", "SWRM_TX1_CH4", "SWRM_TX2_CH1", "SWRM_TX2_CH2", "SWRM_TX2_CH3", "SWRM_TX2_CH4", @@ -540,6 +610,7 @@ static int swr_dmic_probe(struct swr_device *pdev) pdev->dev.of_node->full_name); goto dev_err; } + swr_dmic_parse_port_params(&pdev->dev, "qcom,swr-tx-port-params"); /* * Add 5msec delay to provide sufficient time for @@ -568,6 +639,8 @@ static int swr_dmic_probe(struct swr_device *pdev) goto err; } pdev->dev_num = swr_devnum; + swr_init_port_params(pdev, SWR_DMIC_MAX_PORTS, + swr_dmic->swr_tx_port_params); swr_dmic->driver = devm_kzalloc(&pdev->dev, sizeof(struct snd_soc_component_driver), GFP_KERNEL); diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index 92a69770e8..47f783119c 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "wcd937x-mbhc.h" #include "wcd937x.h" @@ -18,6 +19,7 @@ #define MAX_PORT 8 #define MAX_CH_PER_PORT 8 #define MAX_TX_PWR_CH 2 +#define SWR_NUM_PORTS 4 #define WCD937X_MAX_SLAVE_PORT_TYPES 10 extern struct regmap_config wcd937x_regmap_config; @@ -72,6 +74,8 @@ struct wcd937x_priv { tx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; struct codec_port_info rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; + struct port_params tx_port_params[SWR_UC_MAX][SWR_NUM_PORTS]; + struct swr_dev_frame_config swr_tx_port_params[SWR_UC_MAX]; struct regulator_bulk_data *supplies; struct notifier_block nblock; /* wcd callback to bolero */ diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 22a452e2da..5e2b3169d4 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -229,6 +229,77 @@ found: return 0; } +/* qcom,swr-tx-port-params = , , , ,*UC0* + , , , , *UC1* + , , , ; *UC2* + , , , ; *UC3 */ +static int wcd937x_parse_port_params(struct device *dev, + char *prop, u8 path) +{ + u32 *dt_array, map_size, max_uc; + int ret = 0; + u32 offset1, lane_ctrl, cnt = 0; + struct port_params (*map)[SWR_UC_MAX][SWR_NUM_PORTS]; + struct swr_dev_frame_config (*map_uc)[SWR_UC_MAX]; + struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); + + switch (path) { + case CODEC_TX: + map = &wcd937x->tx_port_params; + map_uc = &wcd937x->swr_tx_port_params; + break; + default: + ret = -EINVAL; + goto err_port_map; + } + + if (!of_find_property(dev->of_node, prop, + &map_size)) { + dev_err(dev, "missing port mapping prop %s\n", prop); + ret = -EINVAL; + goto err_port_map; + } + + max_uc = map_size / (SWR_NUM_PORTS * SWR_PORT_PARAMS * sizeof(u32)); + + if (max_uc != SWR_UC_MAX) { + dev_err(dev, "%s: port params not provided for all usecases\n", + __func__); + ret = -EINVAL; + goto err_port_map; + } + dt_array = kzalloc(map_size, GFP_KERNEL); + + if (!dt_array) { + ret = -ENOMEM; + goto err_alloc; + } + ret = of_property_read_u32_array(dev->of_node, prop, dt_array, + SWR_NUM_PORTS * SWR_PORT_PARAMS * max_uc); + if (ret) { + dev_err(dev, "%s: Failed to read port mapping from prop %s\n", + __func__, prop); + goto err_pdata_fail; + } + + for (i = 0; i < max_uc; i++) { + for (j = 0; j < SWR_NUM_PORTS; j++) { + cnt = (i * SWR_NUM_PORTS + j) * SWR_PORT_PARAMS; + (*map)[i][j].offset1 = dt_array[cnt]; + (*map)[i][j].lane_ctrl = dt_array[cnt + 1]; + } + (*map_uc)[i] = &(*map)[i][0]; + } + kfree(dt_array); + return 0; + +err_pdata_fail: + kfree(dt_array); +err_alloc: +err_port_map: + return ret; +} + static int wcd937x_parse_port_mapping(struct device *dev, char *prop, u8 path) { @@ -3186,6 +3257,13 @@ static int wcd937x_bind(struct device *dev) dev_err(dev, "Failed to read port mapping\n"); goto err; } + ret = wcd937x_parse_port_params(dev, "qcom,swr-tx-port-params", + CODEC_TX); + if (ret) { + dev_err(dev, "Failed to read port params\n"); + goto err; + } + wcd937x->rx_swr_dev = get_matching_swr_slave_device(pdata->rx_slave); if (!wcd937x->rx_swr_dev) { @@ -3202,6 +3280,8 @@ static int wcd937x_bind(struct device *dev) ret = -ENODEV; goto err; } + swr_init_port_params(wcd937x->tx_swr_dev, SWR_NUM_PORTS, + wcd937x->swr_tx_port_params); wcd937x->regmap = devm_regmap_init_swr(wcd937x->tx_swr_dev, &wcd937x_regmap_config); diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index 7da5b36875..09e32a783b 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "wcd938x-mbhc.h" #include "wcd938x.h" @@ -21,6 +22,7 @@ #define MAX_PORT 8 #define MAX_CH_PER_PORT 8 #define TX_ADC_MAX 4 +#define SWR_NUM_PORTS 4 enum { TX_HDR12 = 0, @@ -88,6 +90,8 @@ struct wcd938x_priv { tx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; struct codec_port_info rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; + struct port_params tx_port_params[SWR_UC_MAX][SWR_NUM_PORTS]; + struct swr_dev_frame_config swr_tx_port_params[SWR_UC_MAX]; struct regulator_bulk_data *supplies; struct notifier_block nblock; /* wcd callback to bolero */ diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index d5bd6ae3da..cd7d71c92f 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -342,6 +342,78 @@ found: return 0; } + +/* qcom,swr-tx-port-params = , , , ,*UC0* + , , , , *UC1* + , , , ; *UC2* + , , , ; *UC3 */ +static int wcd938x_parse_port_params(struct device *dev, + char *prop, u8 path) +{ + u32 *dt_array, map_size, max_uc; + int ret = 0; + u32 offset1, lane_ctrl, cnt = 0; + struct port_params (*map)[SWR_UC_MAX][SWR_NUM_PORTS]; + struct swr_dev_frame_config (*map_uc)[SWR_UC_MAX]; + struct wcd938x_priv *wcd938x = dev_get_drvdata(dev); + + switch (path) { + case CODEC_TX: + map = &wcd938x->tx_port_params; + map_uc = &wcd938x->swr_tx_port_params; + break; + default: + ret = -EINVAL; + goto err_port_map; + } + + if (!of_find_property(dev->of_node, prop, + &map_size)) { + dev_err(dev, "missing port mapping prop %s\n", prop); + ret = -EINVAL; + goto err_port_map; + } + + max_uc = map_size / (SWR_NUM_PORTS * SWR_PORT_PARAMS * sizeof(u32)); + + if (max_uc != SWR_UC_MAX) { + dev_err(dev, "%s: port params not provided for all usecases\n", + __func__); + ret = -EINVAL; + goto err_port_map; + } + dt_array = kzalloc(map_size, GFP_KERNEL); + + if (!dt_array) { + ret = -ENOMEM; + goto err_alloc; + } + ret = of_property_read_u32_array(dev->of_node, prop, dt_array, + SWR_NUM_PORTS * SWR_PORT_PARAMS * max_uc); + if (ret) { + dev_err(dev, "%s: Failed to read port mapping from prop %s\n", + __func__, prop); + goto err_pdata_fail; + } + + for (i = 0; i < max_uc; i++) { + for (j = 0; j < SWR_NUM_PORTS; j++) { + cnt = (i * SWR_NUM_PORTS + j) * SWR_PORT_PARAMS; + (*map)[i][j].offset1 = dt_array[cnt]; + (*map)[i][j].lane_ctrl = dt_array[cnt + 1]; + } + (*map_uc)[i] = &(*map)[i][0]; + } + kfree(dt_array); + return 0; + +err_pdata_fail: + kfree(dt_array); +err_alloc: +err_port_map: + return ret; +} + static int wcd938x_parse_port_mapping(struct device *dev, char *prop, u8 path) { @@ -4277,6 +4349,8 @@ static int wcd938x_bind(struct device *dev) ret = -ENODEV; goto err; } + swr_init_port_params(wcd938x->tx_swr_dev, SWR_NUM_PORTS, + wcd938x->swr_tx_port_params); wcd938x->regmap = devm_regmap_init_swr(wcd938x->tx_swr_dev, &wcd938x_regmap_config); @@ -4479,6 +4553,12 @@ static int wcd938x_probe(struct platform_device *pdev) dev_err(dev, "Failed to read port mapping\n"); goto err; } + ret = wcd938x_parse_port_params(dev, "qcom,swr-tx-port-params", + CODEC_TX); + if (ret) { + dev_err(dev, "Failed to read port params\n"); + goto err; + } mutex_init(&wcd938x->wakeup_lock); mutex_init(&wcd938x->micb_lock); diff --git a/asoc/lahaina-port-config.h b/asoc/lahaina-port-config.h index 653ff24ca9..4ce2f25a8b 100755 --- a/asoc/lahaina-port-config.h +++ b/asoc/lahaina-port-config.h @@ -7,6 +7,7 @@ #define _LAHAINA_PORT_CONFIG #include +#include #define WSA_MSTR_PORT_MASK 0xFF /* diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index a8c5ec83e9..bde88ddcee 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -11,6 +11,14 @@ #include #include "audio_mod_devicetable.h" +enum { + SWR_UC0 = 0, + SWR_UC1, + SWR_UC2, + SWR_UC3, + SWR_UC_MAX, +}; + #define SWR_CLK_RATE_0P3MHZ 300000 #define SWR_CLK_RATE_0P6MHZ 600000 #define SWR_CLK_RATE_1P2MHZ 1200000 @@ -32,6 +40,8 @@ struct swr_device; * configurations of all devices */ #define SWR_MAX_MSTR_PORT_NUM (SWR_MAX_DEV_NUM * SWR_MAX_DEV_PORT_NUM) +/* SWR slave port params count */ +#define SWR_PORT_PARAMS 2 /* Regmap support for soundwire interface */ struct regmap *__devm_regmap_init_swr(struct swr_device *dev, @@ -121,6 +131,16 @@ struct swr_port_info { u32 ch_rate; }; +struct swr_port_params { + u32 offset1; + u32 lane_ctrl; +}; + +struct swr_dev_frame_config { + struct swr_port_params *pp; +}; + + /* * struct swr_params - represent transfer of data from soundwire slave * to soundwire master @@ -208,6 +228,8 @@ struct swr_master { const void *buf, size_t len); int (*get_logical_dev_num)(struct swr_master *mstr, u64 dev_id, u8 *dev_num); + int (*init_port_params)(struct swr_master *mstr, u32 dev_num, + u32 num_ports, struct swr_dev_frame_config *uc_arr); int (*slvdev_datapath_control)(struct swr_master *mstr, bool enable); bool (*remove_from_group)(struct swr_master *mstr); void (*device_wakeup_vote)(struct swr_master *mstr); @@ -332,6 +354,9 @@ extern void swr_port_response(struct swr_master *mstr, u8 tid); extern int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id, u8 *dev_num); +extern int swr_init_port_params(struct swr_device *dev, + u32 num_ports, struct swr_dev_frame_config *pp); + extern int swr_read(struct swr_device *dev, u8 dev_num, u16 reg_addr, void *buf, u32 len); diff --git a/include/soc/swr-common.h b/include/soc/swr-common.h index e55fb81f96..56723979e9 100755 --- a/include/soc/swr-common.h +++ b/include/soc/swr-common.h @@ -10,13 +10,6 @@ #include #include -enum { - SWR_UC0 = 0, - SWR_UC1, - SWR_UC2, - SWR_UC_MAX, -}; - struct port_params { u16 si; u8 off1; diff --git a/soc/soundwire.c b/soc/soundwire.c index 60fe3f732c..0e62400a3a 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -476,6 +476,32 @@ int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id, } EXPORT_SYMBOL(swr_get_logical_dev_num); +/** + * swr_init_port_params - soundwire slave port params set + * @dev: pointer to soundwire slave device + * @num_ports: number of slave ports + * @pp: port params for all ports for all usecases + * + * This API will set soundwire port params from slave + */ +int swr_init_port_params(struct swr_device *dev, + u32 num_ports, struct swr_dev_frame_config *pp) +{ + int ret = 0; + struct swr_master *master = dev->master; + + if (!master) { + pr_err("%s: Master is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&master->mlock); + ret = master->init_port_params(master, dev->dev_num, + num_ports, pp); + mutex_unlock(&master->mlock); + return ret; +} +EXPORT_SYMBOL(swr_init_port_params); + /** * swr_device_wakeup_vote - Wakeup master and slave devices from clock stop * @dev: pointer to soundwire slave device diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 54d9418947..436c2ec880 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -26,7 +26,6 @@ #include "swr-slave-registers.h" #include #include "swr-mstr-ctrl.h" -#include "swr-slave-port-config.h" #define SWR_NUM_PORTS 4 /* TODO - Get this info from DT */ @@ -131,32 +130,6 @@ static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr); static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val); static int swrm_runtime_resume(struct device *dev); -static u64 swrm_phy_dev[] = { - 0, - 0xd01170223, - 0x858350223, - 0x858350222, - 0x858350221, - 0x858350220, -}; - -static u8 swrm_get_device_id(struct swr_mstr_ctrl *swrm, u8 devnum) -{ - int i; - - for (i = 1; i < (swrm->num_dev + 1); i++) { - if (swrm->logical_dev[devnum] == swrm_phy_dev[i]) - break; - } - - if (i == (swrm->num_dev + 1)) { - pr_info("%s: could not find the slave\n", __func__); - i = devnum; - } - - return i; -} - static u8 swrm_get_clk_div(int mclk_freq, int bus_clk_freq) { int clk_div = 0; @@ -1361,37 +1334,44 @@ static u8 swrm_get_controller_offset1(struct swr_mstr_ctrl *swrm, return offset1; } +static int swrm_get_uc(int bus_clk) +{ + switch (bus_clk) { + case SWR_CLK_RATE_4P8MHZ: + return SWR_UC1; + case SWR_CLK_RATE_1P2MHZ: + return SWR_UC2; + case SWR_CLK_RATE_0P6MHZ: + return SWR_UC3; + case SWR_CLK_RATE_9P6MHZ: + default: + return SWR_UC0; + } + return SWR_UC0; +} + static void swrm_get_device_frame_shape(struct swr_mstr_ctrl *swrm, struct swrm_mports *mport, struct swr_port_info *port_req) { - u32 port_id = 0; - u8 dev_num = 0; - struct port_params *pp_dev; - struct port_params *pp_port; + u32 uc = SWR_UC0; + u32 port_id_offset = 0; - if ((swrm->master_id == MASTER_ID_TX) && - ((swrm->bus_clk == SWR_CLK_RATE_9P6MHZ) || - (swrm->bus_clk == SWR_CLK_RATE_0P6MHZ) || - (swrm->bus_clk == SWR_CLK_RATE_4P8MHZ))) { - dev_num = swrm_get_device_id(swrm, port_req->dev_num); - port_id = port_req->slave_port_id; - if (swrm->bus_clk == SWR_CLK_RATE_9P6MHZ) - pp_dev = swrdev_frame_params_9p6MHz[dev_num].pp; - else if (swrm->bus_clk == SWR_CLK_RATE_0P6MHZ) - pp_dev = swrdev_frame_params_0p6MHz[dev_num].pp; - else - pp_dev = swrdev_frame_params_4p8MHz[dev_num].pp; - pp_port = &pp_dev[port_id]; - port_req->sinterval = pp_port->si; - port_req->offset1 = pp_port->off1; - port_req->offset2 = pp_port->off2; - port_req->hstart = pp_port->hstart; - port_req->hstop = pp_port->hstop; - port_req->word_length = pp_port->wd_len; - port_req->blk_pack_mode = pp_port->bp_mode; - port_req->blk_grp_count = pp_port->bgp_ctrl; - port_req->lane_ctrl = pp_port->lane_ctrl; + if (swrm->master_id == MASTER_ID_TX) { + uc = swrm_get_uc(swrm->bus_clk); + port_id_offset = (port_req->dev_num - 1) * + SWR_MAX_DEV_PORT_NUM + + port_req->slave_port_id; + port_req->sinterval = + ((swrm->bus_clk * 2) / port_req->ch_rate) - 1; + port_req->offset1 = swrm->pp[uc][port_id_offset].offset1; + port_req->offset2 = 0x00; + port_req->hstart = 0xFF; + port_req->hstop = 0xFF; + port_req->word_length = 0xFF; + port_req->blk_pack_mode = 0xFF; + port_req->blk_grp_count = 0xFF; + port_req->lane_ctrl = swrm->pp[uc][port_id_offset].lane_ctrl; } else { /* copy master port config to slave */ port_req->sinterval = mport->sinterval; @@ -2398,7 +2378,6 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, "%s: devnum %d assigned for dev %llx\n", __func__, i, swr_dev->addr); - swrm->logical_dev[i] = swr_dev->addr; } } } @@ -2414,6 +2393,27 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, return ret; } +static int swrm_init_port_params(struct swr_master *mstr, u32 dev_num, + u32 num_ports, + struct swr_dev_frame_config *uc_arr) +{ + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr); + int i, j, port_id_offset; + + if (!swrm) { + pr_err("%s: Invalid handle to swr controller\n", __func__); + return 0; + } + for (i = 0; i < SWR_UC_MAX; i++) { + for (j = 0; j < num_ports; j++) { + port_id_offset = (dev_num - 1) * SWR_MAX_DEV_PORT_NUM + j; + swrm->pp[i][port_id_offset].offset1 = uc_arr[i].pp[j].offset1; + swrm->pp[i][port_id_offset].lane_ctrl = uc_arr[i].pp[j].lane_ctrl; + } + } + return 0; +} + static void swrm_device_wakeup_vote(struct swr_master *mstr) { struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr); @@ -2613,7 +2613,6 @@ static int swrm_probe(struct platform_device *pdev) int ret = 0; struct clk *lpass_core_hw_vote = NULL; struct clk *lpass_core_audio = NULL; - u32 is_wcd937x = 0; /* Allocate soundwire master driver structure */ swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl), @@ -2654,13 +2653,6 @@ static int swrm_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s: failed to get master id\n", __func__); goto err_pdata_fail; } - /* update the physical device address if wcd937x. */ - ret = of_property_read_u32(pdev->dev.of_node, "qcom,is_wcd937x", - &is_wcd937x); - if (ret) - dev_dbg(&pdev->dev, "%s: failed to get wcd info\n", __func__); - else if (is_wcd937x) - swrm_phy_dev[1] = 0xa01170223; ret = of_property_read_u32(pdev->dev.of_node, "qcom,dynamic-port-map-supported", &swrm->dynamic_port_map_supported); @@ -2779,6 +2771,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->master.write = swrm_write; swrm->master.bulk_write = swrm_bulk_write; swrm->master.get_logical_dev_num = swrm_get_logical_dev_num; + swrm->master.init_port_params = swrm_init_port_params; swrm->master.connect_port = swrm_connect_port; swrm->master.disconnect_port = swrm_disconnect_port; swrm->master.slvdev_datapath_control = swrm_slvdev_datapath_control; diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 874b97a589..5928fe9f30 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -44,7 +44,7 @@ #define SWR_MAX_CH_PER_PORT 8 -#define SWRM_NUM_AUTO_ENUM_SLAVES 6 +#define SWRM_NUM_AUTO_ENUM_SLAVES 11 enum { SWR_MSTR_PAUSE, @@ -196,8 +196,8 @@ struct swr_mstr_ctrl { u32 wr_fifo_depth; u32 num_auto_enum; bool enable_slave_irq; - u64 logical_dev[SWRM_NUM_AUTO_ENUM_SLAVES]; u32 is_always_on; + struct swr_port_params pp[SWR_UC_MAX][SWR_MAX_MSTR_PORT_NUM];/*max_devNum * max_ports 11 * 14 */ #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_swrm_dent; struct dentry *debugfs_peek; diff --git a/soc/swr-slave-port-config.h b/soc/swr-slave-port-config.h deleted file mode 100644 index 87cb8b9605..0000000000 --- a/soc/swr-slave-port-config.h +++ /dev/null @@ -1,167 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. - */ - -#ifndef _SWR_SLAVE_PORT_CONFIG -#define _SWR_SLAVE_PORT_CONFIG - -#include - -#define WSA_MSTR_PORT_MASK 0xFF -/* - * Add port configuration in the format - *{ si, off1, off2, hstart, hstop, wd_len, bp_mode, bgp_ctrl, lane_ctrl, dir, - * stream_type} - */ - -/* DUMMY */ -static struct port_params tx_dummy[SWR_MSTR_PORT_LEN] = { - {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ - {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */ -}; - -/* AMIC 9.6 MHz clock */ -#ifdef CONFIG_SND_SOC_HOLI -static struct port_params tx_wcd_9p6MHz[SWR_MSTR_PORT_LEN] = { - {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */ - {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ - {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */ - {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX4 */ -}; -#else -static struct port_params tx_wcd_9p6MHz[SWR_MSTR_PORT_LEN] = { - {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */ - {7, 5, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ - {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */ - {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX4 */ -}; -#endif - -/* AMIC 4.8 MHz clock */ -static struct port_params tx_wcd_4p8MHz[SWR_MSTR_PORT_LEN] = { - {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */ - {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ - {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */ - {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX4 */ -}; - -/* AMIC 0.6 MHz clock, single channel */ -static struct port_params tx_wcd_0p6MHz[SWR_MSTR_PORT_LEN] = { - {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ - {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */ - {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX4 */ -}; -/* 4 Channel configuration */ -/* SWR DMIC0 */ -static struct port_params tx_bottom_mic_9p6MHz[SWR_MSTR_PORT_LEN] = { - {7, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {7, 6, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -/* SWR DMIC1 */ -static struct port_params tx_receiver_mic_9p6MHz[SWR_MSTR_PORT_LEN] = { - {7, 4, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {7, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -/* SWR DMIC2 */ -static struct port_params tx_back_mic_9p6MHz[SWR_MSTR_PORT_LEN] = { - {7, 3, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -/* SWR DMIC3 */ -static struct port_params tx_top_mic_9p6MHz[SWR_MSTR_PORT_LEN] = { - {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {7, 5, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -/* The 4.8MHZ port config is used in - * 1. single mic standalone in "high power" mode - * 2. dual mic standalone in "high power" mode - * 3. sva standalone single/dual/tri/quad in "low-power" mode - * 4. sva single/dmic in "low-power" + single mic in "high power" concurrency - */ -/* SWR DMIC0 */ -static struct port_params tx_bottom_mic_4p8MHz[SWR_MSTR_PORT_LEN] = { - {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {15, 4, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -/* SWR DMIC1 */ -static struct port_params tx_receiver_mic_4p8MHz[SWR_MSTR_PORT_LEN] = { - {3, 3, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {7, 6, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -/* SWR DMIC2 */ -static struct port_params tx_back_mic_4p8MHz[SWR_MSTR_PORT_LEN] = { - {3, 3, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {7, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -/* SWR DMIC3 */ -static struct port_params tx_top_mic_4p8MHz[SWR_MSTR_PORT_LEN] = { - {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {15, 3, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -/* 1 Channel configuration */ -/* SWR DMIC0 */ -static struct port_params tx_bottom_mic_0p6MHz[SWR_MSTR_PORT_LEN] = { - {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -/* SWR DMIC1 */ -static struct port_params tx_receiver_mic_0p6MHz[SWR_MSTR_PORT_LEN] = { - {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -/* SWR DMIC2 */ -static struct port_params tx_back_mic_0p6MHz[SWR_MSTR_PORT_LEN] = { - {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -/* SWR DMIC3 */ -static struct port_params tx_top_mic_0p6MHz[SWR_MSTR_PORT_LEN] = { - {3, 3, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ - {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ -}; - -struct swr_dev_frame_config { - struct port_params *pp; -}; - -static struct swr_dev_frame_config swrdev_frame_params_9p6MHz[] = { - {tx_dummy}, - {tx_wcd_9p6MHz}, - {tx_top_mic_9p6MHz}, - {tx_back_mic_9p6MHz}, - {tx_receiver_mic_9p6MHz}, - {tx_bottom_mic_9p6MHz}, -}; - -static struct swr_dev_frame_config swrdev_frame_params_4p8MHz[] = { - {tx_dummy}, - {tx_wcd_4p8MHz}, - {tx_top_mic_4p8MHz}, - {tx_back_mic_4p8MHz}, - {tx_receiver_mic_4p8MHz}, - {tx_bottom_mic_4p8MHz}, -}; - -static struct swr_dev_frame_config swrdev_frame_params_0p6MHz[] = { - {tx_dummy}, - {tx_wcd_0p6MHz}, - {tx_top_mic_0p6MHz}, - {tx_back_mic_0p6MHz}, - {tx_receiver_mic_0p6MHz}, - {tx_bottom_mic_0p6MHz}, -}; -#endif /* _LAHAINA_PORT_CONFIG */