Merge "asoc: bolero: Update dmic sample rate config for VA macro"

This commit is contained in:
Linux Build Service Account
2018-06-26 12:32:15 -07:00
committad av Gerrit - the friendly Code Review server
förälder eadfffe17a 135d405d2e
incheckning 7c20a7cc2e

Visa fil

@@ -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
@@ -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;
@@ -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;
@@ -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",
@@ -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:
@@ -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);
@@ -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;
@@ -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);
@@ -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) {