summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/adau1701.c
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2014-11-19 20:29:05 +0300
committerMark Brown <broonie@kernel.org>2014-11-20 12:55:34 +0300
commitd48b088e3ec45eeccf0fce0b75378e41428f47e9 (patch)
tree2a81e6d82c6aeeaf35620938f4079d290748b4bf /sound/soc/codecs/adau1701.c
parent6b25730f68073ee95079d241ea6aa7be00805254 (diff)
downloadlinux-d48b088e3ec45eeccf0fce0b75378e41428f47e9.tar.xz
ASoC: sigmadsp: Restructure in preparation for fw v2 support
The v2 file format of the SigmaDSP takes a more declarative style compared to the imperative style of the v1 format. In addition some features that are supported with v2 require the driver to keep state around for the firmware. This requires a bit of restructuring of both the firmware loader itself and the drivers making use of the firmware loader. Instead of loading and executing the firmware in place when the DSP is configured the firmware is now loaded at driver probe time. This is required since the new firmware format will in addition to the firmware data itself contain meta information describing the firmware and its requirements and capabilities. Those will for example be used to restrict the supported samplerates advertised by the driver to userspace to the list of samplerates supported for the firmware. This only does the restructuring required by the v2 format, but does not yet add support for the new format itself. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/adau1701.c')
-rw-r--r--sound/soc/codecs/adau1701.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 370b742117ef..05d5eb5984b6 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -103,6 +103,8 @@ struct adau1701 {
unsigned int sysclk;
struct regmap *regmap;
u8 pin_config[12];
+
+ struct sigmadsp *sigmadsp;
};
static const struct snd_kcontrol_new adau1701_controls[] = {
@@ -238,12 +240,14 @@ static int adau1701_reg_read(void *context, unsigned int reg,
return 0;
}
-static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
+static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv,
+ unsigned int rate)
{
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *client = to_i2c_client(codec->dev);
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])) {
@@ -284,7 +288,7 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
* know the correct PLL setup
*/
if (clkdiv != ADAU1707_CLKDIV_UNSET) {
- ret = process_sigma_firmware(client, ADAU1701_FIRMWARE);
+ ret = sigmadsp_setup(adau1701->sigmadsp, rate);
if (ret) {
dev_warn(codec->dev, "Failed to load firmware\n");
return ret;
@@ -385,7 +389,7 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
* firmware upload.
*/
if (clkdiv != adau1701->pll_clkdiv) {
- ret = adau1701_reset(codec, clkdiv);
+ ret = adau1701_reset(codec, clkdiv, params_rate(params));
if (ret < 0)
return ret;
}
@@ -554,6 +558,14 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
return 0;
}
+static int adau1701_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(dai->codec);
+
+ return sigmadsp_restrict_params(adau1701->sigmadsp, substream);
+}
+
#define ADAU1701_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \
SNDRV_PCM_RATE_192000)
@@ -564,6 +576,7 @@ static const struct snd_soc_dai_ops adau1701_dai_ops = {
.set_fmt = adau1701_set_dai_fmt,
.hw_params = adau1701_hw_params,
.digital_mute = adau1701_digital_mute,
+ .startup = adau1701_startup,
};
static struct snd_soc_dai_driver adau1701_dai = {
@@ -600,6 +613,10 @@ static int adau1701_probe(struct snd_soc_codec *codec)
unsigned int val;
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+ ret = sigmadsp_attach(adau1701->sigmadsp, &codec->component);
+ if (ret)
+ return ret;
+
/*
* Let the pll_clkdiv variable default to something that won't happen
* at runtime. That way, we can postpone the firmware download from
@@ -609,7 +626,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET;
/* initalize with pre-configured pll mode settings */
- ret = adau1701_reset(codec, adau1701->pll_clkdiv);
+ ret = adau1701_reset(codec, adau1701->pll_clkdiv, 0);
if (ret < 0)
return ret;
@@ -722,6 +739,12 @@ static int adau1701_i2c_probe(struct i2c_client *client,
adau1701->gpio_pll_mode[1] = gpio_pll_mode[1];
i2c_set_clientdata(client, adau1701);
+
+ adau1701->sigmadsp = devm_sigmadsp_init_i2c(client, NULL,
+ ADAU1701_FIRMWARE);
+ if (IS_ERR(adau1701->sigmadsp))
+ return PTR_ERR(adau1701->sigmadsp);
+
ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
&adau1701_dai, 1);
return ret;