int adau17x1_setup_firmware(struct snd_soc_component *component, unsigned int rate) { int ret; int dspsr, dsp_run; struct adau *adau = snd_soc_component_get_drvdata(component); struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); /* Check if sample rate is the same as before. If it is there is no * point in performing the below steps as the call to * sigmadsp_setup(...) will return directly when it finds the sample * rate to be the same as before. By checking this we can prevent an * audiable popping noise which occours when toggling DSP_RUN. */ if (adau->sigmadsp->current_samplerate == rate) return 0; snd_soc_dapm_mutex_lock(dapm); ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr); if (ret) goto err; ret = regmap_read(adau->regmap, ADAU17X1_DSP_RUN, &dsp_run); if (ret) goto err; regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1); regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf); regmap_write(adau->regmap, ADAU17X1_DSP_RUN, 0); ret = sigmadsp_setup(adau->sigmadsp, rate); if (ret) { regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0); goto err; } regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr); regmap_write(adau->regmap, ADAU17X1_DSP_RUN, dsp_run); err: snd_soc_dapm_mutex_unlock(dapm); return ret; }
int adau17x1_setup_firmware(struct adau *adau, unsigned int rate) { int ret; int dspsr; ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr); if (ret) return ret; regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1); regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf); ret = sigmadsp_setup(adau->sigmadsp, rate); if (ret) { regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0); return ret; } regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr); return 0; }
static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv, unsigned int rate) { struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); int ret; sigmadsp_reset(adau1701->sigmadsp); if (clkdiv != ADAU1707_CLKDIV_UNSET && gpio_is_valid(adau1701->gpio_pll_mode[0]) && gpio_is_valid(adau1701->gpio_pll_mode[1])) { switch (clkdiv) { case 64: gpio_set_value_cansleep(adau1701->gpio_pll_mode[0], 0); gpio_set_value_cansleep(adau1701->gpio_pll_mode[1], 0); break; case 256: gpio_set_value_cansleep(adau1701->gpio_pll_mode[0], 0); gpio_set_value_cansleep(adau1701->gpio_pll_mode[1], 1); break; case 384: gpio_set_value_cansleep(adau1701->gpio_pll_mode[0], 1); gpio_set_value_cansleep(adau1701->gpio_pll_mode[1], 0); break; case 0: /* fallback */ case 512: gpio_set_value_cansleep(adau1701->gpio_pll_mode[0], 1); gpio_set_value_cansleep(adau1701->gpio_pll_mode[1], 1); break; } } adau1701->pll_clkdiv = clkdiv; if (gpio_is_valid(adau1701->gpio_nreset)) { gpio_set_value_cansleep(adau1701->gpio_nreset, 0); /* minimum reset time is 20ns */ udelay(1); gpio_set_value_cansleep(adau1701->gpio_nreset, 1); /* power-up time may be as long as 85ms */ mdelay(85); } /* * Postpone the firmware download to a point in time when we * know the correct PLL setup */ if (clkdiv != ADAU1707_CLKDIV_UNSET) { ret = sigmadsp_setup(adau1701->sigmadsp, rate); if (ret) { dev_warn(codec->dev, "Failed to load firmware\n"); return ret; } } regmap_write(adau1701->regmap, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT); regmap_write(adau1701->regmap, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR); regcache_mark_dirty(adau1701->regmap); regcache_sync(adau1701->regmap); return 0; }