[PATCH v2 00/12] ASoC: codecs: qcom add support for SM8450 and SC8280XP
This patchset adds support for SM8450 and SC8280XP SoC and also some of the fixes requried to get stable audio on X13s.
Tested SmartSpeakers and Headset on SM8450 MTP and Lenovo Thinkpad X13s.
Changes since v1: - moved va-macro from using of_device_is_compatible to compatible data - added some fixes for qcom codecs.
Srinivas Kandagatla (12): ASoC: codecs: wsa-macro: handle swr_reset correctly ASoC: codecs: rx-macro: handle swr_reset correctly ASoC: codecs: tx-macro: handle swr_reset correctly ASoC: codecs: tx-macro: fix active_decimator array ASoC: codecs: tx-macro: fix kcontrol put ASoC: codecs: wsa883x: add clock stop support ASoC: qcom: dt-bindings: add sm8450 and sc8280xp compatibles ASoC: codecs: wsa-macro: add support for sm8450 and sc8280xp ASoC: codecs: tx-macro: add support for sm8450 and sc8280xp ASoC: codecs: rx-macro: add support for sm8450 and sc8280xp ASoC: codecs: va-macro: clear the frame sync counter before enabling ASoC: codecs: va-macro: add support for sm8450 and sc8280xp
.../bindings/sound/qcom,lpass-rx-macro.yaml | 2 + .../bindings/sound/qcom,lpass-tx-macro.yaml | 2 + .../bindings/sound/qcom,lpass-va-macro.yaml | 2 + .../bindings/sound/qcom,lpass-wsa-macro.yaml | 2 + sound/soc/codecs/lpass-rx-macro.c | 18 ++-- sound/soc/codecs/lpass-tx-macro.c | 36 ++++---- sound/soc/codecs/lpass-va-macro.c | 82 +++++++++++++++++-- sound/soc/codecs/lpass-wsa-macro.c | 19 ++--- sound/soc/codecs/wsa883x.c | 28 +------ 9 files changed, 120 insertions(+), 71 deletions(-)
Reset soundwire block on frame sync generation clock reset. Without this we are hitting read/write timeouts randomly during runtime pm.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/lpass-wsa-macro.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-)
diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index 27da6c6c3c5a..130d25b334ff 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -338,7 +338,6 @@ struct wsa_macro { int ec_hq[WSA_MACRO_RX1 + 1]; u16 prim_int_users[WSA_MACRO_RX1 + 1]; u16 wsa_mclk_users; - bool reset_swr; unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS]; int rx_port_value[WSA_MACRO_RX_MAX]; @@ -2271,23 +2270,16 @@ static int wsa_swrm_clock(struct wsa_macro *wsa, bool enable) wsa_macro_mclk_enable(wsa, true);
/* reset swr ip */ - if (wsa->reset_swr) - regmap_update_bits(regmap, - CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, - CDC_WSA_SWR_RST_EN_MASK, - CDC_WSA_SWR_RST_ENABLE); + regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, + CDC_WSA_SWR_RST_EN_MASK, CDC_WSA_SWR_RST_ENABLE);
regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, CDC_WSA_SWR_CLK_EN_MASK, CDC_WSA_SWR_CLK_ENABLE);
/* Bring out of reset */ - if (wsa->reset_swr) - regmap_update_bits(regmap, - CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, - CDC_WSA_SWR_RST_EN_MASK, - CDC_WSA_SWR_RST_DISABLE); - wsa->reset_swr = false; + regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, + CDC_WSA_SWR_RST_EN_MASK, CDC_WSA_SWR_RST_DISABLE); } else { regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, CDC_WSA_SWR_CLK_EN_MASK, 0); @@ -2431,7 +2423,6 @@ static int wsa_macro_probe(struct platform_device *pdev)
dev_set_drvdata(dev, wsa);
- wsa->reset_swr = true; wsa->dev = dev;
/* set MCLK and NPL rates */
Reset soundwire block on frame sync generation clock reset. Without this we are hitting read/write timeouts randomly during runtime pm. Along with this remove a swr_reset redundant flag.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/lpass-rx-macro.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 3143f9cd7277..338e3f0cad12 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -596,7 +596,6 @@ struct rx_macro { int rx_port_value[RX_MACRO_PORTS_MAX]; u16 prim_int_users[INTERP_MAX]; int rx_mclk_users; - bool reset_swr; int clsh_users; int rx_mclk_cnt; bool is_ear_mode_on; @@ -3442,18 +3441,15 @@ static int swclk_gate_enable(struct clk_hw *hw) }
rx_macro_mclk_enable(rx, true); - if (rx->reset_swr) - regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, - CDC_RX_SWR_RESET_MASK, - CDC_RX_SWR_RESET); + regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + CDC_RX_SWR_RESET_MASK, + CDC_RX_SWR_RESET);
regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, CDC_RX_SWR_CLK_EN_MASK, 1);
- if (rx->reset_swr) - regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, - CDC_RX_SWR_RESET_MASK, 0); - rx->reset_swr = false; + regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + CDC_RX_SWR_RESET_MASK, 0);
return 0; } @@ -3579,7 +3575,6 @@ static int rx_macro_probe(struct platform_device *pdev)
dev_set_drvdata(dev, rx);
- rx->reset_swr = true; rx->dev = dev;
/* set MCLK and NPL rates */ @@ -3701,7 +3696,6 @@ static int __maybe_unused rx_macro_runtime_resume(struct device *dev) } regcache_cache_only(rx->regmap, false); regcache_sync(rx->regmap); - rx->reset_swr = true;
return 0; err_fsgen:
Reset soundwire block on frame sync generation clock reset. Without this we are hitting read/write timeouts randomly during runtime pm. Along with this remove a swr_reset redundant flag.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/lpass-tx-macro.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index 55503ba480bb..c19bb19b717b 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -268,7 +268,6 @@ struct tx_macro { struct clk *fsgen; struct clk_hw hw; bool dec_active[NUM_DECIMATORS]; - bool reset_swr; int tx_mclk_users; u16 dmic_clk_div; bool bcs_enable; @@ -1702,18 +1701,14 @@ static int swclk_gate_enable(struct clk_hw *hw) }
tx_macro_mclk_enable(tx, true); - if (tx->reset_swr) - regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, - CDC_TX_SWR_RESET_MASK, - CDC_TX_SWR_RESET_ENABLE); + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + CDC_TX_SWR_RESET_MASK, CDC_TX_SWR_RESET_ENABLE);
regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, CDC_TX_SWR_CLK_EN_MASK, CDC_TX_SWR_CLK_ENABLE); - if (tx->reset_swr) - regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, - CDC_TX_SWR_RESET_MASK, 0x0); - tx->reset_swr = false; + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + CDC_TX_SWR_RESET_MASK, 0x0);
return 0; } @@ -1855,7 +1850,6 @@ static int tx_macro_probe(struct platform_device *pdev)
dev_set_drvdata(dev, tx);
- tx->reset_swr = true; tx->dev = dev;
/* set MCLK and NPL rates */ @@ -1970,7 +1964,6 @@ static int __maybe_unused tx_macro_runtime_resume(struct device *dev)
regcache_cache_only(tx->regmap, false); regcache_sync(tx->regmap); - tx->reset_swr = true;
return 0; err_fsgen:
currently active_decimator[] is unsigned long however we store negative values when there is no decimator setup -1.
This is first bug, and the second bug is that we do not check if the decimator is valid before writing to register using decimator as offset in CDC_TXn_TX_PATH_CTL()
Fix these both by making active_decimator as integer array and adding check in tx_macro_digital_mute() before accessing CDC_TXn_TX_PATH_CTL() register.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/lpass-tx-macro.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index c19bb19b717b..5c03ef8d88b3 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -259,7 +259,7 @@ struct tx_macro { struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; unsigned long active_ch_mask[TX_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS]; - unsigned long active_decimator[TX_MACRO_MAX_DAIS]; + int active_decimator[TX_MACRO_MAX_DAIS]; struct regmap *regmap; struct clk *mclk; struct clk *npl; @@ -1117,6 +1117,10 @@ static int tx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream) struct tx_macro *tx = snd_soc_component_get_drvdata(component); u16 decimator;
+ /* active decimator not set yet */ + if (tx->active_decimator[dai->id] == -1) + return 0; + decimator = tx->active_decimator[dai->id];
if (mute)
tx_macro_tx_mixer_put() and tx_macro_dec_mode_put() currently returns zero eventhough it changes the value. Fix this, so that change notifications are sent correctly.
Fixes: d207bdea0ca9 ("ASoC: codecs: lpass-tx-macro: add dapm widgets and route") Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/lpass-tx-macro.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index 5c03ef8d88b3..7f9370ed126f 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -822,17 +822,23 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, struct tx_macro *tx = snd_soc_component_get_drvdata(component);
if (enable) { + if (tx->active_decimator[dai_id] == dec_id) + return 0; + set_bit(dec_id, &tx->active_ch_mask[dai_id]); tx->active_ch_cnt[dai_id]++; tx->active_decimator[dai_id] = dec_id; } else { + if (tx->active_decimator[dai_id] == -1) + return 0; + tx->active_ch_cnt[dai_id]--; clear_bit(dec_id, &tx->active_ch_mask[dai_id]); tx->active_decimator[dai_id] = -1; } snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
- return 0; + return 1; }
static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, @@ -1018,9 +1024,12 @@ static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol, int path = e->shift_l; struct tx_macro *tx = snd_soc_component_get_drvdata(component);
+ if (tx->dec_mode[path] == value) + return 0; + tx->dec_mode[path] = value;
- return 0; + return 1; }
static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol,
WSA883x does support clock stop, so remove code that reset the Codec during runtime pm suspend and add flag to mark clock stop support.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/wsa883x.c | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-)
diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index 63e1d7aa6137..c7b10bbfba7e 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -415,7 +415,6 @@
#define WSA883X_NUM_REGISTERS (WSA883X_EMEM_63 + 1) #define WSA883X_MAX_REGISTER (WSA883X_NUM_REGISTERS - 1) -#define WSA883X_PROBE_TIMEOUT 1000
#define WSA883X_VERSION_1_0 0 #define WSA883X_VERSION_1_1 1 @@ -1409,6 +1408,7 @@ static int wsa883x_probe(struct sdw_slave *pdev, wsa883x->sconfig.type = SDW_STREAM_PDM;
pdev->prop.sink_ports = GENMASK(WSA883X_MAX_SWR_PORTS, 0); + pdev->prop.simple_clk_stop_capable = true; pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop; pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; gpiod_direction_output(wsa883x->sd_n, 1); @@ -1440,43 +1440,17 @@ static int wsa883x_probe(struct sdw_slave *pdev, static int __maybe_unused wsa883x_runtime_suspend(struct device *dev) { struct regmap *regmap = dev_get_regmap(dev, NULL); - struct wsa883x_priv *wsa883x = dev_get_drvdata(dev); - - gpiod_direction_output(wsa883x->sd_n, 0);
regcache_cache_only(regmap, true); regcache_mark_dirty(regmap);
- regulator_disable(wsa883x->vdd); return 0; }
static int __maybe_unused wsa883x_runtime_resume(struct device *dev) { - struct sdw_slave *slave = dev_to_sdw_dev(dev); struct regmap *regmap = dev_get_regmap(dev, NULL); - struct wsa883x_priv *wsa883x = dev_get_drvdata(dev); - unsigned long time; - int ret; - - ret = regulator_enable(wsa883x->vdd); - if (ret) { - dev_err(dev, "Failed to enable vdd regulator (%d)\n", ret); - return ret; - } - - gpiod_direction_output(wsa883x->sd_n, 1); - - time = wait_for_completion_timeout(&slave->initialization_complete, - msecs_to_jiffies(WSA883X_PROBE_TIMEOUT)); - if (!time) { - dev_err(dev, "Initialization not complete, timed out\n"); - gpiod_direction_output(wsa883x->sd_n, 0); - regulator_disable(wsa883x->vdd); - return -ETIMEDOUT; - }
- usleep_range(20000, 20010); regcache_cache_only(regmap, false); regcache_sync(regmap);
This patch adds SM8450 and SC8280XP compatible entry for LPASS TX, RX, WSA and VA codec macros.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Acked-by: Rob Herring robh@kernel.org --- .../devicetree/bindings/sound/qcom,lpass-rx-macro.yaml | 2 ++ .../devicetree/bindings/sound/qcom,lpass-tx-macro.yaml | 2 ++ .../devicetree/bindings/sound/qcom,lpass-va-macro.yaml | 2 ++ .../devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml | 2 ++ 4 files changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml index a6905bcf89d2..1de11e7f33bb 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml @@ -14,6 +14,8 @@ properties: enum: - qcom,sc7280-lpass-rx-macro - qcom,sm8250-lpass-rx-macro + - qcom,sm8450-lpass-rx-macro + - qcom,sc8280xp-lpass-rx-macro
reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml index 324595a62ae8..de8297b358e8 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml @@ -14,6 +14,8 @@ properties: enum: - qcom,sc7280-lpass-tx-macro - qcom,sm8250-lpass-tx-macro + - qcom,sm8450-lpass-tx-macro + - qcom,sc8280xp-lpass-tx-macro
reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml index 7b4cc84eda8c..9f473c08cb2e 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml @@ -14,6 +14,8 @@ properties: enum: - qcom,sc7280-lpass-va-macro - qcom,sm8250-lpass-va-macro + - qcom,sm8450-lpass-va-macro + - qcom,sc8280xp-lpass-va-macro
reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml index 13cdb8a10687..4959ad658eac 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml @@ -14,6 +14,8 @@ properties: enum: - qcom,sc7280-lpass-wsa-macro - qcom,sm8250-lpass-wsa-macro + - qcom,sm8450-lpass-wsa-macro + - qcom,sc8280xp-lpass-wsa-macro
reg: maxItems: 1
Add compatible for sm8450 and sc8280xp.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/lpass-wsa-macro.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index 130d25b334ff..5e0abefe7cce 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -2552,6 +2552,8 @@ static const struct dev_pm_ops wsa_macro_pm_ops = { static const struct of_device_id wsa_macro_dt_match[] = { {.compatible = "qcom,sc7280-lpass-wsa-macro"}, {.compatible = "qcom,sm8250-lpass-wsa-macro"}, + {.compatible = "qcom,sm8450-lpass-wsa-macro"}, + {.compatible = "qcom,sc8280xp-lpass-wsa-macro" }, {} }; MODULE_DEVICE_TABLE(of, wsa_macro_dt_match);
Add compatible for sm8450 and sc8280xp.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/lpass-tx-macro.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index 7f9370ed126f..ee15cf6b98bb 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -1994,6 +1994,8 @@ static const struct dev_pm_ops tx_macro_pm_ops = { static const struct of_device_id tx_macro_dt_match[] = { { .compatible = "qcom,sc7280-lpass-tx-macro" }, { .compatible = "qcom,sm8250-lpass-tx-macro" }, + { .compatible = "qcom,sm8450-lpass-tx-macro" }, + { .compatible = "qcom,sc8280xp-lpass-tx-macro" }, { } }; MODULE_DEVICE_TABLE(of, tx_macro_dt_match);
Add compatible for sm8450 and sc8280xp.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/lpass-rx-macro.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 338e3f0cad12..a9ef9d5ffcc5 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -3654,6 +3654,8 @@ static int rx_macro_remove(struct platform_device *pdev) static const struct of_device_id rx_macro_dt_match[] = { { .compatible = "qcom,sc7280-lpass-rx-macro" }, { .compatible = "qcom,sm8250-lpass-rx-macro" }, + { .compatible = "qcom,sm8450-lpass-rx-macro" }, + { .compatible = "qcom,sc8280xp-lpass-rx-macro" }, { } }; MODULE_DEVICE_TABLE(of, rx_macro_dt_match);
Clear the frame sync counter before enabling it.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/lpass-va-macro.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c index 1ea10dc70748..a35f684053d2 100644 --- a/sound/soc/codecs/lpass-va-macro.c +++ b/sound/soc/codecs/lpass-va-macro.c @@ -23,6 +23,7 @@ #define CDC_VA_MCLK_CONTROL_EN BIT(0) #define CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL (0x0004) #define CDC_VA_FS_CONTROL_EN BIT(0) +#define CDC_VA_FS_COUNTER_CLR BIT(1) #define CDC_VA_CLK_RST_CTRL_SWR_CONTROL (0x0008) #define CDC_VA_TOP_CSR_TOP_CFG0 (0x0080) #define CDC_VA_FS_BROADCAST_EN BIT(1) @@ -423,9 +424,12 @@ static int va_clk_rsc_fs_gen_request(struct va_macro *va, bool enable) regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, CDC_VA_MCLK_CONTROL_EN, CDC_VA_MCLK_CONTROL_EN); - + /* clear the fs counter */ + regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_VA_FS_CONTROL_EN | CDC_VA_FS_COUNTER_CLR, + CDC_VA_FS_CONTROL_EN | CDC_VA_FS_COUNTER_CLR); regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, - CDC_VA_FS_CONTROL_EN, + CDC_VA_FS_CONTROL_EN | CDC_VA_FS_COUNTER_CLR, CDC_VA_FS_CONTROL_EN);
regmap_update_bits(regmap, CDC_VA_TOP_CSR_TOP_CFG0,
LPASS VA Macro now has soundwire master to deal with access to analog mic in low power island use cases.
This is added after sc8280xp, add support for this. Along with this also add compatibles for sm8450 and sc8280xp.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/lpass-va-macro.c | 74 +++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-)
diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c index a35f684053d2..b0b6cf29cba3 100644 --- a/sound/soc/codecs/lpass-va-macro.c +++ b/sound/soc/codecs/lpass-va-macro.c @@ -25,6 +25,10 @@ #define CDC_VA_FS_CONTROL_EN BIT(0) #define CDC_VA_FS_COUNTER_CLR BIT(1) #define CDC_VA_CLK_RST_CTRL_SWR_CONTROL (0x0008) +#define CDC_VA_SWR_RESET_MASK BIT(1) +#define CDC_VA_SWR_RESET_ENABLE BIT(1) +#define CDC_VA_SWR_CLK_EN_MASK BIT(0) +#define CDC_VA_SWR_CLK_ENABLE BIT(0) #define CDC_VA_TOP_CSR_TOP_CFG0 (0x0080) #define CDC_VA_FS_BROADCAST_EN BIT(1) #define CDC_VA_TOP_CSR_DMIC0_CTL (0x0084) @@ -66,6 +70,8 @@ #define CDC_VA_TOP_CSR_SWR_MIC_CTL0 (0x00D0) #define CDC_VA_TOP_CSR_SWR_MIC_CTL1 (0x00D4) #define CDC_VA_TOP_CSR_SWR_MIC_CTL2 (0x00D8) +#define CDC_VA_SWR_MIC_CLK_SEL_0_1_MASK (0xEE) +#define CDC_VA_SWR_MIC_CLK_SEL_0_1_DIV1 (0xCC) #define CDC_VA_TOP_CSR_SWR_CTRL (0x00DC) #define CDC_VA_INP_MUX_ADC_MUX0_CFG0 (0x0100) #define CDC_VA_INP_MUX_ADC_MUX0_CFG1 (0x0104) @@ -194,6 +200,7 @@ struct va_macro { unsigned long active_ch_mask[VA_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[VA_MACRO_MAX_DAIS]; u16 dmic_clk_div; + bool has_swr_master;
int dec_mode[VA_MACRO_NUM_DECIMATORS]; struct regmap *regmap; @@ -216,6 +223,18 @@ struct va_macro {
#define to_va_macro(_hw) container_of(_hw, struct va_macro, hw)
+struct va_macro_data { + bool has_swr_master; +}; + +static const struct va_macro_data sm8250_va_data = { + .has_swr_master = false, +}; + +static const struct va_macro_data sm8450_va_data = { + .has_swr_master = true, +}; + static bool va_is_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { @@ -325,6 +344,9 @@ static bool va_is_rw_register(struct device *dev, unsigned int reg) case CDC_VA_TOP_CSR_DMIC2_CTL: case CDC_VA_TOP_CSR_DMIC3_CTL: case CDC_VA_TOP_CSR_DMIC_CFG: + case CDC_VA_TOP_CSR_SWR_MIC_CTL0: + case CDC_VA_TOP_CSR_SWR_MIC_CTL1: + case CDC_VA_TOP_CSR_SWR_MIC_CTL2: case CDC_VA_TOP_CSR_DEBUG_BUS: case CDC_VA_TOP_CSR_DEBUG_EN: case CDC_VA_TOP_CSR_TX_I2S_CTL: @@ -1306,12 +1328,36 @@ static const struct snd_soc_component_driver va_macro_component_drv = {
static int fsgen_gate_enable(struct clk_hw *hw) { - return va_macro_mclk_enable(to_va_macro(hw), true); + struct va_macro *va = to_va_macro(hw); + struct regmap *regmap = va->regmap; + int ret; + + ret = va_macro_mclk_enable(va, true); + if (!va->has_swr_master) + return ret; + + regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL, + CDC_VA_SWR_RESET_MASK, CDC_VA_SWR_RESET_ENABLE); + + regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL, + CDC_VA_SWR_CLK_EN_MASK, + CDC_VA_SWR_CLK_ENABLE); + regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL, + CDC_VA_SWR_RESET_MASK, 0x0); + + return ret; }
static void fsgen_gate_disable(struct clk_hw *hw) { - va_macro_mclk_enable(to_va_macro(hw), false); + struct va_macro *va = to_va_macro(hw); + struct regmap *regmap = va->regmap; + + if (va->has_swr_master) + regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL, + CDC_VA_SWR_CLK_EN_MASK, 0x0); + + va_macro_mclk_enable(va, false); }
static int fsgen_gate_is_enabled(struct clk_hw *hw) @@ -1405,6 +1451,7 @@ static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate, static int va_macro_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + const struct va_macro_data *data; struct va_macro *va; void __iomem *base; u32 sample_rate = 0; @@ -1459,6 +1506,9 @@ static int va_macro_probe(struct platform_device *pdev)
dev_set_drvdata(dev, va);
+ data = of_device_get_match_data(dev); + va->has_swr_master = data->has_swr_master; + /* mclk rate */ clk_set_rate(va->mclk, 2 * VA_MACRO_MCLK_FREQ);
@@ -1484,6 +1534,20 @@ static int va_macro_probe(struct platform_device *pdev) goto err_clkout; }
+ if (va->has_swr_master) { + /* Set default CLK div to 1 */ + regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL0, + CDC_VA_SWR_MIC_CLK_SEL_0_1_MASK, + CDC_VA_SWR_MIC_CLK_SEL_0_1_DIV1); + regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL1, + CDC_VA_SWR_MIC_CLK_SEL_0_1_MASK, + CDC_VA_SWR_MIC_CLK_SEL_0_1_DIV1); + regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL2, + CDC_VA_SWR_MIC_CLK_SEL_0_1_MASK, + CDC_VA_SWR_MIC_CLK_SEL_0_1_DIV1); + + } + ret = devm_snd_soc_register_component(dev, &va_macro_component_drv, va_macro_dais, ARRAY_SIZE(va_macro_dais)); @@ -1558,8 +1622,10 @@ static const struct dev_pm_ops va_macro_pm_ops = { };
static const struct of_device_id va_macro_dt_match[] = { - { .compatible = "qcom,sc7280-lpass-va-macro" }, - { .compatible = "qcom,sm8250-lpass-va-macro" }, + { .compatible = "qcom,sc7280-lpass-va-macro", .data = &sm8250_va_data }, + { .compatible = "qcom,sm8250-lpass-va-macro", .data = &sm8250_va_data }, + { .compatible = "qcom,sm8450-lpass-va-macro", .data = &sm8450_va_data }, + { .compatible = "qcom,sc8280xp-lpass-va-macro", .data = &sm8450_va_data }, {} }; MODULE_DEVICE_TABLE(of, va_macro_dt_match);
On Tue, 6 Sep 2022 18:01:00 +0100, Srinivas Kandagatla wrote:
This patchset adds support for SM8450 and SC8280XP SoC and also some of the fixes requried to get stable audio on X13s.
Tested SmartSpeakers and Headset on SM8450 MTP and Lenovo Thinkpad X13s.
Changes since v1:
- moved va-macro from using of_device_is_compatible to compatible data
- added some fixes for qcom codecs.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[01/12] ASoC: codecs: wsa-macro: handle swr_reset correctly commit: fdc972d4a754b32cdf05294669ae0d6036242826 [02/12] ASoC: codecs: rx-macro: handle swr_reset correctly commit: 1a4e73915a7553d7ffb4f365b8a671bb2fa1f7ef [03/12] ASoC: codecs: tx-macro: handle swr_reset correctly commit: d83a7201412d32e2ac76f20439470976b2edf699 [04/12] ASoC: codecs: tx-macro: fix active_decimator array commit: 1c6a7f5250ce81f11a248f9bf88fdbca8b6b0b5d [05/12] ASoC: codecs: tx-macro: fix kcontrol put commit: c1057a08af438e0cf5450c1d977a3011198ed2f8 [06/12] ASoC: codecs: wsa883x: add clock stop support commit: 3e29fb7479760d6d03380125d500b60081ccb5e9 [07/12] ASoC: qcom: dt-bindings: add sm8450 and sc8280xp compatibles commit: 473d218b56559934ef4720a6fc086c8ad0da9d38 [08/12] ASoC: codecs: wsa-macro: add support for sm8450 and sc8280xp commit: 8d2be441ebc1078eaa9f2b7aa7c6d3880973851e [09/12] ASoC: codecs: tx-macro: add support for sm8450 and sc8280xp commit: 7ca36514752fa5bdf0d237436dc0042aefbf42ad [10/12] ASoC: codecs: rx-macro: add support for sm8450 and sc8280xp commit: c0bcaa72fabab1f2900aecc8643f33212c0072cc [11/12] ASoC: codecs: va-macro: clear the frame sync counter before enabling commit: c55b7381d7932eb303dbd97691f89c1a9c452956 [12/12] ASoC: codecs: va-macro: add support for sm8450 and sc8280xp commit: 0f47dd211938d5646f4041407089390bf89b96e8
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Mark Brown
-
Srinivas Kandagatla