Loading asoc/codecs/wcd938x/internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,8 @@ #include <asoc/wcd-clsh.h> #include "wcd938x-mbhc.h" #define SWR_SCP_CONTROL 0x44 #define SWR_SCP_HOST_CLK_DIV2_CTL_BANK 0xE0 #define WCD938X_MAX_MICBIAS 4 /* Convert from vout ctl to micbias voltage in mV */ Loading asoc/codecs/wcd938x/wcd938x.c +56 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "wcd938x-registers.h" #include "wcd938x.h" #define WCD938X_DRV_NAME "wcd938x_codec" #define NUM_SWRS_DT_PARAMS 5 #define WCD938X_VARIANT_ENTRY_SIZE 32 Loading Loading @@ -126,6 +127,45 @@ static int wcd938x_handle_post_irq(void *data) return IRQ_HANDLED; } static int wcd938x_swr_slv_get_current_bank(struct swr_device *dev, u8 devnum) { int ret = 0; int bank = 0; ret = swr_read(dev, devnum, SWR_SCP_CONTROL, &bank, 1); if (ret) return -EINVAL; return ((bank & 0x40) ? 1: 0); } static int wcd938x_swr_slv_set_host_clk_div2(struct swr_device *dev, u8 devnum, int bank) { u8 val = (bank ? 1 : 0); return (swr_write(dev, devnum, (SWR_SCP_HOST_CLK_DIV2_CTL_BANK + (0x10 * bank)), &val)); } static int wcd938x_set_swr_clk_rate(struct snd_soc_component *component, int mode, int bank) { u8 mask = (bank ? 0xF0 : 0x0F); u8 val = 0; if ((mode == ADC_MODE_ULP1) || (mode == ADC_MODE_ULP2)) val = (bank ? 0x60 : 0x06); else val = 0x00; snd_soc_component_update_bits(component, WCD938X_DIGITAL_SWR_TX_CLK_RATE, mask, val); return 0; } static int wcd938x_init_reg(struct snd_soc_component *component) { snd_soc_component_update_bits(component, WCD938X_SLEEP_CTL, 0x0E, 0x0E); Loading Loading @@ -1335,17 +1375,33 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, snd_soc_dapm_to_component(w->dapm); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); int ret = 0; int bank = 0; int mode = 0; bank = wcd938x_swr_slv_get_current_bank(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num); wcd938x_swr_slv_set_host_clk_div2(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num, bank); switch (event) { case SND_SOC_DAPM_PRE_PMU: ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num, true); if (test_bit(WCD_ADC1, &wcd938x->status_mask)) mode |= wcd938x->tx_mode[WCD_ADC1]; if (test_bit(WCD_ADC2, &wcd938x->status_mask)) mode |= wcd938x->tx_mode[WCD_ADC2]; if (test_bit(WCD_ADC3, &wcd938x->status_mask)) mode |= wcd938x->tx_mode[WCD_ADC3]; if (test_bit(WCD_ADC4, &wcd938x->status_mask)) mode |= wcd938x->tx_mode[WCD_ADC4]; wcd938x_set_swr_clk_rate(component, mode, bank); break; case SND_SOC_DAPM_POST_PMD: ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num, false); wcd938x_set_swr_clk_rate(component, ADC_MODE_INVALID, bank); break; }; Loading Loading
asoc/codecs/wcd938x/internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,8 @@ #include <asoc/wcd-clsh.h> #include "wcd938x-mbhc.h" #define SWR_SCP_CONTROL 0x44 #define SWR_SCP_HOST_CLK_DIV2_CTL_BANK 0xE0 #define WCD938X_MAX_MICBIAS 4 /* Convert from vout ctl to micbias voltage in mV */ Loading
asoc/codecs/wcd938x/wcd938x.c +56 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "wcd938x-registers.h" #include "wcd938x.h" #define WCD938X_DRV_NAME "wcd938x_codec" #define NUM_SWRS_DT_PARAMS 5 #define WCD938X_VARIANT_ENTRY_SIZE 32 Loading Loading @@ -126,6 +127,45 @@ static int wcd938x_handle_post_irq(void *data) return IRQ_HANDLED; } static int wcd938x_swr_slv_get_current_bank(struct swr_device *dev, u8 devnum) { int ret = 0; int bank = 0; ret = swr_read(dev, devnum, SWR_SCP_CONTROL, &bank, 1); if (ret) return -EINVAL; return ((bank & 0x40) ? 1: 0); } static int wcd938x_swr_slv_set_host_clk_div2(struct swr_device *dev, u8 devnum, int bank) { u8 val = (bank ? 1 : 0); return (swr_write(dev, devnum, (SWR_SCP_HOST_CLK_DIV2_CTL_BANK + (0x10 * bank)), &val)); } static int wcd938x_set_swr_clk_rate(struct snd_soc_component *component, int mode, int bank) { u8 mask = (bank ? 0xF0 : 0x0F); u8 val = 0; if ((mode == ADC_MODE_ULP1) || (mode == ADC_MODE_ULP2)) val = (bank ? 0x60 : 0x06); else val = 0x00; snd_soc_component_update_bits(component, WCD938X_DIGITAL_SWR_TX_CLK_RATE, mask, val); return 0; } static int wcd938x_init_reg(struct snd_soc_component *component) { snd_soc_component_update_bits(component, WCD938X_SLEEP_CTL, 0x0E, 0x0E); Loading Loading @@ -1335,17 +1375,33 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, snd_soc_dapm_to_component(w->dapm); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); int ret = 0; int bank = 0; int mode = 0; bank = wcd938x_swr_slv_get_current_bank(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num); wcd938x_swr_slv_set_host_clk_div2(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num, bank); switch (event) { case SND_SOC_DAPM_PRE_PMU: ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num, true); if (test_bit(WCD_ADC1, &wcd938x->status_mask)) mode |= wcd938x->tx_mode[WCD_ADC1]; if (test_bit(WCD_ADC2, &wcd938x->status_mask)) mode |= wcd938x->tx_mode[WCD_ADC2]; if (test_bit(WCD_ADC3, &wcd938x->status_mask)) mode |= wcd938x->tx_mode[WCD_ADC3]; if (test_bit(WCD_ADC4, &wcd938x->status_mask)) mode |= wcd938x->tx_mode[WCD_ADC4]; wcd938x_set_swr_clk_rate(component, mode, bank); break; case SND_SOC_DAPM_POST_PMD: ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num, false); wcd938x_set_swr_clk_rate(component, ADC_MODE_INVALID, bank); break; }; Loading