Loading asoc/codecs/bolero/va-macro.c +86 −5 Original line number Diff line number Diff line Loading @@ -39,7 +39,11 @@ #define CF_MIN_3DB_75HZ 0x1 #define CF_MIN_3DB_150HZ 0x2 #define VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0 #define VA_MACRO_MCLK_FREQ 9600000 #define VA_MACRO_TX_PATH_OFFSET 0x80 #define VA_MACRO_TX_DMIC_CLK_DIV_MASK 0x0E #define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01 #define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40 Loading @@ -66,6 +70,15 @@ enum { VA_MACRO_DEC_MAX, }; enum { VA_MACRO_CLK_DIV_2, VA_MACRO_CLK_DIV_3, VA_MACRO_CLK_DIV_4, VA_MACRO_CLK_DIV_6, VA_MACRO_CLK_DIV_8, VA_MACRO_CLK_DIV_16, }; struct va_mute_work { struct va_macro_priv *va_priv; u32 decimator; Loading Loading @@ -94,6 +107,7 @@ struct va_macro_priv { s32 dmic_2_3_clk_cnt; s32 dmic_4_5_clk_cnt; s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; u16 va_mclk_users; char __iomem *va_io_base; struct regulator *micb_supply; Loading Loading @@ -415,22 +429,22 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, case 0: case 1: dmic_clk_cnt = &(va_priv->dmic_0_1_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TX0_TX_PATH_CTL; 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_TX1_TX_PATH_CTL; 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_TX2_TX_PATH_CTL; 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_TX3_TX_PATH_CTL; dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; break; default: dev_err(va_dev, "%s: Invalid DMIC Selection\n", Loading @@ -446,6 +460,10 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, if (*dmic_clk_cnt == 1) { snd_soc_update_bits(codec, dmic_clk_reg, dmic_clk_en, dmic_clk_en); snd_soc_update_bits(codec, dmic_clk_reg, VA_MACRO_TX_DMIC_CLK_DIV_MASK, va_priv->dmic_clk_div << VA_MACRO_TX_DMIC_CLK_DIV_SHFT); } break; case SND_SOC_DAPM_POST_PMD: Loading Loading @@ -1255,6 +1273,56 @@ static const struct snd_kcontrol_new va_macro_snd_controls[] = { 0, -84, 40, digital_gain), }; static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate, struct va_macro_priv *va_priv) { u32 div_factor; u32 mclk_rate = VA_MACRO_MCLK_FREQ; if (dmic_sample_rate == VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED || mclk_rate % dmic_sample_rate != 0) goto undefined_rate; div_factor = mclk_rate / dmic_sample_rate; switch (div_factor) { case 2: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_2; break; case 3: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_3; break; case 4: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_4; break; case 6: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_6; break; case 8: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_8; break; case 16: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_16; break; default: /* Any other DIV factor is invalid */ goto undefined_rate; } /* Valid dmic DIV factors */ dev_dbg(va_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n", __func__, div_factor, mclk_rate); return dmic_sample_rate; undefined_rate: dev_dbg(va_priv->dev, "%s: Invalid rate %d, for mclk %d\n", __func__, dmic_sample_rate, mclk_rate); dmic_sample_rate = VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED; return dmic_sample_rate; } static int va_macro_init(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); Loading Loading @@ -1355,7 +1423,7 @@ static int va_macro_probe(struct platform_device *pdev) { struct macro_ops ops; struct va_macro_priv *va_priv; u32 va_base_addr; u32 va_base_addr, sample_rate = 0; char __iomem *va_io_base; struct clk *va_core_clk; bool va_without_decimation = false; Loading @@ -1363,6 +1431,7 @@ static int va_macro_probe(struct platform_device *pdev) const char *micb_voltage_str = "qcom,va-vdd-micb-voltage"; const char *micb_current_str = "qcom,va-vdd-micb-current"; int ret = 0; const char *dmic_sample_rate = "qcom,va-dmic-sample-rate"; va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv), GFP_KERNEL); Loading @@ -1381,6 +1450,18 @@ static int va_macro_probe(struct platform_device *pdev) "qcom,va-without-decimation"); va_priv->va_without_decimation = va_without_decimation; ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate, &sample_rate); if (ret) { dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", __func__, sample_rate); va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_2; } else { if (va_macro_validate_dmic_sample_rate( sample_rate, va_priv) == VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED) return -EINVAL; } va_io_base = devm_ioremap(&pdev->dev, va_base_addr, VA_MAX_OFFSET); if (!va_io_base) { Loading Loading
asoc/codecs/bolero/va-macro.c +86 −5 Original line number Diff line number Diff line Loading @@ -39,7 +39,11 @@ #define CF_MIN_3DB_75HZ 0x1 #define CF_MIN_3DB_150HZ 0x2 #define VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0 #define VA_MACRO_MCLK_FREQ 9600000 #define VA_MACRO_TX_PATH_OFFSET 0x80 #define VA_MACRO_TX_DMIC_CLK_DIV_MASK 0x0E #define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01 #define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40 Loading @@ -66,6 +70,15 @@ enum { VA_MACRO_DEC_MAX, }; enum { VA_MACRO_CLK_DIV_2, VA_MACRO_CLK_DIV_3, VA_MACRO_CLK_DIV_4, VA_MACRO_CLK_DIV_6, VA_MACRO_CLK_DIV_8, VA_MACRO_CLK_DIV_16, }; struct va_mute_work { struct va_macro_priv *va_priv; u32 decimator; Loading Loading @@ -94,6 +107,7 @@ struct va_macro_priv { s32 dmic_2_3_clk_cnt; s32 dmic_4_5_clk_cnt; s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; u16 va_mclk_users; char __iomem *va_io_base; struct regulator *micb_supply; Loading Loading @@ -415,22 +429,22 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, case 0: case 1: dmic_clk_cnt = &(va_priv->dmic_0_1_clk_cnt); dmic_clk_reg = BOLERO_CDC_VA_TX0_TX_PATH_CTL; 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_TX1_TX_PATH_CTL; 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_TX2_TX_PATH_CTL; 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_TX3_TX_PATH_CTL; dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; break; default: dev_err(va_dev, "%s: Invalid DMIC Selection\n", Loading @@ -446,6 +460,10 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, if (*dmic_clk_cnt == 1) { snd_soc_update_bits(codec, dmic_clk_reg, dmic_clk_en, dmic_clk_en); snd_soc_update_bits(codec, dmic_clk_reg, VA_MACRO_TX_DMIC_CLK_DIV_MASK, va_priv->dmic_clk_div << VA_MACRO_TX_DMIC_CLK_DIV_SHFT); } break; case SND_SOC_DAPM_POST_PMD: Loading Loading @@ -1255,6 +1273,56 @@ static const struct snd_kcontrol_new va_macro_snd_controls[] = { 0, -84, 40, digital_gain), }; static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate, struct va_macro_priv *va_priv) { u32 div_factor; u32 mclk_rate = VA_MACRO_MCLK_FREQ; if (dmic_sample_rate == VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED || mclk_rate % dmic_sample_rate != 0) goto undefined_rate; div_factor = mclk_rate / dmic_sample_rate; switch (div_factor) { case 2: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_2; break; case 3: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_3; break; case 4: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_4; break; case 6: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_6; break; case 8: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_8; break; case 16: va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_16; break; default: /* Any other DIV factor is invalid */ goto undefined_rate; } /* Valid dmic DIV factors */ dev_dbg(va_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n", __func__, div_factor, mclk_rate); return dmic_sample_rate; undefined_rate: dev_dbg(va_priv->dev, "%s: Invalid rate %d, for mclk %d\n", __func__, dmic_sample_rate, mclk_rate); dmic_sample_rate = VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED; return dmic_sample_rate; } static int va_macro_init(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); Loading Loading @@ -1355,7 +1423,7 @@ static int va_macro_probe(struct platform_device *pdev) { struct macro_ops ops; struct va_macro_priv *va_priv; u32 va_base_addr; u32 va_base_addr, sample_rate = 0; char __iomem *va_io_base; struct clk *va_core_clk; bool va_without_decimation = false; Loading @@ -1363,6 +1431,7 @@ static int va_macro_probe(struct platform_device *pdev) const char *micb_voltage_str = "qcom,va-vdd-micb-voltage"; const char *micb_current_str = "qcom,va-vdd-micb-current"; int ret = 0; const char *dmic_sample_rate = "qcom,va-dmic-sample-rate"; va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv), GFP_KERNEL); Loading @@ -1381,6 +1450,18 @@ static int va_macro_probe(struct platform_device *pdev) "qcom,va-without-decimation"); va_priv->va_without_decimation = va_without_decimation; ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate, &sample_rate); if (ret) { dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", __func__, sample_rate); va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_2; } else { if (va_macro_validate_dmic_sample_rate( sample_rate, va_priv) == VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED) return -EINVAL; } va_io_base = devm_ioremap(&pdev->dev, va_base_addr, VA_MAX_OFFSET); if (!va_io_base) { Loading