summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c13
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c20
-rw-r--r--sound/soc/cirrus/Kconfig2
-rw-r--r--sound/soc/codecs/arizona.c254
-rw-r--r--sound/soc/codecs/cs4271.c63
-rw-r--r--sound/soc/codecs/cs42l51.c71
-rw-r--r--sound/soc/codecs/cs42l52.c92
-rw-r--r--sound/soc/codecs/cs42l73.c55
-rw-r--r--sound/soc/codecs/da7210.c20
-rw-r--r--sound/soc/codecs/wm5102.c28
-rw-r--r--sound/soc/codecs/wm5110.c19
-rw-r--r--sound/soc/codecs/wm8997.c25
-rw-r--r--sound/soc/codecs/wm_adsp.c50
13 files changed, 408 insertions, 304 deletions
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 1ead3c977a51..de433cfd044c 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -341,6 +341,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
{
int id = dai->id;
struct atmel_ssc_info *ssc_p = &ssc_info[id];
+ struct ssc_device *ssc = ssc_p->ssc;
struct atmel_pcm_dma_params *dma_params;
int dir, channels, bits;
u32 tfmr, rfmr, tcmr, rcmr;
@@ -466,7 +467,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
| SSC_BF(RCMR_START, start_event)
| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
+ | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
+ SSC_CKS_PIN : SSC_CKS_CLOCK);
rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
| SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
@@ -481,7 +483,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
| SSC_BF(TCMR_START, start_event)
| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
| SSC_BF(TCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
+ | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
+ SSC_CKS_CLOCK : SSC_CKS_PIN);
tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
| SSC_BF(TFMR_FSDEN, 0)
@@ -550,7 +553,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
| SSC_BF(RCMR_START, SSC_START_RISING_RF)
| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(RCMR_CKS, SSC_CKS_PIN);
+ | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
+ SSC_CKS_PIN : SSC_CKS_CLOCK);
rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
| SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
@@ -565,7 +569,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
| SSC_BF(TCMR_START, SSC_START_RISING_RF)
| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
| SSC_BF(TCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
+ | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
+ SSC_CKS_CLOCK : SSC_CKS_PIN);
tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
| SSC_BF(TFMR_FSDEN, 0)
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index f15bff1548f8..174bd546c08b 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -155,25 +155,14 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
- /* Add specific widgets */
- snd_soc_dapm_new_controls(dapm, at91sam9g20ek_dapm_widgets,
- ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
- /* Set up specific audio path interconnects */
- snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
-
/* not connected */
snd_soc_dapm_nc_pin(dapm, "RLINEIN");
snd_soc_dapm_nc_pin(dapm, "LLINEIN");
-#ifdef ENABLE_MIC_INPUT
- snd_soc_dapm_enable_pin(dapm, "Int Mic");
-#else
- snd_soc_dapm_nc_pin(dapm, "Int Mic");
+#ifndef ENABLE_MIC_INPUT
+ snd_soc_dapm_nc_pin(&rtd->card->dapm, "Int Mic");
#endif
- /* always connected */
- snd_soc_dapm_enable_pin(dapm, "Ext Spk");
-
return 0;
}
@@ -194,6 +183,11 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = {
.dai_link = &at91sam9g20ek_dai,
.num_links = 1,
.set_bias_level = at91sam9g20ek_set_bias_level,
+
+ .dapm_widgets = at91sam9g20ek_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(at91sam9g20ek_dapm_widgets),
+ .dapm_routes = intercon,
+ .num_dapm_routes = ARRAY_SIZE(intercon),
};
static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
diff --git a/sound/soc/cirrus/Kconfig b/sound/soc/cirrus/Kconfig
index 06f938deda15..c872dacbab98 100644
--- a/sound/soc/cirrus/Kconfig
+++ b/sound/soc/cirrus/Kconfig
@@ -1,6 +1,6 @@
config SND_EP93XX_SOC
tristate "SoC Audio support for the Cirrus Logic EP93xx series"
- depends on (ARCH_EP93XX || COMPILE_TEST) && SND_SOC
+ depends on ARCH_EP93XX || COMPILE_TEST
select SND_SOC_GENERIC_DMAENGINE_PCM
help
Say Y or M if you want to add support for codecs attached to
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index a32b84ac03f6..29e198f57d4c 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -53,6 +53,14 @@
#define ARIZONA_AIF_RX_ENABLES 0x1A
#define ARIZONA_AIF_FORCE_WRITE 0x1B
+#define ARIZONA_FLL_VCO_CORNER 141900000
+#define ARIZONA_FLL_MAX_FREF 13500000
+#define ARIZONA_FLL_MIN_FVCO 90000000
+#define ARIZONA_FLL_MAX_FRATIO 16
+#define ARIZONA_FLL_MAX_REFDIV 8
+#define ARIZONA_FLL_MIN_OUTDIV 2
+#define ARIZONA_FLL_MAX_OUTDIV 7
+
#define arizona_fll_err(_fll, fmt, ...) \
dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
#define arizona_fll_warn(_fll, fmt, ...) \
@@ -1386,74 +1394,147 @@ struct arizona_fll_cfg {
int gain;
};
-static int arizona_calc_fll(struct arizona_fll *fll,
- struct arizona_fll_cfg *cfg,
- unsigned int Fref,
- unsigned int Fout)
+static int arizona_validate_fll(struct arizona_fll *fll,
+ unsigned int Fref,
+ unsigned int Fout)
{
- unsigned int target, div, gcd_fll;
- int i, ratio;
+ unsigned int Fvco_min;
+
+ if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
+ arizona_fll_err(fll,
+ "Can't scale %dMHz in to <=13.5MHz\n",
+ Fref);
+ return -EINVAL;
+ }
- arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
+ Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
+ if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
+ arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
+ Fout);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int arizona_find_fratio(unsigned int Fref, int *fratio)
+{
+ int i;
+
+ /* Find an appropriate FLL_FRATIO */
+ for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
+ if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
+ if (fratio)
+ *fratio = fll_fratios[i].fratio;
+ return fll_fratios[i].ratio;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int arizona_calc_fratio(struct arizona_fll *fll,
+ struct arizona_fll_cfg *cfg,
+ unsigned int target,
+ unsigned int Fref, bool sync)
+{
+ int init_ratio, ratio;
+ int refdiv, div;
- /* Fref must be <=13.5MHz */
+ /* Fref must be <=13.5MHz, find initial refdiv */
div = 1;
cfg->refdiv = 0;
- while ((Fref / div) > 13500000) {
+ while (Fref > ARIZONA_FLL_MAX_FREF) {
div *= 2;
+ Fref /= 2;
cfg->refdiv++;
- if (div > 8) {
- arizona_fll_err(fll,
- "Can't scale %dMHz in to <=13.5MHz\n",
- Fref);
+ if (div > ARIZONA_FLL_MAX_REFDIV)
return -EINVAL;
+ }
+
+ /* Find an appropriate FLL_FRATIO */
+ init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
+ if (init_ratio < 0) {
+ arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
+ Fref);
+ return init_ratio;
+ }
+
+ switch (fll->arizona->type) {
+ case WM5110:
+ if (fll->arizona->rev < 3 || sync)
+ return init_ratio;
+ break;
+ default:
+ return init_ratio;
+ }
+
+ cfg->fratio = init_ratio - 1;
+
+ /* Adjust FRATIO/refdiv to avoid integer mode if possible */
+ refdiv = cfg->refdiv;
+
+ while (div <= ARIZONA_FLL_MAX_REFDIV) {
+ for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO;
+ ratio++) {
+ if (target % (ratio * Fref)) {
+ cfg->refdiv = refdiv;
+ cfg->fratio = ratio - 1;
+ return ratio;
+ }
}
+
+ for (ratio = init_ratio - 1; ratio >= 0; ratio--) {
+ if (ARIZONA_FLL_VCO_CORNER / (fll->vco_mult * ratio) <
+ Fref)
+ break;
+
+ if (target % (ratio * Fref)) {
+ cfg->refdiv = refdiv;
+ cfg->fratio = ratio - 1;
+ return ratio;
+ }
+ }
+
+ div *= 2;
+ Fref /= 2;
+ refdiv++;
+ init_ratio = arizona_find_fratio(Fref, NULL);
}
- /* Apply the division for our remaining calculations */
- Fref /= div;
+ arizona_fll_warn(fll, "Falling back to integer mode operation\n");
+ return cfg->fratio + 1;
+}
+
+static int arizona_calc_fll(struct arizona_fll *fll,
+ struct arizona_fll_cfg *cfg,
+ unsigned int Fref, bool sync)
+{
+ unsigned int target, div, gcd_fll;
+ int i, ratio;
+
+ arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
/* Fvco should be over the targt; don't check the upper bound */
- div = 1;
- while (Fout * div < 90000000 * fll->vco_mult) {
+ div = ARIZONA_FLL_MIN_OUTDIV;
+ while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
div++;
- if (div > 7) {
- arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
- Fout);
+ if (div > ARIZONA_FLL_MAX_OUTDIV)
return -EINVAL;
- }
}
- target = Fout * div / fll->vco_mult;
+ target = fll->fout * div / fll->vco_mult;
cfg->outdiv = div;
arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
- /* Find an appropraite FLL_FRATIO and factor it out of the target */
- for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
- if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
- cfg->fratio = fll_fratios[i].fratio;
- ratio = fll_fratios[i].ratio;
- break;
- }
- }
- if (i == ARRAY_SIZE(fll_fratios)) {
- arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
- Fref);
- return -EINVAL;
- }
+ /* Find an appropriate FLL_FRATIO and refdiv */
+ ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
+ if (ratio < 0)
+ return ratio;
- for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
- if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
- cfg->gain = fll_gains[i].gain;
- break;
- }
- }
- if (i == ARRAY_SIZE(fll_gains)) {
- arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
- Fref);
- return -EINVAL;
- }
+ /* Apply the division for our remaining calculations */
+ Fref = Fref / (1 << cfg->refdiv);
cfg->n = target / (ratio * Fref);
@@ -1478,6 +1559,18 @@ static int arizona_calc_fll(struct arizona_fll *fll,
cfg->lambda >>= 1;
}
+ for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
+ if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
+ cfg->gain = fll_gains[i].gain;
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(fll_gains)) {
+ arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
+ Fref);
+ return -EINVAL;
+ }
+
arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
cfg->n, cfg->theta, cfg->lambda);
arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
@@ -1505,14 +1598,18 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
- if (sync)
- regmap_update_bits_async(arizona->regmap, base + 0x7,
- ARIZONA_FLL1_GAIN_MASK,
- cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
- else
- regmap_update_bits_async(arizona->regmap, base + 0x9,
- ARIZONA_FLL1_GAIN_MASK,
- cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
+ if (sync) {
+ regmap_update_bits(arizona->regmap, base + 0x7,
+ ARIZONA_FLL1_GAIN_MASK,
+ cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
+ } else {
+ regmap_update_bits(arizona->regmap, base + 0x5,
+ ARIZONA_FLL1_OUTDIV_MASK,
+ cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
+ regmap_update_bits(arizona->regmap, base + 0x9,
+ ARIZONA_FLL1_GAIN_MASK,
+ cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
+ }
regmap_update_bits_async(arizona->regmap, base + 2,
ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
@@ -1535,13 +1632,12 @@ static bool arizona_is_enabled_fll(struct arizona_fll *fll)
return reg & ARIZONA_FLL1_ENA;
}
-static void arizona_enable_fll(struct arizona_fll *fll,
- struct arizona_fll_cfg *ref,
- struct arizona_fll_cfg *sync)
+static void arizona_enable_fll(struct arizona_fll *fll)
{
struct arizona *arizona = fll->arizona;
int ret;
bool use_sync = false;
+ struct arizona_fll_cfg cfg;
/*
* If we have both REFCLK and SYNCCLK then enable both,
@@ -1549,23 +1645,21 @@ static void arizona_enable_fll(struct arizona_fll *fll,
*/
if (fll->ref_src >= 0 && fll->ref_freq &&
fll->ref_src != fll->sync_src) {
- regmap_update_bits_async(arizona->regmap, fll->base + 5,
- ARIZONA_FLL1_OUTDIV_MASK,
- ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
+ arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
- arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
+ arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
false);
if (fll->sync_src >= 0) {
- arizona_apply_fll(arizona, fll->base + 0x10, sync,
+ arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
+
+ arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
fll->sync_src, true);
use_sync = true;
}
} else if (fll->sync_src >= 0) {
- regmap_update_bits_async(arizona->regmap, fll->base + 5,
- ARIZONA_FLL1_OUTDIV_MASK,
- sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
+ arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
- arizona_apply_fll(arizona, fll->base, sync,
+ arizona_apply_fll(arizona, fll->base, &cfg,
fll->sync_src, false);
regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
@@ -1627,32 +1721,22 @@ static void arizona_disable_fll(struct arizona_fll *fll)
int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
unsigned int Fref, unsigned int Fout)
{
- struct arizona_fll_cfg ref, sync;
int ret;
if (fll->ref_src == source && fll->ref_freq == Fref)
return 0;
- if (fll->fout) {
- if (Fref > 0) {
- ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
- if (ret != 0)
- return ret;
- }
-
- if (fll->sync_src >= 0) {
- ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
- fll->fout);
- if (ret != 0)
- return ret;
- }
+ if (fll->fout && Fref > 0) {
+ ret = arizona_validate_fll(fll, Fref, fll->fout);
+ if (ret != 0)
+ return ret;
}
fll->ref_src = source;
fll->ref_freq = Fref;
if (fll->fout && Fref > 0) {
- arizona_enable_fll(fll, &ref, &sync);
+ arizona_enable_fll(fll);
}
return 0;
@@ -1662,7 +1746,6 @@ EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
int arizona_set_fll(struct arizona_fll *fll, int source,
unsigned int Fref, unsigned int Fout)
{
- struct arizona_fll_cfg ref, sync;
int ret;
if (fll->sync_src == source &&
@@ -1671,13 +1754,12 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
if (Fout) {
if (fll->ref_src >= 0) {
- ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
- Fout);
+ ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
if (ret != 0)
return ret;
}
- ret = arizona_calc_fll(fll, &sync, Fref, Fout);
+ ret = arizona_validate_fll(fll, Fref, Fout);
if (ret != 0)
return ret;
}
@@ -1687,7 +1769,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
fll->fout = Fout;
if (Fout) {
- arizona_enable_fll(fll, &ref, &sync);
+ arizona_enable_fll(fll);
} else {
arizona_disable_fll(fll);
}
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index ce05fd93dc74..aef4965750c7 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -159,7 +159,6 @@ static bool cs4271_volatile_reg(struct device *dev, unsigned int reg)
}
struct cs4271_private {
- /* SND_SOC_I2C or SND_SOC_SPI */
unsigned int mclk;
bool master;
bool deemph;
@@ -540,14 +539,10 @@ static int cs4271_probe(struct snd_soc_codec *codec)
struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
struct cs4271_platform_data *cs4271plat = codec->dev->platform_data;
int ret;
- int gpio_nreset = -EINVAL;
bool amutec_eq_bmutec = false;
#ifdef CONFIG_OF
if (of_match_device(cs4271_dt_ids, codec->dev)) {
- gpio_nreset = of_get_named_gpio(codec->dev->of_node,
- "reset-gpio", 0);
-
if (of_get_property(codec->dev->of_node,
"cirrus,amutec-eq-bmutec", NULL))
amutec_eq_bmutec = true;
@@ -559,27 +554,19 @@ static int cs4271_probe(struct snd_soc_codec *codec)
#endif
if (cs4271plat) {
- if (gpio_is_valid(cs4271plat->gpio_nreset))
- gpio_nreset = cs4271plat->gpio_nreset;
-
amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec;
cs4271->enable_soft_reset = cs4271plat->enable_soft_reset;
}
- if (gpio_nreset >= 0)
- if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset"))
- gpio_nreset = -EINVAL;
- if (gpio_nreset >= 0) {
+ if (gpio_is_valid(cs4271->gpio_nreset)) {
/* Reset codec */
- gpio_direction_output(gpio_nreset, 0);
+ gpio_direction_output(cs4271->gpio_nreset, 0);
udelay(1);
- gpio_set_value(gpio_nreset, 1);
+ gpio_set_value(cs4271->gpio_nreset, 1);
/* Give the codec time to wake up */
udelay(1);
}
- cs4271->gpio_nreset = gpio_nreset;
-
ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
CS4271_MODE2_PDN | CS4271_MODE2_CPEN,
CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
@@ -625,6 +612,36 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
.num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes),
};
+static int cs4271_common_probe(struct device *dev,
+ struct cs4271_private **c)
+{
+ struct cs4271_platform_data *cs4271plat = dev->platform_data;
+ struct cs4271_private *cs4271;
+
+ cs4271 = devm_kzalloc(dev, sizeof(*cs4271), GFP_KERNEL);
+ if (!cs4271)
+ return -ENOMEM;
+
+ if (of_match_device(cs4271_dt_ids, dev))
+ cs4271->gpio_nreset =
+ of_get_named_gpio(dev->of_node, "reset-gpio", 0);
+
+ if (cs4271plat)
+ cs4271->gpio_nreset = cs4271plat->gpio_nreset;
+
+ if (gpio_is_valid(cs4271->gpio_nreset)) {
+ int ret;
+
+ ret = devm_gpio_request(dev, cs4271->gpio_nreset,
+ "CS4271 Reset");
+ if (ret < 0)
+ return ret;
+ }
+
+ *c = cs4271;
+ return 0;
+}
+
#if defined(CONFIG_SPI_MASTER)
static const struct regmap_config cs4271_spi_regmap = {
@@ -644,10 +661,11 @@ static const struct regmap_config cs4271_spi_regmap = {
static int cs4271_spi_probe(struct spi_device *spi)
{
struct cs4271_private *cs4271;
+ int ret;
- cs4271 = devm_kzalloc(&spi->dev, sizeof(*cs4271), GFP_KERNEL);
- if (!cs4271)
- return -ENOMEM;
+ ret = cs4271_common_probe(&spi->dev, &cs4271);
+ if (ret < 0)
+ return ret;
spi_set_drvdata(spi, cs4271);
cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap);
@@ -698,10 +716,11 @@ static int cs4271_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct cs4271_private *cs4271;
+ int ret;
- cs4271 = devm_kzalloc(&client->dev, sizeof(*cs4271), GFP_KERNEL);
- if (!cs4271)
- return -ENOMEM;
+ ret = cs4271_common_probe(&client->dev, &cs4271);
+ if (ret < 0)
+ return ret;
i2c_set_clientdata(client, cs4271);
cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap);
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 6e9ea8379a91..3eab46020a30 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -30,6 +30,7 @@
#include <sound/pcm_params.h>
#include <sound/pcm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include "cs42l51.h"
@@ -40,7 +41,6 @@ enum master_slave_mode {
};
struct cs42l51_private {
- enum snd_soc_control_type control_type;
unsigned int mclk;
unsigned int audio_mode; /* The mode (I2S or left-justified) */
enum master_slave_mode func;
@@ -52,24 +52,6 @@ struct cs42l51_private {
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
-static int cs42l51_fill_cache(struct snd_soc_codec *codec)
-{
- u8 *cache = codec->reg_cache + 1;
- struct i2c_client *i2c_client = to_i2c_client(codec->dev);
- s32 length;
-
- length = i2c_smbus_read_i2c_block_data(i2c_client,
- CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache);
- if (length != CS42L51_NUMREGS) {
- dev_err(&i2c_client->dev,
- "I2C read failure, addr=0x%x (ret=%d vs %d)\n",
- i2c_client->addr, length, CS42L51_NUMREGS);
- return -EIO;
- }
-
- return 0;
-}
-
static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -505,16 +487,9 @@ static struct snd_soc_dai_driver cs42l51_dai = {
static int cs42l51_probe(struct snd_soc_codec *codec)
{
- struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
int ret, reg;
- ret = cs42l51_fill_cache(codec);
- if (ret < 0) {
- dev_err(codec->dev, "failed to fill register cache\n");
- return ret;
- }
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
@@ -538,8 +513,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
.probe = cs42l51_probe,
- .reg_cache_size = CS42L51_NUMREGS + 1,
- .reg_word_size = sizeof(u8),
.controls = cs42l51_snd_controls,
.num_controls = ARRAY_SIZE(cs42l51_snd_controls),
@@ -549,38 +522,53 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
.num_dapm_routes = ARRAY_SIZE(cs42l51_routes),
};
+static const struct regmap_config cs42l51_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = CS42L51_CHARGE_FREQ,
+ .cache_type = REGCACHE_RBTREE,
+};
+
static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id)
{
struct cs42l51_private *cs42l51;
+ struct regmap *regmap;
+ unsigned int val;
int ret;
+ regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ dev_err(&i2c_client->dev, "Failed to create regmap: %d\n",
+ ret);
+ return ret;
+ }
+
/* Verify that we have a CS42L51 */
- ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
+ ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val);
if (ret < 0) {
dev_err(&i2c_client->dev, "failed to read I2C\n");
goto error;
}
- if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
- (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
- dev_err(&i2c_client->dev, "Invalid chip id\n");
+ if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
+ (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
+ dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val);
ret = -ENODEV;
goto error;
}
dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
- ret & 7);
+ val & 7);
cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private),
GFP_KERNEL);
- if (!cs42l51) {
- dev_err(&i2c_client->dev, "could not allocate codec\n");
+ if (!cs42l51)
return -ENOMEM;
- }
i2c_set_clientdata(i2c_client, cs42l51);
- cs42l51->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c_client->dev,
&soc_codec_device_cs42l51, &cs42l51_dai, 1);
@@ -600,10 +588,17 @@ static const struct i2c_device_id cs42l51_id[] = {
};
MODULE_DEVICE_TABLE(i2c, cs42l51_id);
+static const struct of_device_id cs42l51_of_match[] = {
+ { .compatible = "cirrus,cs42l51", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, cs42l51_of_match);
+
static struct i2c_driver cs42l51_i2c_driver = {
.driver = {
.name = "cs42l51-codec",
.owner = THIS_MODULE,
+ .of_match_table = cs42l51_of_match,
},
.id_table = cs42l51_id,
.probe = cs42l51_i2c_probe,
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 0bac6d5a4ac8..be455ea5f2fe 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -210,13 +210,11 @@ static const char * const cs42l52_adca_text[] = {
static const char * const cs42l52_adcb_text[] = {
"Input1B", "Input2B", "Input3B", "Input4B", "PGA Input Right"};
-static const struct soc_enum adca_enum =
- SOC_ENUM_SINGLE(CS42L52_ADC_PGA_A, 5,
- ARRAY_SIZE(cs42l52_adca_text), cs42l52_adca_text);
+static SOC_ENUM_SINGLE_DECL(adca_enum,
+ CS42L52_ADC_PGA_A, 5, cs42l52_adca_text);
-static const struct soc_enum adcb_enum =
- SOC_ENUM_SINGLE(CS42L52_ADC_PGA_B, 5,
- ARRAY_SIZE(cs42l52_adcb_text), cs42l52_adcb_text);
+static SOC_ENUM_SINGLE_DECL(adcb_enum,
+ CS42L52_ADC_PGA_B, 5, cs42l52_adcb_text);
static const struct snd_kcontrol_new adca_mux =
SOC_DAPM_ENUM("Left ADC Input Capture Mux", adca_enum);
@@ -229,26 +227,22 @@ static const char * const mic_bias_level_text[] = {
"0.8 +VA", "0.83 +VA", "0.91 +VA"
};
-static const struct soc_enum mic_bias_level_enum =
- SOC_ENUM_SINGLE(CS42L52_IFACE_CTL2, 0,
- ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text);
+static SOC_ENUM_SINGLE_DECL(mic_bias_level_enum,
+ CS42L52_IFACE_CTL2, 0, mic_bias_level_text);
static const char * const cs42l52_mic_text[] = { "MIC1", "MIC2" };
-static const struct soc_enum mica_enum =
- SOC_ENUM_SINGLE(CS42L52_MICA_CTL, 5,
- ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text);
+static SOC_ENUM_SINGLE_DECL(mica_enum,
+ CS42L52_MICA_CTL, 5, cs42l52_mic_text);
-static const struct soc_enum micb_enum =
- SOC_ENUM_SINGLE(CS42L52_MICB_CTL, 5,
- ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text);
+static SOC_ENUM_SINGLE_DECL(micb_enum,
+ CS42L52_MICB_CTL, 5, cs42l52_mic_text);
static const char * const digital_output_mux_text[] = {"ADC", "DSP"};
-static const struct soc_enum digital_output_mux_enum =
- SOC_ENUM_SINGLE(CS42L52_ADC_MISC_CTL, 6,
- ARRAY_SIZE(digital_output_mux_text),
- digital_output_mux_text);
+static SOC_ENUM_SINGLE_DECL(digital_output_mux_enum,
+ CS42L52_ADC_MISC_CTL, 6,
+ digital_output_mux_text);
static const struct snd_kcontrol_new digital_output_mux =
SOC_DAPM_ENUM("Digital Output Mux", digital_output_mux_enum);
@@ -258,18 +252,18 @@ static const char * const hp_gain_num_text[] = {
"0.7099", "0.8399", "1.000", "1.1430"
};
-static const struct soc_enum hp_gain_enum =
- SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 5,
- ARRAY_SIZE(hp_gain_num_text), hp_gain_num_text);
+static SOC_ENUM_SINGLE_DECL(hp_gain_enum,
+ CS42L52_PB_CTL1, 5,
+ hp_gain_num_text);
static const char * const beep_pitch_text[] = {
"C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5",
"C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7"
};
-static const struct soc_enum beep_pitch_enum =
- SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 4,
- ARRAY_SIZE(beep_pitch_text), beep_pitch_text);
+static SOC_ENUM_SINGLE_DECL(beep_pitch_enum,
+ CS42L52_BEEP_FREQ, 4,
+ beep_pitch_text);
static const char * const beep_ontime_text[] = {
"86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s",
@@ -277,66 +271,66 @@ static const char * const beep_ontime_text[] = {
"3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s"
};
-static const struct soc_enum beep_ontime_enum =
- SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 0,
- ARRAY_SIZE(beep_ontime_text), beep_ontime_text);
+static SOC_ENUM_SINGLE_DECL(beep_ontime_enum,
+ CS42L52_BEEP_FREQ, 0,
+ beep_ontime_text);
static const char * const beep_offtime_text[] = {
"1.23 s", "2.58 s", "3.90 s", "5.20 s",
"6.60 s", "8.05 s", "9.35 s", "10.80 s"
};
-static const struct soc_enum beep_offtime_enum =
- SOC_ENUM_SINGLE(CS42L52_BEEP_VOL, 5,
- ARRAY_SIZE(beep_offtime_text), beep_offtime_text);
+static SOC_ENUM_SINGLE_DECL(beep_offtime_enum,
+ CS42L52_BEEP_VOL, 5,
+ beep_offtime_text);
static const char * const beep_config_text[] = {
"Off", "Single", "Multiple", "Continuous"
};
-static const struct soc_enum beep_config_enum =
- SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 6,
- ARRAY_SIZE(beep_config_text), beep_config_text);
+static SOC_ENUM_SINGLE_DECL(beep_config_enum,
+ CS42L52_BEEP_TONE_CTL, 6,
+ beep_config_text);
static const char * const beep_bass_text[] = {
"50 Hz", "100 Hz", "200 Hz", "250 Hz"
};
-static const struct soc_enum beep_bass_enum =
- SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 1,
- ARRAY_SIZE(beep_bass_text), beep_bass_text);
+static SOC_ENUM_SINGLE_DECL(beep_bass_enum,
+ CS42L52_BEEP_TONE_CTL, 1,
+ beep_bass_text);
static const char * const beep_treble_text[] = {
"5 kHz", "7 kHz", "10 kHz", " 15 kHz"
};
-static const struct soc_enum beep_treble_enum =
- SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 3,
- ARRAY_SIZE(beep_treble_text), beep_treble_text);
+static SOC_ENUM_SINGLE_DECL(beep_treble_enum,
+ CS42L52_BEEP_TONE_CTL, 3,
+ beep_treble_text);
static const char * const ng_threshold_text[] = {
"-34dB", "-37dB", "-40dB", "-43dB",
"-46dB", "-52dB", "-58dB", "-64dB"
};
-static const struct soc_enum ng_threshold_enum =
- SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 2,
- ARRAY_SIZE(ng_threshold_text), ng_threshold_text);
+static SOC_ENUM_SINGLE_DECL(ng_threshold_enum,
+ CS42L52_NOISE_GATE_CTL, 2,
+ ng_threshold_text);
static const char * const cs42l52_ng_delay_text[] = {
"50ms", "100ms", "150ms", "200ms"};
-static const struct soc_enum ng_delay_enum =
- SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 0,
- ARRAY_SIZE(cs42l52_ng_delay_text), cs42l52_ng_delay_text);
+static SOC_ENUM_SINGLE_DECL(ng_delay_enum,
+ CS42L52_NOISE_GATE_CTL, 0,
+ cs42l52_ng_delay_text);
static const char * const cs42l52_ng_type_text[] = {
"Apply Specific", "Apply All"
};
-static const struct soc_enum ng_type_enum =
- SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 6,
- ARRAY_SIZE(cs42l52_ng_type_text), cs42l52_ng_type_text);
+static SOC_ENUM_SINGLE_DECL(ng_type_enum,
+ CS42L52_NOISE_GATE_CTL, 6,
+ cs42l52_ng_type_text);
static const char * const left_swap_text[] = {
"Left", "LR 2", "Right"};
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index 549d5d6a3fef..06f429184821 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -278,13 +278,13 @@ static const DECLARE_TLV_DB_SCALE(attn_tlv, -6300, 100, 1);
static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" };
static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" };
-static const struct soc_enum pgaa_enum =
- SOC_ENUM_SINGLE(CS42L73_ADCIPC, 3,
- ARRAY_SIZE(cs42l73_pgaa_text), cs42l73_pgaa_text);
+static SOC_ENUM_SINGLE_DECL(pgaa_enum,
+ CS42L73_ADCIPC, 3,
+ cs42l73_pgaa_text);
-static const struct soc_enum pgab_enum =
- SOC_ENUM_SINGLE(CS42L73_ADCIPC, 7,
- ARRAY_SIZE(cs42l73_pgab_text), cs42l73_pgab_text);
+static SOC_ENUM_SINGLE_DECL(pgab_enum,
+ CS42L73_ADCIPC, 7,
+ cs42l73_pgab_text);
static const struct snd_kcontrol_new pgaa_mux =
SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum);
@@ -309,9 +309,9 @@ static const struct snd_kcontrol_new input_right_mixer[] = {
static const char * const cs42l73_ng_delay_text[] = {
"50ms", "100ms", "150ms", "200ms" };
-static const struct soc_enum ng_delay_enum =
- SOC_ENUM_SINGLE(CS42L73_NGCAB, 0,
- ARRAY_SIZE(cs42l73_ng_delay_text), cs42l73_ng_delay_text);
+static SOC_ENUM_SINGLE_DECL(ng_delay_enum,
+ CS42L73_NGCAB, 0,
+ cs42l73_ng_delay_text);
static const char * const cs42l73_mono_mix_texts[] = {
"Left", "Right", "Mono Mix"};
@@ -357,19 +357,19 @@ static const struct snd_kcontrol_new esl_xsp_mixer =
static const char * const cs42l73_ip_swap_text[] = {
"Stereo", "Mono A", "Mono B", "Swap A-B"};
-static const struct soc_enum ip_swap_enum =
- SOC_ENUM_SINGLE(CS42L73_MIOPC, 6,
- ARRAY_SIZE(cs42l73_ip_swap_text), cs42l73_ip_swap_text);
+static SOC_ENUM_SINGLE_DECL(ip_swap_enum,
+ CS42L73_MIOPC, 6,
+ cs42l73_ip_swap_text);
static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"};
-static const struct soc_enum vsp_output_mux_enum =
- SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 5,
- ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text);
+static SOC_ENUM_SINGLE_DECL(vsp_output_mux_enum,
+ CS42L73_MIXERCTL, 5,
+ cs42l73_spo_mixer_text);
-static const struct soc_enum xsp_output_mux_enum =
- SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 4,
- ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text);
+static SOC_ENUM_SINGLE_DECL(xsp_output_mux_enum,
+ CS42L73_MIXERCTL, 4,
+ cs42l73_spo_mixer_text);
static const struct snd_kcontrol_new vsp_output_mux =
SOC_DAPM_ENUM("Route", vsp_output_mux_enum);
@@ -1108,7 +1108,7 @@ static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
return 0;
}
-static u32 cs42l73_asrc_rates[] = {
+static const unsigned int cs42l73_asrc_rates[] = {
8000, 11025, 12000, 16000, 22050,
24000, 32000, 44100, 48000
};
@@ -1241,7 +1241,7 @@ static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate)
0x7F, tristate << 7);
}
-static struct snd_pcm_hw_constraint_list constraints_12_24 = {
+static const struct snd_pcm_hw_constraint_list constraints_12_24 = {
.count = ARRAY_SIZE(cs42l73_asrc_rates),
.list = cs42l73_asrc_rates,
};
@@ -1255,9 +1255,6 @@ static int cs42l73_pcm_startup(struct snd_pcm_substream *substream,
return 0;
}
-/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */
-#define CS42L73_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT)
-
#define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
@@ -1278,14 +1275,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
.stream_name = "XSP Playback",
.channels_min = 1,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.capture = {
.stream_name = "XSP Capture",
.channels_min = 1,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.ops = &cs42l73_ops,
@@ -1298,14 +1295,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
.stream_name = "ASP Playback",
.channels_min = 2,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.capture = {
.stream_name = "ASP Capture",
.channels_min = 2,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.ops = &cs42l73_ops,
@@ -1318,14 +1315,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
.stream_name = "VSP Playback",
.channels_min = 1,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.capture = {
.stream_name = "VSP Capture",
.channels_min = 1,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.ops = &cs42l73_ops,
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index e62e294a8033..01e55fc72307 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -307,29 +307,29 @@ static const char * const da7210_hpf_cutoff_txt[] = {
"Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi"
};
-static const struct soc_enum da7210_dac_hpf_cutoff =
- SOC_ENUM_SINGLE(DA7210_DAC_HPF, 0, 4, da7210_hpf_cutoff_txt);
+static SOC_ENUM_SINGLE_DECL(da7210_dac_hpf_cutoff,
+ DA7210_DAC_HPF, 0, da7210_hpf_cutoff_txt);
-static const struct soc_enum da7210_adc_hpf_cutoff =
- SOC_ENUM_SINGLE(DA7210_ADC_HPF, 0, 4, da7210_hpf_cutoff_txt);
+static SOC_ENUM_SINGLE_DECL(da7210_adc_hpf_cutoff,
+ DA7210_ADC_HPF, 0, da7210_hpf_cutoff_txt);
/* ADC and DAC voice (8kHz) high pass cutoff value */
static const char * const da7210_vf_cutoff_txt[] = {
"2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
};
-static const struct soc_enum da7210_dac_vf_cutoff =
- SOC_ENUM_SINGLE(DA7210_DAC_HPF, 4, 8, da7210_vf_cutoff_txt);
+static SOC_ENUM_SINGLE_DECL(da7210_dac_vf_cutoff,
+ DA7210_DAC_HPF, 4, da7210_vf_cutoff_txt);
-static const struct soc_enum da7210_adc_vf_cutoff =
- SOC_ENUM_SINGLE(DA7210_ADC_HPF, 4, 8, da7210_vf_cutoff_txt);
+static SOC_ENUM_SINGLE_DECL(da7210_adc_vf_cutoff,
+ DA7210_ADC_HPF, 4, da7210_vf_cutoff_txt);
static const char *da7210_hp_mode_txt[] = {
"Class H", "Class G"
};
-static const struct soc_enum da7210_hp_mode_sel =
- SOC_ENUM_SINGLE(DA7210_HP_CFG, 0, 2, da7210_hp_mode_txt);
+static SOC_ENUM_SINGLE_DECL(da7210_hp_mode_sel,
+ DA7210_HP_CFG, 0, da7210_hp_mode_txt);
/* ALC can be enabled only if noise suppression is disabled */
static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index ce9c8e14d4bd..34109050ceed 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -582,7 +582,7 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
{
struct snd_soc_codec *codec = w->codec;
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
- struct regmap *regmap = codec->control_data;
+ struct regmap *regmap = arizona->regmap;
const struct reg_default *patch = NULL;
int i, patch_size;
@@ -622,13 +622,16 @@ static const unsigned int wm5102_osr_val[] = {
static const struct soc_enum wm5102_hpout_osr[] = {
SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
- ARIZONA_OUT1_OSR_SHIFT, 0x7, 3,
+ ARIZONA_OUT1_OSR_SHIFT, 0x7,
+ ARRAY_SIZE(wm5102_osr_text),
wm5102_osr_text, wm5102_osr_val),
SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
- ARIZONA_OUT2_OSR_SHIFT, 0x7, 3,
+ ARIZONA_OUT2_OSR_SHIFT, 0x7,
+ ARRAY_SIZE(wm5102_osr_text),
wm5102_osr_text, wm5102_osr_val),
SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
- ARIZONA_OUT3_OSR_SHIFT, 0x7, 3,
+ ARIZONA_OUT3_OSR_SHIFT, 0x7,
+ ARRAY_SIZE(wm5102_osr_text),
wm5102_osr_text, wm5102_osr_val),
};
@@ -685,15 +688,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
-SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21,
- ARIZONA_EQ1_ENA_MASK),
-SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21,
- ARIZONA_EQ2_ENA_MASK),
-SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21,
- ARIZONA_EQ3_ENA_MASK),
-SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21,
- ARIZONA_EQ4_ENA_MASK),
-
+SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19),
+SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
@@ -705,6 +701,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
24, 0, eq_tlv),
+SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19),
+SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
@@ -716,6 +714,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
24, 0, eq_tlv),
+SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19),
+SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
@@ -727,6 +727,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
24, 0, eq_tlv),
+SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19),
+SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 2c3c962d9a85..d7bf8848174a 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -136,7 +136,7 @@ static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w,
{
struct snd_soc_codec *codec = w->codec;
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
- struct regmap *regmap = codec->control_data;
+ struct regmap *regmap = arizona->regmap;
const struct reg_default *patch = NULL;
int i, patch_size;
@@ -247,15 +247,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
-SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21,
- ARIZONA_EQ1_ENA_MASK),
-SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21,
- ARIZONA_EQ2_ENA_MASK),
-SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21,
- ARIZONA_EQ3_ENA_MASK),
-SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21,
- ARIZONA_EQ4_ENA_MASK),
-
+SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19),
+SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
@@ -267,6 +260,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
24, 0, eq_tlv),
+SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19),
+SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
@@ -278,6 +273,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
24, 0, eq_tlv),
+SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19),
+SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
@@ -289,6 +286,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
24, 0, eq_tlv),
+SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19),
+SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
index 555115ee2159..e10f44d7fdb7 100644
--- a/sound/soc/codecs/wm8997.c
+++ b/sound/soc/codecs/wm8997.c
@@ -86,7 +86,7 @@ static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w,
{
struct snd_soc_codec *codec = w->codec;
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
- struct regmap *regmap = codec->control_data;
+ struct regmap *regmap = arizona->regmap;
const struct reg_default *patch = NULL;
int i, patch_size;
@@ -123,10 +123,12 @@ static const unsigned int wm8997_osr_val[] = {
static const struct soc_enum wm8997_hpout_osr[] = {
SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
- ARIZONA_OUT1_OSR_SHIFT, 0x7, 3,
+ ARIZONA_OUT1_OSR_SHIFT, 0x7,
+ ARRAY_SIZE(wm8997_osr_text),
wm8997_osr_text, wm8997_osr_val),
SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
- ARIZONA_OUT3_OSR_SHIFT, 0x7, 3,
+ ARIZONA_OUT3_OSR_SHIFT, 0x7,
+ ARRAY_SIZE(wm8997_osr_text),
wm8997_osr_text, wm8997_osr_val),
};
@@ -170,15 +172,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
-SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21,
- ARIZONA_EQ1_ENA_MASK),
-SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21,
- ARIZONA_EQ2_ENA_MASK),
-SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21,
- ARIZONA_EQ3_ENA_MASK),
-SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21,
- ARIZONA_EQ4_ENA_MASK),
-
+SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19),
+SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
@@ -190,6 +185,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
24, 0, eq_tlv),
+SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19),
+SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
@@ -201,6 +198,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
24, 0, eq_tlv),
+SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19),
+SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
@@ -212,6 +211,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
24, 0, eq_tlv),
+SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19),
+SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0),
SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
24, 0, eq_tlv),
SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 444626fcab40..bb5f7b4e3ebb 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -684,24 +684,38 @@ static int wm_adsp_load(struct wm_adsp *dsp)
}
if (reg) {
- buf = wm_adsp_buf_alloc(region->data,
- le32_to_cpu(region->len),
- &buf_list);
- if (!buf) {
- adsp_err(dsp, "Out of memory\n");
- ret = -ENOMEM;
- goto out_fw;
- }
+ size_t to_write = PAGE_SIZE;
+ size_t remain = le32_to_cpu(region->len);
+ const u8 *data = region->data;
+
+ while (remain > 0) {
+ if (remain < PAGE_SIZE)
+ to_write = remain;
+
+ buf = wm_adsp_buf_alloc(data,
+ to_write,
+ &buf_list);
+ if (!buf) {
+ adsp_err(dsp, "Out of memory\n");
+ ret = -ENOMEM;
+ goto out_fw;
+ }
- ret = regmap_raw_write_async(regmap, reg, buf->buf,
- le32_to_cpu(region->len));
- if (ret != 0) {
- adsp_err(dsp,
- "%s.%d: Failed to write %d bytes at %d in %s: %d\n",
- file, regions,
- le32_to_cpu(region->len), offset,
- region_name, ret);
- goto out_fw;
+ ret = regmap_raw_write_async(regmap, reg,
+ buf->buf,
+ to_write);
+ if (ret != 0) {
+ adsp_err(dsp,
+ "%s.%d: Failed to write %zd bytes at %d in %s: %d\n",
+ file, regions,
+ to_write, offset,
+ region_name, ret);
+ goto out_fw;
+ }
+
+ data += to_write;
+ reg += to_write / 2;
+ remain -= to_write;
}
}
@@ -1679,6 +1693,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
list_del(&alg_region->list);
kfree(alg_region);
}
+
+ adsp_dbg(dsp, "Shutdown complete\n");
break;
default: