Loading asoc/codecs/bolero/bolero-cdc.c +129 −1 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ */ #include <linux/of_platform.h> #include <linux/of_platform.h> Loading Loading @@ -476,6 +476,129 @@ void bolero_unregister_res_clk(struct device *dev) } } EXPORT_SYMBOL(bolero_unregister_res_clk); EXPORT_SYMBOL(bolero_unregister_res_clk); static u8 bolero_dmic_clk_div_get(struct snd_soc_component *component, int mode) { struct bolero_priv* priv = snd_soc_component_get_drvdata(component); int macro = (mode ? VA_MACRO : TX_MACRO); int ret = 0; if (priv->macro_params[macro].clk_div_get) { ret = priv->macro_params[macro].clk_div_get(component); if (ret > 0) return ret; } return 1; } int bolero_dmic_clk_enable(struct snd_soc_component *component, u32 dmic, u32 tx_mode, bool enable) { struct bolero_priv* priv = snd_soc_component_get_drvdata(component); u8 dmic_clk_en = 0x01; u16 dmic_clk_reg = 0; s32 *dmic_clk_cnt = NULL; u8 *dmic_clk_div = NULL; u8 freq_change_mask = 0; u8 clk_div = 0; dev_dbg(component->dev, "%s: enable: %d, tx_mode:%d, dmic: %d\n", __func__, enable, tx_mode, dmic); switch (dmic) { case 0: case 1: dmic_clk_cnt = &(priv->dmic_0_1_clk_cnt); dmic_clk_div = &(priv->dmic_0_1_clk_div); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL; freq_change_mask = 0x01; break; case 2: case 3: dmic_clk_cnt = &(priv->dmic_2_3_clk_cnt); dmic_clk_div = &(priv->dmic_2_3_clk_div); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL; freq_change_mask = 0x02; break; case 4: case 5: dmic_clk_cnt = &(priv->dmic_4_5_clk_cnt); dmic_clk_div = &(priv->dmic_4_5_clk_div); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL; freq_change_mask = 0x04; break; case 6: case 7: dmic_clk_cnt = &(priv->dmic_6_7_clk_cnt); dmic_clk_div = &(priv->dmic_6_7_clk_div); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; freq_change_mask = 0x08; break; default: dev_err(component->dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; } dev_dbg(component->dev, "%s: DMIC%d dmic_clk_cnt %d\n", __func__, dmic, *dmic_clk_cnt); if (enable) { clk_div = bolero_dmic_clk_div_get(component, tx_mode); (*dmic_clk_cnt)++; if (*dmic_clk_cnt == 1) { snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, 0x80, 0x00); snd_soc_component_update_bits(component, dmic_clk_reg, 0x0E, clk_div << 0x1); snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, dmic_clk_en); } else { if (*dmic_clk_div > clk_div) { snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, freq_change_mask, freq_change_mask); snd_soc_component_update_bits(component, dmic_clk_reg, 0x0E, clk_div << 0x1); snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, freq_change_mask, 0x00); } else { clk_div = *dmic_clk_div; } } *dmic_clk_div = clk_div; } else { (*dmic_clk_cnt)--; if (*dmic_clk_cnt == 0) { snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, 0); clk_div = 0; snd_soc_component_update_bits(component, dmic_clk_reg, 0x0E, clk_div << 0x1); } else { clk_div = bolero_dmic_clk_div_get(component, tx_mode); if (*dmic_clk_div > clk_div) { clk_div = bolero_dmic_clk_div_get(component, !tx_mode); snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, freq_change_mask, freq_change_mask); snd_soc_component_update_bits(component, dmic_clk_reg, 0x0E, clk_div << 0x1); snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, freq_change_mask, 0x00); } else { clk_div = *dmic_clk_div; } } *dmic_clk_div = clk_div; } return 0; } EXPORT_SYMBOL(bolero_dmic_clk_enable); /** /** * bolero_register_macro - Registers macro to bolero * bolero_register_macro - Registers macro to bolero * * Loading Loading @@ -524,6 +647,9 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->macro_params[macro_id].reg_evt_listener = priv->macro_params[macro_id].reg_evt_listener = ops->reg_evt_listener; ops->reg_evt_listener; } } if (macro_id == TX_MACRO || macro_id == VA_MACRO) priv->macro_params[macro_id].clk_div_get = ops->clk_div_get; if (priv->version == BOLERO_VERSION_2_1) { if (priv->version == BOLERO_VERSION_2_1) { if (macro_id == VA_MACRO) if (macro_id == VA_MACRO) priv->macro_params[macro_id].reg_wake_irq = priv->macro_params[macro_id].reg_wake_irq = Loading Loading @@ -594,6 +720,8 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) priv->macro_params[macro_id].clk_switch = NULL; priv->macro_params[macro_id].clk_switch = NULL; priv->macro_params[macro_id].reg_evt_listener = NULL; priv->macro_params[macro_id].reg_evt_listener = NULL; } } if (macro_id == TX_MACRO || macro_id == VA_MACRO) priv->macro_params[macro_id].clk_div_get = NULL; priv->num_dais -= priv->macro_params[macro_id].num_dais; priv->num_dais -= priv->macro_params[macro_id].num_dais; priv->num_macros_registered--; priv->num_macros_registered--; Loading asoc/codecs/bolero/bolero-cdc.h +16 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ */ #ifndef BOLERO_CDC_H #ifndef BOLERO_CDC_H Loading Loading @@ -50,6 +50,12 @@ enum { BOLERO_MACRO_EVT_BCS_CLK_OFF BOLERO_MACRO_EVT_BCS_CLK_OFF }; }; enum { DMIC_TX = 0, DMIC_VA = 1, }; struct macro_ops { struct macro_ops { int (*init)(struct snd_soc_component *component); int (*init)(struct snd_soc_component *component); int (*exit)(struct snd_soc_component *component); int (*exit)(struct snd_soc_component *component); Loading @@ -63,6 +69,7 @@ struct macro_ops { int (*set_port_map)(struct snd_soc_component *component, u32 uc, int (*set_port_map)(struct snd_soc_component *component, u32 uc, u32 size, void *data); u32 size, void *data); int (*clk_switch)(struct snd_soc_component *component); int (*clk_switch)(struct snd_soc_component *component); int (*clk_div_get)(struct snd_soc_component *component); int (*reg_evt_listener)(struct snd_soc_component *component, bool en); int (*reg_evt_listener)(struct snd_soc_component *component, bool en); char __iomem *io_base; char __iomem *io_base; u16 clk_id_req; u16 clk_id_req; Loading Loading @@ -93,6 +100,8 @@ int bolero_register_event_listener(struct snd_soc_component *component, void bolero_wsa_pa_on(struct device *dev); void bolero_wsa_pa_on(struct device *dev); bool bolero_check_core_votes(struct device *dev); bool bolero_check_core_votes(struct device *dev); int bolero_get_version(struct device *dev); int bolero_get_version(struct device *dev); int bolero_dmic_clk_enable(struct snd_soc_component *component, u32 dmic, u32 tx_mode, bool enable); #else #else static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) { { Loading Loading @@ -177,5 +186,11 @@ static int bolero_get_version(struct device *dev) { { return 0; return 0; } } static int bolero_dmic_clk_enable(struct snd_soc_component *component, u32 dmic, u32 tx_mode, bool enable) { return 0; } #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ #endif /* BOLERO_CDC_H */ asoc/codecs/bolero/internal.h +9 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ */ #ifndef _BOLERO_INTERNAL_H #ifndef _BOLERO_INTERNAL_H Loading Loading @@ -82,6 +82,14 @@ struct bolero_priv { struct blocking_notifier_head notifier; struct blocking_notifier_head notifier; struct device *clk_dev; struct device *clk_dev; rsc_clk_cb_t rsc_clk_cb; rsc_clk_cb_t rsc_clk_cb; s32 dmic_0_1_clk_cnt; s32 dmic_2_3_clk_cnt; s32 dmic_4_5_clk_cnt; s32 dmic_6_7_clk_cnt; u8 dmic_0_1_clk_div; u8 dmic_2_3_clk_div; u8 dmic_4_5_clk_div; u8 dmic_6_7_clk_div; }; }; struct regmap *bolero_regmap_init(struct device *dev, struct regmap *bolero_regmap_init(struct device *dev, Loading asoc/codecs/bolero/tx-macro.c +16 −55 Original line number Original line Diff line number Diff line Loading @@ -158,10 +158,6 @@ struct tx_macro_priv { struct work_struct tx_macro_add_child_devices_work; struct work_struct tx_macro_add_child_devices_work; struct hpf_work tx_hpf_work[NUM_DECIMATORS]; struct hpf_work tx_hpf_work[NUM_DECIMATORS]; struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; s32 dmic_0_1_clk_cnt; s32 dmic_2_3_clk_cnt; s32 dmic_4_5_clk_cnt; s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; u16 dmic_clk_div; u32 version; u32 version; u32 is_used_tx_swr_gpio; u32 is_used_tx_swr_gpio; Loading Loading @@ -814,17 +810,9 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, { { struct snd_soc_component *component = struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); snd_soc_dapm_to_component(w->dapm); u8 dmic_clk_en = 0x01; u16 dmic_clk_reg = 0; s32 *dmic_clk_cnt = NULL; unsigned int dmic = 0; unsigned int dmic = 0; int ret = 0; int ret = 0; char *wname = NULL; char *wname = NULL; struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; wname = strpbrk(w->name, "01234567"); wname = strpbrk(w->name, "01234567"); if (!wname) { if (!wname) { Loading @@ -839,54 +827,15 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, return -EINVAL; return -EINVAL; } } switch (dmic) { dev_dbg(component->dev, "%s: event %d DMIC%d\n", case 0: __func__, event, dmic); case 1: dmic_clk_cnt = &(tx_priv->dmic_0_1_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL; break; case 2: case 3: dmic_clk_cnt = &(tx_priv->dmic_2_3_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL; break; case 4: case 5: dmic_clk_cnt = &(tx_priv->dmic_4_5_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL; break; case 6: case 7: dmic_clk_cnt = &(tx_priv->dmic_6_7_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; break; default: dev_err(component->dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; } dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", __func__, event, dmic, *dmic_clk_cnt); switch (event) { switch (event) { case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU: (*dmic_clk_cnt)++; bolero_dmic_clk_enable(component, dmic, DMIC_TX, true); if (*dmic_clk_cnt == 1) { snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, 0x80, 0x00); snd_soc_component_update_bits(component, dmic_clk_reg, 0x0E, tx_priv->dmic_clk_div << 0x1); snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, dmic_clk_en); } break; break; case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD: (*dmic_clk_cnt)--; bolero_dmic_clk_enable(component, dmic, DMIC_TX, false); if (*dmic_clk_cnt == 0) snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, 0); break; break; } } Loading Loading @@ -2665,6 +2614,17 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, return ret; return ret; } } static int tx_macro_clk_div_get(struct snd_soc_component *component) { struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; return tx_priv->dmic_clk_div; } static int tx_macro_clk_switch(struct snd_soc_component *component) static int tx_macro_clk_switch(struct snd_soc_component *component) { { struct device *tx_dev = NULL; struct device *tx_dev = NULL; Loading Loading @@ -3168,6 +3128,7 @@ static void tx_macro_init_ops(struct macro_ops *ops, ops->event_handler = tx_macro_event_handler; ops->event_handler = tx_macro_event_handler; ops->reg_wake_irq = tx_macro_reg_wake_irq; ops->reg_wake_irq = tx_macro_reg_wake_irq; ops->set_port_map = tx_macro_set_port_map; ops->set_port_map = tx_macro_set_port_map; ops->clk_div_get = tx_macro_clk_div_get; ops->clk_switch = tx_macro_clk_switch; ops->clk_switch = tx_macro_clk_switch; ops->reg_evt_listener = tx_macro_register_event_listener; ops->reg_evt_listener = tx_macro_register_event_listener; } } Loading asoc/codecs/bolero/va-macro.c +20 −61 Original line number Original line Diff line number Diff line Loading @@ -142,10 +142,6 @@ struct va_macro_priv { struct va_mute_work va_mute_dwork[VA_MACRO_NUM_DECIMATORS]; struct va_mute_work va_mute_dwork[VA_MACRO_NUM_DECIMATORS]; unsigned long active_ch_mask[VA_MACRO_MAX_DAIS]; unsigned long active_ch_mask[VA_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[VA_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[VA_MACRO_MAX_DAIS]; s32 dmic_0_1_clk_cnt; s32 dmic_2_3_clk_cnt; s32 dmic_4_5_clk_cnt; s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; u16 dmic_clk_div; u16 va_mclk_users; u16 va_mclk_users; int swr_clk_users; int swr_clk_users; Loading Loading @@ -196,6 +192,17 @@ static bool va_macro_get_data(struct snd_soc_component *component, return true; return true; } } static int va_macro_clk_div_get(struct snd_soc_component *component) { struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; return va_priv->dmic_clk_div; } static int va_macro_mclk_enable(struct va_macro_priv *va_priv, static int va_macro_mclk_enable(struct va_macro_priv *va_priv, bool mclk_enable, bool dapm) bool mclk_enable, bool dapm) { { Loading Loading @@ -978,81 +985,32 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, { { struct snd_soc_component *component = struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); snd_soc_dapm_to_component(w->dapm); u8 dmic_clk_en = 0x01; unsigned int dmic = 0; u16 dmic_clk_reg; int ret = 0; s32 *dmic_clk_cnt; unsigned int dmic; int ret; char *wname; char *wname; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; wname = strpbrk(w->name, "01234567"); wname = strpbrk(w->name, "01234567"); if (!wname) { if (!wname) { dev_err(va_dev, "%s: widget not found\n", __func__); dev_err(component->dev, "%s: widget not found\n", __func__); return -EINVAL; return -EINVAL; } } ret = kstrtouint(wname, 10, &dmic); ret = kstrtouint(wname, 10, &dmic); if (ret < 0) { if (ret < 0) { dev_err(va_dev, "%s: Invalid DMIC line on the codec\n", dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", __func__); __func__); return -EINVAL; return -EINVAL; } } switch (dmic) { dev_dbg(component->dev, "%s: event %d DMIC%d\n", case 0: __func__, event, dmic); case 1: dmic_clk_cnt = &(va_priv->dmic_0_1_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL; break; case 2: case 3: dmic_clk_cnt = &(va_priv->dmic_2_3_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL; break; case 4: case 5: dmic_clk_cnt = &(va_priv->dmic_4_5_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL; break; case 6: case 7: dmic_clk_cnt = &(va_priv->dmic_6_7_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; break; default: dev_err(va_dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; } dev_dbg(va_dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", __func__, event, dmic, *dmic_clk_cnt); switch (event) { switch (event) { case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU: (*dmic_clk_cnt)++; bolero_dmic_clk_enable(component, dmic, DMIC_VA, true); if (*dmic_clk_cnt == 1) { snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, 0x80, 0x00); snd_soc_component_update_bits(component, dmic_clk_reg, VA_MACRO_TX_DMIC_CLK_DIV_MASK, va_priv->dmic_clk_div << VA_MACRO_TX_DMIC_CLK_DIV_SHFT); snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, dmic_clk_en); } break; break; case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD: (*dmic_clk_cnt)--; bolero_dmic_clk_enable(component, dmic, DMIC_VA, false); if (*dmic_clk_cnt == 0) { snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, 0); } break; break; } } Loading Loading @@ -2834,6 +2792,7 @@ static void va_macro_init_ops(struct macro_ops *ops, ops->event_handler = va_macro_event_handler; ops->event_handler = va_macro_event_handler; ops->set_port_map = va_macro_set_port_map; ops->set_port_map = va_macro_set_port_map; ops->reg_wake_irq = va_macro_reg_wake_irq; ops->reg_wake_irq = va_macro_reg_wake_irq; ops->clk_div_get = va_macro_clk_div_get; } } static int va_macro_probe(struct platform_device *pdev) static int va_macro_probe(struct platform_device *pdev) Loading Loading
asoc/codecs/bolero/bolero-cdc.c +129 −1 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ */ #include <linux/of_platform.h> #include <linux/of_platform.h> Loading Loading @@ -476,6 +476,129 @@ void bolero_unregister_res_clk(struct device *dev) } } EXPORT_SYMBOL(bolero_unregister_res_clk); EXPORT_SYMBOL(bolero_unregister_res_clk); static u8 bolero_dmic_clk_div_get(struct snd_soc_component *component, int mode) { struct bolero_priv* priv = snd_soc_component_get_drvdata(component); int macro = (mode ? VA_MACRO : TX_MACRO); int ret = 0; if (priv->macro_params[macro].clk_div_get) { ret = priv->macro_params[macro].clk_div_get(component); if (ret > 0) return ret; } return 1; } int bolero_dmic_clk_enable(struct snd_soc_component *component, u32 dmic, u32 tx_mode, bool enable) { struct bolero_priv* priv = snd_soc_component_get_drvdata(component); u8 dmic_clk_en = 0x01; u16 dmic_clk_reg = 0; s32 *dmic_clk_cnt = NULL; u8 *dmic_clk_div = NULL; u8 freq_change_mask = 0; u8 clk_div = 0; dev_dbg(component->dev, "%s: enable: %d, tx_mode:%d, dmic: %d\n", __func__, enable, tx_mode, dmic); switch (dmic) { case 0: case 1: dmic_clk_cnt = &(priv->dmic_0_1_clk_cnt); dmic_clk_div = &(priv->dmic_0_1_clk_div); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL; freq_change_mask = 0x01; break; case 2: case 3: dmic_clk_cnt = &(priv->dmic_2_3_clk_cnt); dmic_clk_div = &(priv->dmic_2_3_clk_div); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL; freq_change_mask = 0x02; break; case 4: case 5: dmic_clk_cnt = &(priv->dmic_4_5_clk_cnt); dmic_clk_div = &(priv->dmic_4_5_clk_div); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL; freq_change_mask = 0x04; break; case 6: case 7: dmic_clk_cnt = &(priv->dmic_6_7_clk_cnt); dmic_clk_div = &(priv->dmic_6_7_clk_div); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; freq_change_mask = 0x08; break; default: dev_err(component->dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; } dev_dbg(component->dev, "%s: DMIC%d dmic_clk_cnt %d\n", __func__, dmic, *dmic_clk_cnt); if (enable) { clk_div = bolero_dmic_clk_div_get(component, tx_mode); (*dmic_clk_cnt)++; if (*dmic_clk_cnt == 1) { snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, 0x80, 0x00); snd_soc_component_update_bits(component, dmic_clk_reg, 0x0E, clk_div << 0x1); snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, dmic_clk_en); } else { if (*dmic_clk_div > clk_div) { snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, freq_change_mask, freq_change_mask); snd_soc_component_update_bits(component, dmic_clk_reg, 0x0E, clk_div << 0x1); snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, freq_change_mask, 0x00); } else { clk_div = *dmic_clk_div; } } *dmic_clk_div = clk_div; } else { (*dmic_clk_cnt)--; if (*dmic_clk_cnt == 0) { snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, 0); clk_div = 0; snd_soc_component_update_bits(component, dmic_clk_reg, 0x0E, clk_div << 0x1); } else { clk_div = bolero_dmic_clk_div_get(component, tx_mode); if (*dmic_clk_div > clk_div) { clk_div = bolero_dmic_clk_div_get(component, !tx_mode); snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, freq_change_mask, freq_change_mask); snd_soc_component_update_bits(component, dmic_clk_reg, 0x0E, clk_div << 0x1); snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, freq_change_mask, 0x00); } else { clk_div = *dmic_clk_div; } } *dmic_clk_div = clk_div; } return 0; } EXPORT_SYMBOL(bolero_dmic_clk_enable); /** /** * bolero_register_macro - Registers macro to bolero * bolero_register_macro - Registers macro to bolero * * Loading Loading @@ -524,6 +647,9 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->macro_params[macro_id].reg_evt_listener = priv->macro_params[macro_id].reg_evt_listener = ops->reg_evt_listener; ops->reg_evt_listener; } } if (macro_id == TX_MACRO || macro_id == VA_MACRO) priv->macro_params[macro_id].clk_div_get = ops->clk_div_get; if (priv->version == BOLERO_VERSION_2_1) { if (priv->version == BOLERO_VERSION_2_1) { if (macro_id == VA_MACRO) if (macro_id == VA_MACRO) priv->macro_params[macro_id].reg_wake_irq = priv->macro_params[macro_id].reg_wake_irq = Loading Loading @@ -594,6 +720,8 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) priv->macro_params[macro_id].clk_switch = NULL; priv->macro_params[macro_id].clk_switch = NULL; priv->macro_params[macro_id].reg_evt_listener = NULL; priv->macro_params[macro_id].reg_evt_listener = NULL; } } if (macro_id == TX_MACRO || macro_id == VA_MACRO) priv->macro_params[macro_id].clk_div_get = NULL; priv->num_dais -= priv->macro_params[macro_id].num_dais; priv->num_dais -= priv->macro_params[macro_id].num_dais; priv->num_macros_registered--; priv->num_macros_registered--; Loading
asoc/codecs/bolero/bolero-cdc.h +16 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ */ #ifndef BOLERO_CDC_H #ifndef BOLERO_CDC_H Loading Loading @@ -50,6 +50,12 @@ enum { BOLERO_MACRO_EVT_BCS_CLK_OFF BOLERO_MACRO_EVT_BCS_CLK_OFF }; }; enum { DMIC_TX = 0, DMIC_VA = 1, }; struct macro_ops { struct macro_ops { int (*init)(struct snd_soc_component *component); int (*init)(struct snd_soc_component *component); int (*exit)(struct snd_soc_component *component); int (*exit)(struct snd_soc_component *component); Loading @@ -63,6 +69,7 @@ struct macro_ops { int (*set_port_map)(struct snd_soc_component *component, u32 uc, int (*set_port_map)(struct snd_soc_component *component, u32 uc, u32 size, void *data); u32 size, void *data); int (*clk_switch)(struct snd_soc_component *component); int (*clk_switch)(struct snd_soc_component *component); int (*clk_div_get)(struct snd_soc_component *component); int (*reg_evt_listener)(struct snd_soc_component *component, bool en); int (*reg_evt_listener)(struct snd_soc_component *component, bool en); char __iomem *io_base; char __iomem *io_base; u16 clk_id_req; u16 clk_id_req; Loading Loading @@ -93,6 +100,8 @@ int bolero_register_event_listener(struct snd_soc_component *component, void bolero_wsa_pa_on(struct device *dev); void bolero_wsa_pa_on(struct device *dev); bool bolero_check_core_votes(struct device *dev); bool bolero_check_core_votes(struct device *dev); int bolero_get_version(struct device *dev); int bolero_get_version(struct device *dev); int bolero_dmic_clk_enable(struct snd_soc_component *component, u32 dmic, u32 tx_mode, bool enable); #else #else static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) { { Loading Loading @@ -177,5 +186,11 @@ static int bolero_get_version(struct device *dev) { { return 0; return 0; } } static int bolero_dmic_clk_enable(struct snd_soc_component *component, u32 dmic, u32 tx_mode, bool enable) { return 0; } #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ #endif /* BOLERO_CDC_H */
asoc/codecs/bolero/internal.h +9 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ */ #ifndef _BOLERO_INTERNAL_H #ifndef _BOLERO_INTERNAL_H Loading Loading @@ -82,6 +82,14 @@ struct bolero_priv { struct blocking_notifier_head notifier; struct blocking_notifier_head notifier; struct device *clk_dev; struct device *clk_dev; rsc_clk_cb_t rsc_clk_cb; rsc_clk_cb_t rsc_clk_cb; s32 dmic_0_1_clk_cnt; s32 dmic_2_3_clk_cnt; s32 dmic_4_5_clk_cnt; s32 dmic_6_7_clk_cnt; u8 dmic_0_1_clk_div; u8 dmic_2_3_clk_div; u8 dmic_4_5_clk_div; u8 dmic_6_7_clk_div; }; }; struct regmap *bolero_regmap_init(struct device *dev, struct regmap *bolero_regmap_init(struct device *dev, Loading
asoc/codecs/bolero/tx-macro.c +16 −55 Original line number Original line Diff line number Diff line Loading @@ -158,10 +158,6 @@ struct tx_macro_priv { struct work_struct tx_macro_add_child_devices_work; struct work_struct tx_macro_add_child_devices_work; struct hpf_work tx_hpf_work[NUM_DECIMATORS]; struct hpf_work tx_hpf_work[NUM_DECIMATORS]; struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; s32 dmic_0_1_clk_cnt; s32 dmic_2_3_clk_cnt; s32 dmic_4_5_clk_cnt; s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; u16 dmic_clk_div; u32 version; u32 version; u32 is_used_tx_swr_gpio; u32 is_used_tx_swr_gpio; Loading Loading @@ -814,17 +810,9 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, { { struct snd_soc_component *component = struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); snd_soc_dapm_to_component(w->dapm); u8 dmic_clk_en = 0x01; u16 dmic_clk_reg = 0; s32 *dmic_clk_cnt = NULL; unsigned int dmic = 0; unsigned int dmic = 0; int ret = 0; int ret = 0; char *wname = NULL; char *wname = NULL; struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; wname = strpbrk(w->name, "01234567"); wname = strpbrk(w->name, "01234567"); if (!wname) { if (!wname) { Loading @@ -839,54 +827,15 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, return -EINVAL; return -EINVAL; } } switch (dmic) { dev_dbg(component->dev, "%s: event %d DMIC%d\n", case 0: __func__, event, dmic); case 1: dmic_clk_cnt = &(tx_priv->dmic_0_1_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL; break; case 2: case 3: dmic_clk_cnt = &(tx_priv->dmic_2_3_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL; break; case 4: case 5: dmic_clk_cnt = &(tx_priv->dmic_4_5_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL; break; case 6: case 7: dmic_clk_cnt = &(tx_priv->dmic_6_7_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; break; default: dev_err(component->dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; } dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", __func__, event, dmic, *dmic_clk_cnt); switch (event) { switch (event) { case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU: (*dmic_clk_cnt)++; bolero_dmic_clk_enable(component, dmic, DMIC_TX, true); if (*dmic_clk_cnt == 1) { snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, 0x80, 0x00); snd_soc_component_update_bits(component, dmic_clk_reg, 0x0E, tx_priv->dmic_clk_div << 0x1); snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, dmic_clk_en); } break; break; case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD: (*dmic_clk_cnt)--; bolero_dmic_clk_enable(component, dmic, DMIC_TX, false); if (*dmic_clk_cnt == 0) snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, 0); break; break; } } Loading Loading @@ -2665,6 +2614,17 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, return ret; return ret; } } static int tx_macro_clk_div_get(struct snd_soc_component *component) { struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; return tx_priv->dmic_clk_div; } static int tx_macro_clk_switch(struct snd_soc_component *component) static int tx_macro_clk_switch(struct snd_soc_component *component) { { struct device *tx_dev = NULL; struct device *tx_dev = NULL; Loading Loading @@ -3168,6 +3128,7 @@ static void tx_macro_init_ops(struct macro_ops *ops, ops->event_handler = tx_macro_event_handler; ops->event_handler = tx_macro_event_handler; ops->reg_wake_irq = tx_macro_reg_wake_irq; ops->reg_wake_irq = tx_macro_reg_wake_irq; ops->set_port_map = tx_macro_set_port_map; ops->set_port_map = tx_macro_set_port_map; ops->clk_div_get = tx_macro_clk_div_get; ops->clk_switch = tx_macro_clk_switch; ops->clk_switch = tx_macro_clk_switch; ops->reg_evt_listener = tx_macro_register_event_listener; ops->reg_evt_listener = tx_macro_register_event_listener; } } Loading
asoc/codecs/bolero/va-macro.c +20 −61 Original line number Original line Diff line number Diff line Loading @@ -142,10 +142,6 @@ struct va_macro_priv { struct va_mute_work va_mute_dwork[VA_MACRO_NUM_DECIMATORS]; struct va_mute_work va_mute_dwork[VA_MACRO_NUM_DECIMATORS]; unsigned long active_ch_mask[VA_MACRO_MAX_DAIS]; unsigned long active_ch_mask[VA_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[VA_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[VA_MACRO_MAX_DAIS]; s32 dmic_0_1_clk_cnt; s32 dmic_2_3_clk_cnt; s32 dmic_4_5_clk_cnt; s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; u16 dmic_clk_div; u16 va_mclk_users; u16 va_mclk_users; int swr_clk_users; int swr_clk_users; Loading Loading @@ -196,6 +192,17 @@ static bool va_macro_get_data(struct snd_soc_component *component, return true; return true; } } static int va_macro_clk_div_get(struct snd_soc_component *component) { struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; return va_priv->dmic_clk_div; } static int va_macro_mclk_enable(struct va_macro_priv *va_priv, static int va_macro_mclk_enable(struct va_macro_priv *va_priv, bool mclk_enable, bool dapm) bool mclk_enable, bool dapm) { { Loading Loading @@ -978,81 +985,32 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, { { struct snd_soc_component *component = struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); snd_soc_dapm_to_component(w->dapm); u8 dmic_clk_en = 0x01; unsigned int dmic = 0; u16 dmic_clk_reg; int ret = 0; s32 *dmic_clk_cnt; unsigned int dmic; int ret; char *wname; char *wname; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; wname = strpbrk(w->name, "01234567"); wname = strpbrk(w->name, "01234567"); if (!wname) { if (!wname) { dev_err(va_dev, "%s: widget not found\n", __func__); dev_err(component->dev, "%s: widget not found\n", __func__); return -EINVAL; return -EINVAL; } } ret = kstrtouint(wname, 10, &dmic); ret = kstrtouint(wname, 10, &dmic); if (ret < 0) { if (ret < 0) { dev_err(va_dev, "%s: Invalid DMIC line on the codec\n", dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", __func__); __func__); return -EINVAL; return -EINVAL; } } switch (dmic) { dev_dbg(component->dev, "%s: event %d DMIC%d\n", case 0: __func__, event, dmic); case 1: dmic_clk_cnt = &(va_priv->dmic_0_1_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL; break; case 2: case 3: dmic_clk_cnt = &(va_priv->dmic_2_3_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL; break; case 4: case 5: dmic_clk_cnt = &(va_priv->dmic_4_5_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL; break; case 6: case 7: dmic_clk_cnt = &(va_priv->dmic_6_7_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; break; default: dev_err(va_dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; } dev_dbg(va_dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", __func__, event, dmic, *dmic_clk_cnt); switch (event) { switch (event) { case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU: (*dmic_clk_cnt)++; bolero_dmic_clk_enable(component, dmic, DMIC_VA, true); if (*dmic_clk_cnt == 1) { snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, 0x80, 0x00); snd_soc_component_update_bits(component, dmic_clk_reg, VA_MACRO_TX_DMIC_CLK_DIV_MASK, va_priv->dmic_clk_div << VA_MACRO_TX_DMIC_CLK_DIV_SHFT); snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, dmic_clk_en); } break; break; case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD: (*dmic_clk_cnt)--; bolero_dmic_clk_enable(component, dmic, DMIC_VA, false); if (*dmic_clk_cnt == 0) { snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, 0); } break; break; } } Loading Loading @@ -2834,6 +2792,7 @@ static void va_macro_init_ops(struct macro_ops *ops, ops->event_handler = va_macro_event_handler; ops->event_handler = va_macro_event_handler; ops->set_port_map = va_macro_set_port_map; ops->set_port_map = va_macro_set_port_map; ops->reg_wake_irq = va_macro_reg_wake_irq; ops->reg_wake_irq = va_macro_reg_wake_irq; ops->clk_div_get = va_macro_clk_div_get; } } static int va_macro_probe(struct platform_device *pdev) static int va_macro_probe(struct platform_device *pdev) Loading