diff options
Diffstat (limited to '')
-rw-r--r-- | sound/soc/codecs/max98088.c | 114 |
1 files changed, 62 insertions, 52 deletions
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index f031d2caa8b7..405ec16be2b6 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -41,6 +41,7 @@ struct max98088_priv { enum max98088_type devtype; struct max98088_pdata *pdata; struct clk *mclk; + unsigned char mclk_prescaler; unsigned int sysclk; struct max98088_cdata dai[2]; int eq_textcnt; @@ -473,6 +474,9 @@ static const struct snd_kcontrol_new max98088_snd_controls[] = { max98088_mic2pre_get, max98088_mic2pre_set, max98088_micboost_tlv), + SOC_SINGLE("Noise Gate Threshold", M98088_REG_40_MICAGC_THRESH, + 4, 15, 0), + SOC_SINGLE("INA Volume", M98088_REG_37_LVL_INA, 0, 7, 1), SOC_SINGLE("INB Volume", M98088_REG_38_LVL_INB, 0, 7, 1), @@ -996,15 +1000,18 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream, cdata->rate = rate; /* Configure NI when operating as master */ - if (snd_soc_component_read32(component, M98088_REG_14_DAI1_FORMAT) + if (snd_soc_component_read(component, M98088_REG_14_DAI1_FORMAT) & M98088_DAI_MAS) { + unsigned long pclk; + if (max98088->sysclk == 0) { dev_err(component->dev, "Invalid system clock frequency\n"); return -EINVAL; } ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL) * (unsigned long long int)rate; - do_div(ni, (unsigned long long int)max98088->sysclk); + pclk = DIV_ROUND_CLOSEST(max98088->sysclk, max98088->mclk_prescaler); + ni = DIV_ROUND_CLOSEST_ULL(ni, pclk); snd_soc_component_write(component, M98088_REG_12_DAI1_CLKCFG_HI, (ni >> 8) & 0x7F); snd_soc_component_write(component, M98088_REG_13_DAI1_CLKCFG_LO, @@ -1063,15 +1070,18 @@ static int max98088_dai2_hw_params(struct snd_pcm_substream *substream, cdata->rate = rate; /* Configure NI when operating as master */ - if (snd_soc_component_read32(component, M98088_REG_1C_DAI2_FORMAT) + if (snd_soc_component_read(component, M98088_REG_1C_DAI2_FORMAT) & M98088_DAI_MAS) { + unsigned long pclk; + if (max98088->sysclk == 0) { dev_err(component->dev, "Invalid system clock frequency\n"); return -EINVAL; } ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL) * (unsigned long long int)rate; - do_div(ni, (unsigned long long int)max98088->sysclk); + pclk = DIV_ROUND_CLOSEST(max98088->sysclk, max98088->mclk_prescaler); + ni = DIV_ROUND_CLOSEST_ULL(ni, pclk); snd_soc_component_write(component, M98088_REG_1A_DAI2_CLKCFG_HI, (ni >> 8) & 0x7F); snd_soc_component_write(component, M98088_REG_1B_DAI2_CLKCFG_LO, @@ -1113,14 +1123,16 @@ static int max98088_dai_set_sysclk(struct snd_soc_dai *dai, */ if ((freq >= 10000000) && (freq < 20000000)) { snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x10); + max98088->mclk_prescaler = 1; } else if ((freq >= 20000000) && (freq < 30000000)) { snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x20); + max98088->mclk_prescaler = 2; } else { dev_err(component->dev, "Invalid master clock frequency\n"); return -EINVAL; } - if (snd_soc_component_read32(component, M98088_REG_51_PWR_SYS) & M98088_SHDNRUN) { + if (snd_soc_component_read(component, M98088_REG_51_PWR_SYS) & M98088_SHDNRUN) { snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0); snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, @@ -1147,20 +1159,18 @@ static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai, if (fmt != cdata->fmt) { cdata->fmt = fmt; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - /* Slave mode PLL */ + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: + /* Consumer mode PLL */ snd_soc_component_write(component, M98088_REG_12_DAI1_CLKCFG_HI, 0x80); snd_soc_component_write(component, M98088_REG_13_DAI1_CLKCFG_LO, 0x00); break; - case SND_SOC_DAIFMT_CBM_CFM: - /* Set to master mode */ + case SND_SOC_DAIFMT_CBP_CFP: + /* Set to provider mode */ reg14val |= M98088_DAI_MAS; break; - case SND_SOC_DAIFMT_CBS_CFM: - case SND_SOC_DAIFMT_CBM_CFS: default: dev_err(component->dev, "Clock mode unsupported"); return -EINVAL; @@ -1218,20 +1228,18 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai, if (fmt != cdata->fmt) { cdata->fmt = fmt; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - /* Slave mode PLL */ + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: + /* Consumer mode PLL */ snd_soc_component_write(component, M98088_REG_1A_DAI2_CLKCFG_HI, 0x80); snd_soc_component_write(component, M98088_REG_1B_DAI2_CLKCFG_LO, 0x00); break; - case SND_SOC_DAIFMT_CBM_CFM: - /* Set to master mode */ + case SND_SOC_DAIFMT_CBP_CFP: + /* Set to provider mode */ reg1Cval |= M98088_DAI_MAS; break; - case SND_SOC_DAIFMT_CBS_CFM: - case SND_SOC_DAIFMT_CBM_CFS: default: dev_err(component->dev, "Clock mode unsupported"); return -EINVAL; @@ -1274,7 +1282,8 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai, return 0; } -static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute) +static int max98088_dai1_mute(struct snd_soc_dai *codec_dai, int mute, + int direction) { struct snd_soc_component *component = codec_dai->component; int reg; @@ -1289,7 +1298,8 @@ static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute) return 0; } -static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute) +static int max98088_dai2_mute(struct snd_soc_dai *codec_dai, int mute, + int direction) { struct snd_soc_component *component = codec_dai->component; int reg; @@ -1354,14 +1364,16 @@ static const struct snd_soc_dai_ops max98088_dai1_ops = { .set_sysclk = max98088_dai_set_sysclk, .set_fmt = max98088_dai1_set_fmt, .hw_params = max98088_dai1_hw_params, - .digital_mute = max98088_dai1_digital_mute, + .mute_stream = max98088_dai1_mute, + .no_capture_mute = 1, }; static const struct snd_soc_dai_ops max98088_dai2_ops = { .set_sysclk = max98088_dai_set_sysclk, .set_fmt = max98088_dai2_set_fmt, .hw_params = max98088_dai2_hw_params, - .digital_mute = max98088_dai2_digital_mute, + .mute_stream = max98088_dai2_mute, + .no_capture_mute = 1, }; static struct snd_soc_dai_driver max98088_dai[] = { @@ -1440,7 +1452,7 @@ static void max98088_setup_eq1(struct snd_soc_component *component) pdata->eq_cfg[best].rate, fs); /* Disable EQ while configuring, and save current on/off state */ - save = snd_soc_component_read32(component, M98088_REG_49_CFG_LEVEL); + save = snd_soc_component_read(component, M98088_REG_49_CFG_LEVEL); snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, 0); coef_set = &pdata->eq_cfg[sel]; @@ -1487,7 +1499,7 @@ static void max98088_setup_eq2(struct snd_soc_component *component) pdata->eq_cfg[best].rate, fs); /* Disable EQ while configuring, and save current on/off state */ - save = snd_soc_component_read32(component, M98088_REG_49_CFG_LEVEL); + save = snd_soc_component_read(component, M98088_REG_49_CFG_LEVEL); snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN, 0); coef_set = &pdata->eq_cfg[sel]; @@ -1673,7 +1685,7 @@ static int max98088_probe(struct snd_soc_component *component) max98088->mic1pre = 0; max98088->mic2pre = 0; - ret = snd_soc_component_read32(component, M98088_REG_FF_REV_ID); + ret = snd_soc_component_read(component, M98088_REG_FF_REV_ID); if (ret < 0) { dev_err(component->dev, "Failed to read device revision: %d\n", ret); @@ -1725,46 +1737,44 @@ static const struct snd_soc_component_driver soc_component_dev_max98088 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; -static int max98088_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id max98088_i2c_id[] = { + { "max98088", MAX98088 }, + { "max98089", MAX98089 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); + +static int max98088_i2c_probe(struct i2c_client *i2c) { - struct max98088_priv *max98088; - int ret; + struct max98088_priv *max98088; + const struct i2c_device_id *id; - max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv), - GFP_KERNEL); - if (max98088 == NULL) - return -ENOMEM; + max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv), + GFP_KERNEL); + if (max98088 == NULL) + return -ENOMEM; - max98088->regmap = devm_regmap_init_i2c(i2c, &max98088_regmap); - if (IS_ERR(max98088->regmap)) - return PTR_ERR(max98088->regmap); + max98088->regmap = devm_regmap_init_i2c(i2c, &max98088_regmap); + if (IS_ERR(max98088->regmap)) + return PTR_ERR(max98088->regmap); max98088->mclk = devm_clk_get(&i2c->dev, "mclk"); if (IS_ERR(max98088->mclk)) if (PTR_ERR(max98088->mclk) == -EPROBE_DEFER) return PTR_ERR(max98088->mclk); - max98088->devtype = id->driver_data; + id = i2c_match_id(max98088_i2c_id, i2c); + max98088->devtype = id->driver_data; - i2c_set_clientdata(i2c, max98088); - max98088->pdata = i2c->dev.platform_data; + i2c_set_clientdata(i2c, max98088); + max98088->pdata = i2c->dev.platform_data; - ret = devm_snd_soc_register_component(&i2c->dev, - &soc_component_dev_max98088, &max98088_dai[0], 2); - return ret; + return devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_max98088, + &max98088_dai[0], 2); } -static const struct i2c_device_id max98088_i2c_id[] = { - { "max98088", MAX98088 }, - { "max98089", MAX98089 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); - #if defined(CONFIG_OF) static const struct of_device_id max98088_of_match[] = { { .compatible = "maxim,max98088" }, @@ -1779,7 +1789,7 @@ static struct i2c_driver max98088_i2c_driver = { .name = "max98088", .of_match_table = of_match_ptr(max98088_of_match), }, - .probe = max98088_i2c_probe, + .probe_new = max98088_i2c_probe, .id_table = max98088_i2c_id, }; |