Loading asoc/codecs/swr-dmic.c +35 −44 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include "swr-dmic.h" #define NUM_ATTEMPTS 5 #define SWRS_SCP_CONTROL 0x44 static int swr_master_channel_map[] = { ZERO, Loading Loading @@ -66,6 +67,7 @@ struct swr_dmic_priv { int is_en_supply; int port_type; u8 tx_master_port_map[SWR_DMIC_MAX_PORTS]; struct notifier_block nblock; }; const char *codec_name_list[] = { Loading Loading @@ -245,38 +247,6 @@ static int dmic_swr_ctrl(struct snd_soc_dapm_widget *w, return ret; } static int swr_dmic_enable_supply(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct swr_dmic_priv *swr_dmic = snd_soc_component_get_drvdata(component); int ret = 0; dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: ret = swr_dmic_up(swr_dmic->swr_slave); break; case SND_SOC_DAPM_POST_PMU: ret = swr_dmic_reset(swr_dmic->swr_slave); break; case SND_SOC_DAPM_POST_PMD: ret = swr_dmic_down(swr_dmic->swr_slave); break; } if (ret) dev_dbg(component->dev, "%s wname: %s event: %d ret : %d\n", __func__, w->name, event, ret); 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", Loading Loading @@ -306,10 +276,6 @@ static const struct snd_soc_dapm_widget swr_dmic_dapm_widgets[] = { SND_SOC_DAPM_INPUT("SWR_DMIC"), SND_SOC_DAPM_SUPPLY_S("SMIC_SUPPLY", 1, SND_SOC_NOPM, 0, 0, swr_dmic_enable_supply, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_OUT_DRV_E("SMIC_PORT_EN", SND_SOC_NOPM, 0, 0, NULL, 0, swr_dmic_port_enable, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), Loading @@ -317,7 +283,6 @@ static const struct snd_soc_dapm_widget swr_dmic_dapm_widgets[] = { }; static const struct snd_soc_dapm_route swr_dmic_audio_map[] = { {"SWR_DMIC", NULL, "SMIC_SUPPLY"}, {"SWR_DMIC_MIXER", "Switch", "SWR_DMIC"}, {"SMIC_PORT_EN", NULL, "SWR_DMIC_MIXER"}, {"SWR_DMIC_OUTPUT", NULL, "SMIC_PORT_EN"}, Loading Loading @@ -393,6 +358,8 @@ static int enable_wcd_codec_supply(struct swr_dmic_priv *swr_dmic, bool enable) pr_err("%s: component is NULL\n", __func__); return -EINVAL; } dev_dbg(component->dev, "%s: supply %d micbias: %d enable: %d\n", __func__, swr_dmic->is_en_supply, micb_num, enable); if (enable) rc = wcd938x_codec_force_enable_micbias_v2(component, Loading Loading @@ -441,6 +408,29 @@ static struct snd_soc_dai_driver swr_dmic_dai[] = { }, }; static int swr_dmic_event_notify(struct notifier_block *block, unsigned long val, void *data) { u16 event = (val & 0xffff); int ret = 0; struct swr_dmic_priv *swr_dmic = container_of(block, struct swr_dmic_priv, nblock); switch (event) { case WCD938X_EVT_SSR_DOWN: ret = swr_dmic_down(swr_dmic->swr_slave); break; case WCD938X_EVT_SSR_UP: ret = swr_dmic_up(swr_dmic->swr_slave); if (!ret) ret = swr_dmic_reset(swr_dmic->swr_slave); break; } return ret; } static int swr_dmic_probe(struct swr_device *pdev) { int ret = 0; Loading Loading @@ -526,7 +516,7 @@ static int swr_dmic_probe(struct swr_device *pdev) "%s get devnum %d for dev addr %llx failed\n", __func__, swr_devnum, pdev->addr); ret = -EPROBE_DEFER; goto err; goto dev_err; } pdev->dev_num = swr_devnum; Loading Loading @@ -596,10 +586,9 @@ static int swr_dmic_probe(struct swr_device *pdev) strlen(swr_dmic_name_prefix_of) + 1); component->name_prefix = prefix_name; if (swr_dmic->is_en_supply == 1) { enable_wcd_codec_supply(swr_dmic, false); --swr_dmic->is_en_supply; } swr_dmic->nblock.notifier_call = swr_dmic_event_notify; wcd938x_swr_dmic_register_notifier(swr_dmic->supply_component, &swr_dmic->nblock, true); return 0; Loading @@ -624,7 +613,10 @@ static int swr_dmic_remove(struct swr_device *pdev) dev_err(&pdev->dev, "%s: swr_dmic is NULL\n", __func__); return -EINVAL; } if (swr_dmic->is_en_supply == 1) { enable_wcd_codec_supply(swr_dmic, false); --swr_dmic->is_en_supply; } snd_soc_unregister_component(&pdev->dev); swr_set_dev_data(pdev, NULL); return 0; Loading Loading @@ -743,7 +735,6 @@ static struct swr_driver swr_dmic_driver = { .probe = swr_dmic_probe, .remove = swr_dmic_remove, .id_table = swr_dmic_id, .device_down = swr_dmic_down, }; static int __init swr_dmic_init(void) Loading asoc/codecs/wcd938x/internal.h +3 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,9 @@ struct wcd938x_priv { bool dev_up; u8 tx_master_ch_map[WCD938X_MAX_SLAVE_CH_TYPES]; bool usbc_hs_status; /* wcd to swr dmic notification */ bool notify_swr_dmic; struct blocking_notifier_head notifier; }; struct wcd938x_micbias_setting { Loading asoc/codecs/wcd938x/wcd938x.c +46 −2 Original line number Diff line number Diff line Loading @@ -2033,6 +2033,27 @@ static bool get_usbc_hs_status(struct snd_soc_component *component, return false; } int wcd938x_swr_dmic_register_notifier(struct snd_soc_component *component, struct notifier_block *nblock, bool enable) { struct wcd938x_priv *wcd938x_priv; if(NULL == component) { pr_err("%s: wcd938x component is NULL\n", __func__); return -EINVAL; } wcd938x_priv = snd_soc_component_get_drvdata(component); wcd938x_priv->notify_swr_dmic = enable; if (enable) return blocking_notifier_chain_register(&wcd938x_priv->notifier, nblock); else return blocking_notifier_chain_unregister( &wcd938x_priv->notifier, nblock); } EXPORT_SYMBOL(wcd938x_swr_dmic_register_notifier); static int wcd938x_event_notify(struct notifier_block *block, unsigned long val, void *data) Loading Loading @@ -2080,6 +2101,10 @@ static int wcd938x_event_notify(struct notifier_block *block, break; case BOLERO_WCD_EVT_SSR_DOWN: wcd938x->dev_up = false; if(wcd938x->notify_swr_dmic) blocking_notifier_call_chain(&wcd938x->notifier, WCD938X_EVT_SSR_DOWN, NULL); wcd938x->mbhc->wcd_mbhc.deinit_in_progress = true; wcd938x->mbhc->wcd_mbhc.plug_before_ssr = wcd938x->mbhc->wcd_mbhc.current_plug; Loading Loading @@ -2113,6 +2138,10 @@ static int wcd938x_event_notify(struct notifier_block *block, } wcd938x->mbhc->wcd_mbhc.deinit_in_progress = false; wcd938x->dev_up = true; if(wcd938x->notify_swr_dmic) blocking_notifier_call_chain(&wcd938x->notifier, WCD938X_EVT_SSR_UP, NULL); break; case BOLERO_WCD_EVT_CLK_NOTIFY: snd_soc_component_update_bits(component, Loading Loading @@ -2296,6 +2325,9 @@ static int wcd938x_enable_micbias(struct wcd938x_priv *wcd938x, return -EINVAL; }; pr_debug("%s: req: %d micb_num: %d micb_ref: %d pullup_ref: %d\n", __func__, req, micb_num, wcd938x->micb_ref[micb_index], wcd938x->pullup_ref[micb_index]); mutex_lock(&wcd938x->micb_lock); switch (req) { Loading Loading @@ -2360,6 +2392,8 @@ int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *component, int event, int micb_num) { struct wcd938x_priv *wcd938x_priv = NULL; int ret = 0; int micb_index = micb_num - 1; if(NULL == component) { pr_err("%s: wcd938x component is NULL\n", __func__); Loading @@ -2376,6 +2410,15 @@ int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *component, wcd938x_priv = snd_soc_component_get_drvdata(component); if (!wcd938x_priv->dev_up) { if ((wcd938x_priv->pullup_ref[micb_index] > 0) && (event == SND_SOC_DAPM_POST_PMD)) { wcd938x_priv->pullup_ref[micb_index]--; ret = -ENODEV; goto done; } } switch (event) { case SND_SOC_DAPM_PRE_PMU: wcd938x_wakeup(wcd938x_priv, true); Loading @@ -2389,7 +2432,8 @@ int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *component, break; } return 0; done: return ret; } EXPORT_SYMBOL(wcd938x_codec_force_enable_micbias_v2); Loading Loading @@ -3728,7 +3772,6 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) return ret; } } wcd938x->dev_up = true; return ret; err_hwdep: Loading Loading @@ -4088,6 +4131,7 @@ static int wcd938x_bind(struct device *dev) __func__); goto err_irq; } wcd938x->dev_up = true; return ret; err_irq: Loading asoc/codecs/wcd938x/wcd938x.h +9 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,12 @@ enum { WCD9385 = 5, }; /* from WCD to SWR DMIC events */ enum { WCD938X_EVT_SSR_DOWN, WCD938X_EVT_SSR_UP, }; struct swr_slave_ch_map { u8 ch_type; u8 index; Loading Loading @@ -62,6 +68,9 @@ int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, int wcd938x_get_codec_variant(struct snd_soc_component *component); int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *wcd938x, int event, int micb_num); int wcd938x_swr_dmic_register_notifier(struct snd_soc_component *wcd938x, struct notifier_block *nblock, bool enable); static inline int wcd938x_slave_get_master_ch_val(int ch) { Loading Loading
asoc/codecs/swr-dmic.c +35 −44 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include "swr-dmic.h" #define NUM_ATTEMPTS 5 #define SWRS_SCP_CONTROL 0x44 static int swr_master_channel_map[] = { ZERO, Loading Loading @@ -66,6 +67,7 @@ struct swr_dmic_priv { int is_en_supply; int port_type; u8 tx_master_port_map[SWR_DMIC_MAX_PORTS]; struct notifier_block nblock; }; const char *codec_name_list[] = { Loading Loading @@ -245,38 +247,6 @@ static int dmic_swr_ctrl(struct snd_soc_dapm_widget *w, return ret; } static int swr_dmic_enable_supply(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct swr_dmic_priv *swr_dmic = snd_soc_component_get_drvdata(component); int ret = 0; dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: ret = swr_dmic_up(swr_dmic->swr_slave); break; case SND_SOC_DAPM_POST_PMU: ret = swr_dmic_reset(swr_dmic->swr_slave); break; case SND_SOC_DAPM_POST_PMD: ret = swr_dmic_down(swr_dmic->swr_slave); break; } if (ret) dev_dbg(component->dev, "%s wname: %s event: %d ret : %d\n", __func__, w->name, event, ret); 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", Loading Loading @@ -306,10 +276,6 @@ static const struct snd_soc_dapm_widget swr_dmic_dapm_widgets[] = { SND_SOC_DAPM_INPUT("SWR_DMIC"), SND_SOC_DAPM_SUPPLY_S("SMIC_SUPPLY", 1, SND_SOC_NOPM, 0, 0, swr_dmic_enable_supply, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_OUT_DRV_E("SMIC_PORT_EN", SND_SOC_NOPM, 0, 0, NULL, 0, swr_dmic_port_enable, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), Loading @@ -317,7 +283,6 @@ static const struct snd_soc_dapm_widget swr_dmic_dapm_widgets[] = { }; static const struct snd_soc_dapm_route swr_dmic_audio_map[] = { {"SWR_DMIC", NULL, "SMIC_SUPPLY"}, {"SWR_DMIC_MIXER", "Switch", "SWR_DMIC"}, {"SMIC_PORT_EN", NULL, "SWR_DMIC_MIXER"}, {"SWR_DMIC_OUTPUT", NULL, "SMIC_PORT_EN"}, Loading Loading @@ -393,6 +358,8 @@ static int enable_wcd_codec_supply(struct swr_dmic_priv *swr_dmic, bool enable) pr_err("%s: component is NULL\n", __func__); return -EINVAL; } dev_dbg(component->dev, "%s: supply %d micbias: %d enable: %d\n", __func__, swr_dmic->is_en_supply, micb_num, enable); if (enable) rc = wcd938x_codec_force_enable_micbias_v2(component, Loading Loading @@ -441,6 +408,29 @@ static struct snd_soc_dai_driver swr_dmic_dai[] = { }, }; static int swr_dmic_event_notify(struct notifier_block *block, unsigned long val, void *data) { u16 event = (val & 0xffff); int ret = 0; struct swr_dmic_priv *swr_dmic = container_of(block, struct swr_dmic_priv, nblock); switch (event) { case WCD938X_EVT_SSR_DOWN: ret = swr_dmic_down(swr_dmic->swr_slave); break; case WCD938X_EVT_SSR_UP: ret = swr_dmic_up(swr_dmic->swr_slave); if (!ret) ret = swr_dmic_reset(swr_dmic->swr_slave); break; } return ret; } static int swr_dmic_probe(struct swr_device *pdev) { int ret = 0; Loading Loading @@ -526,7 +516,7 @@ static int swr_dmic_probe(struct swr_device *pdev) "%s get devnum %d for dev addr %llx failed\n", __func__, swr_devnum, pdev->addr); ret = -EPROBE_DEFER; goto err; goto dev_err; } pdev->dev_num = swr_devnum; Loading Loading @@ -596,10 +586,9 @@ static int swr_dmic_probe(struct swr_device *pdev) strlen(swr_dmic_name_prefix_of) + 1); component->name_prefix = prefix_name; if (swr_dmic->is_en_supply == 1) { enable_wcd_codec_supply(swr_dmic, false); --swr_dmic->is_en_supply; } swr_dmic->nblock.notifier_call = swr_dmic_event_notify; wcd938x_swr_dmic_register_notifier(swr_dmic->supply_component, &swr_dmic->nblock, true); return 0; Loading @@ -624,7 +613,10 @@ static int swr_dmic_remove(struct swr_device *pdev) dev_err(&pdev->dev, "%s: swr_dmic is NULL\n", __func__); return -EINVAL; } if (swr_dmic->is_en_supply == 1) { enable_wcd_codec_supply(swr_dmic, false); --swr_dmic->is_en_supply; } snd_soc_unregister_component(&pdev->dev); swr_set_dev_data(pdev, NULL); return 0; Loading Loading @@ -743,7 +735,6 @@ static struct swr_driver swr_dmic_driver = { .probe = swr_dmic_probe, .remove = swr_dmic_remove, .id_table = swr_dmic_id, .device_down = swr_dmic_down, }; static int __init swr_dmic_init(void) Loading
asoc/codecs/wcd938x/internal.h +3 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,9 @@ struct wcd938x_priv { bool dev_up; u8 tx_master_ch_map[WCD938X_MAX_SLAVE_CH_TYPES]; bool usbc_hs_status; /* wcd to swr dmic notification */ bool notify_swr_dmic; struct blocking_notifier_head notifier; }; struct wcd938x_micbias_setting { Loading
asoc/codecs/wcd938x/wcd938x.c +46 −2 Original line number Diff line number Diff line Loading @@ -2033,6 +2033,27 @@ static bool get_usbc_hs_status(struct snd_soc_component *component, return false; } int wcd938x_swr_dmic_register_notifier(struct snd_soc_component *component, struct notifier_block *nblock, bool enable) { struct wcd938x_priv *wcd938x_priv; if(NULL == component) { pr_err("%s: wcd938x component is NULL\n", __func__); return -EINVAL; } wcd938x_priv = snd_soc_component_get_drvdata(component); wcd938x_priv->notify_swr_dmic = enable; if (enable) return blocking_notifier_chain_register(&wcd938x_priv->notifier, nblock); else return blocking_notifier_chain_unregister( &wcd938x_priv->notifier, nblock); } EXPORT_SYMBOL(wcd938x_swr_dmic_register_notifier); static int wcd938x_event_notify(struct notifier_block *block, unsigned long val, void *data) Loading Loading @@ -2080,6 +2101,10 @@ static int wcd938x_event_notify(struct notifier_block *block, break; case BOLERO_WCD_EVT_SSR_DOWN: wcd938x->dev_up = false; if(wcd938x->notify_swr_dmic) blocking_notifier_call_chain(&wcd938x->notifier, WCD938X_EVT_SSR_DOWN, NULL); wcd938x->mbhc->wcd_mbhc.deinit_in_progress = true; wcd938x->mbhc->wcd_mbhc.plug_before_ssr = wcd938x->mbhc->wcd_mbhc.current_plug; Loading Loading @@ -2113,6 +2138,10 @@ static int wcd938x_event_notify(struct notifier_block *block, } wcd938x->mbhc->wcd_mbhc.deinit_in_progress = false; wcd938x->dev_up = true; if(wcd938x->notify_swr_dmic) blocking_notifier_call_chain(&wcd938x->notifier, WCD938X_EVT_SSR_UP, NULL); break; case BOLERO_WCD_EVT_CLK_NOTIFY: snd_soc_component_update_bits(component, Loading Loading @@ -2296,6 +2325,9 @@ static int wcd938x_enable_micbias(struct wcd938x_priv *wcd938x, return -EINVAL; }; pr_debug("%s: req: %d micb_num: %d micb_ref: %d pullup_ref: %d\n", __func__, req, micb_num, wcd938x->micb_ref[micb_index], wcd938x->pullup_ref[micb_index]); mutex_lock(&wcd938x->micb_lock); switch (req) { Loading Loading @@ -2360,6 +2392,8 @@ int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *component, int event, int micb_num) { struct wcd938x_priv *wcd938x_priv = NULL; int ret = 0; int micb_index = micb_num - 1; if(NULL == component) { pr_err("%s: wcd938x component is NULL\n", __func__); Loading @@ -2376,6 +2410,15 @@ int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *component, wcd938x_priv = snd_soc_component_get_drvdata(component); if (!wcd938x_priv->dev_up) { if ((wcd938x_priv->pullup_ref[micb_index] > 0) && (event == SND_SOC_DAPM_POST_PMD)) { wcd938x_priv->pullup_ref[micb_index]--; ret = -ENODEV; goto done; } } switch (event) { case SND_SOC_DAPM_PRE_PMU: wcd938x_wakeup(wcd938x_priv, true); Loading @@ -2389,7 +2432,8 @@ int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *component, break; } return 0; done: return ret; } EXPORT_SYMBOL(wcd938x_codec_force_enable_micbias_v2); Loading Loading @@ -3728,7 +3772,6 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) return ret; } } wcd938x->dev_up = true; return ret; err_hwdep: Loading Loading @@ -4088,6 +4131,7 @@ static int wcd938x_bind(struct device *dev) __func__); goto err_irq; } wcd938x->dev_up = true; return ret; err_irq: Loading
asoc/codecs/wcd938x/wcd938x.h +9 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,12 @@ enum { WCD9385 = 5, }; /* from WCD to SWR DMIC events */ enum { WCD938X_EVT_SSR_DOWN, WCD938X_EVT_SSR_UP, }; struct swr_slave_ch_map { u8 ch_type; u8 index; Loading Loading @@ -62,6 +68,9 @@ int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, int wcd938x_get_codec_variant(struct snd_soc_component *component); int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *wcd938x, int event, int micb_num); int wcd938x_swr_dmic_register_notifier(struct snd_soc_component *wcd938x, struct notifier_block *nblock, bool enable); static inline int wcd938x_slave_get_master_ch_val(int ch) { Loading