mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-16 05:26:07 +00:00
Merge remote-tracking branches 'asoc/topic/ab8500', 'asoc/topic/adau17x1', 'asoc/topic/ads117x', 'asoc/topic/adsp' and 'asoc/topic/arizona' into asoc-next
This commit is contained in:
commit
343b890871
24
Documentation/devicetree/bindings/sound/adi,adau17x1.txt
Normal file
24
Documentation/devicetree/bindings/sound/adi,adau17x1.txt
Normal file
@ -0,0 +1,24 @@
|
||||
Analog Devices ADAU1361/ADAU1461/ADAU1761/ADAU1961/ADAU1381/ADAU1781
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Should contain one of the following:
|
||||
"adi,adau1361"
|
||||
"adi,adau1461"
|
||||
"adi,adau1761"
|
||||
"adi,adau1961"
|
||||
"adi,adau1381"
|
||||
"adi,adau1781"
|
||||
|
||||
- reg: The i2c address. Value depends on the state of ADDR0
|
||||
and ADDR1, as wired in hardware.
|
||||
|
||||
Examples:
|
||||
#include <dt-bindings/sound/adau17x1.h>
|
||||
|
||||
i2c_bus {
|
||||
adau1361@38 {
|
||||
compatible = "adi,adau1761";
|
||||
reg = <0x38>;
|
||||
};
|
||||
};
|
11
Documentation/devicetree/bindings/sound/ti,ads117x.txt
Normal file
11
Documentation/devicetree/bindings/sound/ti,ads117x.txt
Normal file
@ -0,0 +1,11 @@
|
||||
Texas Intstruments ADS117x ADC
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "ti,ads1174" or "ti,ads1178"
|
||||
|
||||
Example:
|
||||
|
||||
ads1178 {
|
||||
compatible = "ti,ads1178";
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Driver for ADAU1761/ADAU1461/ADAU1761/ADAU1961/ADAU1781/ADAU1781 codecs
|
||||
* Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961/ADAU1381/ADAU1781 codecs
|
||||
*
|
||||
* Copyright 2011-2014 Analog Devices Inc.
|
||||
* Author: Lars-Peter Clausen <lars@metafoo.de>
|
||||
|
@ -2134,7 +2134,6 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
"%s: ERROR: Unsupporter master mask 0x%x\n",
|
||||
__func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
snd_soc_update_bits(codec, AB8500_DIGIFCONF3, mask, val);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Driver for ADAU1761/ADAU1461/ADAU1761/ADAU1961 codec
|
||||
* Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961 codec
|
||||
*
|
||||
* Copyright 2014 Analog Devices Inc.
|
||||
* Author: Lars-Peter Clausen <lars@metafoo.de>
|
||||
@ -44,9 +44,21 @@ static const struct i2c_device_id adau1761_i2c_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, adau1761_i2c_ids);
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id adau1761_i2c_dt_ids[] = {
|
||||
{ .compatible = "adi,adau1361", },
|
||||
{ .compatible = "adi,adau1461", },
|
||||
{ .compatible = "adi,adau1761", },
|
||||
{ .compatible = "adi,adau1961", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, adau1761_i2c_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver adau1761_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "adau1761",
|
||||
.of_match_table = of_match_ptr(adau1761_i2c_dt_ids),
|
||||
},
|
||||
.probe = adau1761_i2c_probe,
|
||||
.remove = adau1761_i2c_remove,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Driver for ADAU1761/ADAU1461/ADAU1761/ADAU1961 codec
|
||||
* Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961 codec
|
||||
*
|
||||
* Copyright 2014 Analog Devices Inc.
|
||||
* Author: Lars-Peter Clausen <lars@metafoo.de>
|
||||
@ -61,9 +61,21 @@ static const struct spi_device_id adau1761_spi_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, adau1761_spi_id);
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id adau1761_spi_dt_ids[] = {
|
||||
{ .compatible = "adi,adau1361", },
|
||||
{ .compatible = "adi,adau1461", },
|
||||
{ .compatible = "adi,adau1761", },
|
||||
{ .compatible = "adi,adau1961", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, adau1761_spi_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct spi_driver adau1761_spi_driver = {
|
||||
.driver = {
|
||||
.name = "adau1761",
|
||||
.of_match_table = of_match_ptr(adau1761_spi_dt_ids),
|
||||
},
|
||||
.probe = adau1761_spi_probe,
|
||||
.remove = adau1761_spi_remove,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Driver for ADAU1761/ADAU1461/ADAU1761/ADAU1961 codec
|
||||
* Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961 codec
|
||||
*
|
||||
* Copyright 2011-2013 Analog Devices Inc.
|
||||
* Author: Lars-Peter Clausen <lars@metafoo.de>
|
||||
@ -456,13 +456,17 @@ static int adau1761_set_bias_level(struct snd_soc_codec *codec,
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
break;
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
regcache_cache_only(adau->regmap, false);
|
||||
regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
|
||||
ADAU17X1_CLOCK_CONTROL_SYSCLK_EN,
|
||||
ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
|
||||
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
|
||||
regcache_sync(adau->regmap);
|
||||
break;
|
||||
case SND_SOC_BIAS_OFF:
|
||||
regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
|
||||
ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, 0);
|
||||
regcache_cache_only(adau->regmap, true);
|
||||
break;
|
||||
|
||||
}
|
||||
@ -783,6 +787,10 @@ int adau1761_probe(struct device *dev, struct regmap *regmap,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable cache only mode as we could miss writes before bias level
|
||||
* reaches standby and the core clock is enabled */
|
||||
regcache_cache_only(regmap, true);
|
||||
|
||||
return snd_soc_register_codec(dev, &adau1761_codec_driver, dai_drv, 1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(adau1761_probe);
|
||||
|
@ -42,9 +42,19 @@ static const struct i2c_device_id adau1781_i2c_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, adau1781_i2c_ids);
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id adau1781_i2c_dt_ids[] = {
|
||||
{ .compatible = "adi,adau1381", },
|
||||
{ .compatible = "adi,adau1781", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, adau1781_i2c_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver adau1781_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "adau1781",
|
||||
.of_match_table = of_match_ptr(adau1781_i2c_dt_ids),
|
||||
},
|
||||
.probe = adau1781_i2c_probe,
|
||||
.remove = adau1781_i2c_remove,
|
||||
|
@ -59,9 +59,19 @@ static const struct spi_device_id adau1781_spi_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, adau1781_spi_id);
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id adau1781_spi_dt_ids[] = {
|
||||
{ .compatible = "adi,adau1381", },
|
||||
{ .compatible = "adi,adau1781", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, adau1781_spi_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct spi_driver adau1781_spi_driver = {
|
||||
.driver = {
|
||||
.name = "adau1781",
|
||||
.of_match_table = of_match_ptr(adau1781_spi_dt_ids),
|
||||
},
|
||||
.probe = adau1781_spi_probe,
|
||||
.remove = adau1781_spi_remove,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Driver for ADAU1781/ADAU1781 codec
|
||||
* Driver for ADAU1381/ADAU1781 codec
|
||||
*
|
||||
* Copyright 2011-2013 Analog Devices Inc.
|
||||
* Author: Lars-Peter Clausen <lars@metafoo.de>
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <sound/initval.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include <linux/of.h>
|
||||
|
||||
#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
|
||||
#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
|
||||
|
||||
@ -75,9 +77,19 @@ static int ads117x_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id ads117x_dt_ids[] = {
|
||||
{ .compatible = "ti,ads1174" },
|
||||
{ .compatible = "ti,ads1178" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ads117x_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct platform_driver ads117x_codec_driver = {
|
||||
.driver = {
|
||||
.name = "ads117x-codec",
|
||||
.of_match_table = of_match_ptr(ads117x_dt_ids),
|
||||
},
|
||||
|
||||
.probe = ads117x_probe,
|
||||
|
@ -1398,29 +1398,6 @@ static const int arizona_48k_bclk_rates[] = {
|
||||
24576000,
|
||||
};
|
||||
|
||||
static const unsigned int arizona_48k_rates[] = {
|
||||
12000,
|
||||
24000,
|
||||
48000,
|
||||
96000,
|
||||
192000,
|
||||
384000,
|
||||
768000,
|
||||
4000,
|
||||
8000,
|
||||
16000,
|
||||
32000,
|
||||
64000,
|
||||
128000,
|
||||
256000,
|
||||
512000,
|
||||
};
|
||||
|
||||
static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
|
||||
.count = ARRAY_SIZE(arizona_48k_rates),
|
||||
.list = arizona_48k_rates,
|
||||
};
|
||||
|
||||
static const int arizona_44k1_bclk_rates[] = {
|
||||
-1,
|
||||
44100,
|
||||
@ -1443,22 +1420,7 @@ static const int arizona_44k1_bclk_rates[] = {
|
||||
22579200,
|
||||
};
|
||||
|
||||
static const unsigned int arizona_44k1_rates[] = {
|
||||
11025,
|
||||
22050,
|
||||
44100,
|
||||
88200,
|
||||
176400,
|
||||
352800,
|
||||
705600,
|
||||
};
|
||||
|
||||
static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
|
||||
.count = ARRAY_SIZE(arizona_44k1_rates),
|
||||
.list = arizona_44k1_rates,
|
||||
};
|
||||
|
||||
static int arizona_sr_vals[] = {
|
||||
static const unsigned int arizona_sr_vals[] = {
|
||||
0,
|
||||
12000,
|
||||
24000,
|
||||
@ -1485,13 +1447,21 @@ static int arizona_sr_vals[] = {
|
||||
512000,
|
||||
};
|
||||
|
||||
#define ARIZONA_48K_RATE_MASK 0x0F003E
|
||||
#define ARIZONA_44K1_RATE_MASK 0x003E00
|
||||
#define ARIZONA_RATE_MASK (ARIZONA_48K_RATE_MASK | ARIZONA_44K1_RATE_MASK)
|
||||
|
||||
static const struct snd_pcm_hw_constraint_list arizona_constraint = {
|
||||
.count = ARRAY_SIZE(arizona_sr_vals),
|
||||
.list = arizona_sr_vals,
|
||||
};
|
||||
|
||||
static int arizona_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
|
||||
const struct snd_pcm_hw_constraint_list *constraint;
|
||||
unsigned int base_rate;
|
||||
|
||||
if (!substream->runtime)
|
||||
@ -1509,16 +1479,15 @@ static int arizona_startup(struct snd_pcm_substream *substream,
|
||||
}
|
||||
|
||||
if (base_rate == 0)
|
||||
return 0;
|
||||
|
||||
if (base_rate % 8000)
|
||||
constraint = &arizona_44k1_constraint;
|
||||
dai_priv->constraint.mask = ARIZONA_RATE_MASK;
|
||||
else if (base_rate % 8000)
|
||||
dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK;
|
||||
else
|
||||
constraint = &arizona_48k_constraint;
|
||||
dai_priv->constraint.mask = ARIZONA_48K_RATE_MASK;
|
||||
|
||||
return snd_pcm_hw_constraint_list(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_RATE,
|
||||
constraint);
|
||||
&dai_priv->constraint);
|
||||
}
|
||||
|
||||
static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec,
|
||||
@ -1911,6 +1880,7 @@ int arizona_init_dai(struct arizona_priv *priv, int id)
|
||||
struct arizona_dai_priv *dai_priv = &priv->dai[id];
|
||||
|
||||
dai_priv->clk = ARIZONA_CLK_SYSCLK;
|
||||
dai_priv->constraint = arizona_constraint;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2179,11 +2149,12 @@ static int arizona_calc_fll(struct arizona_fll *fll,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
|
||||
arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
|
||||
cfg->n, cfg->theta, cfg->lambda);
|
||||
arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
|
||||
cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
|
||||
arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
|
||||
arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n",
|
||||
cfg->fratio, ratio, cfg->outdiv,
|
||||
cfg->refdiv, 1 << cfg->refdiv);
|
||||
arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -57,7 +57,7 @@
|
||||
#define ARIZONA_CLK_98MHZ 5
|
||||
#define ARIZONA_CLK_147MHZ 6
|
||||
|
||||
#define ARIZONA_MAX_DAI 8
|
||||
#define ARIZONA_MAX_DAI 10
|
||||
#define ARIZONA_MAX_ADSP 4
|
||||
|
||||
#define ARIZONA_DVFS_SR1_RQ 0x001
|
||||
@ -68,6 +68,8 @@ struct wm_adsp;
|
||||
|
||||
struct arizona_dai_priv {
|
||||
int clk;
|
||||
|
||||
struct snd_pcm_hw_constraint_list constraint;
|
||||
};
|
||||
|
||||
struct arizona_priv {
|
||||
|
@ -57,6 +57,25 @@ static const struct wm_adsp_region *cs47l24_dsp_regions[] = {
|
||||
cs47l24_dsp3_regions,
|
||||
};
|
||||
|
||||
static int cs47l24_adsp_power_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
|
||||
unsigned int v;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to read SYSCLK state: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
v = (v & ARIZONA_SYSCLK_FREQ_MASK) >> ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
|
||||
return wm_adsp2_early_event(w, kcontrol, event, v);
|
||||
}
|
||||
|
||||
static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
|
||||
static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
|
||||
static DECLARE_TLV_DB_SCALE(noise_tlv, -13200, 600, 0);
|
||||
@ -405,8 +424,8 @@ SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
|
||||
SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
|
||||
NULL, 0),
|
||||
|
||||
WM_ADSP2("DSP2", 1),
|
||||
WM_ADSP2("DSP3", 2),
|
||||
WM_ADSP2("DSP2", 1, cs47l24_adsp_power_ev),
|
||||
WM_ADSP2("DSP3", 2, cs47l24_adsp_power_ev),
|
||||
|
||||
SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,
|
||||
ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),
|
||||
@ -779,6 +798,9 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
|
||||
{ "AIF2 Capture", NULL, "SYSCLK" },
|
||||
{ "AIF3 Capture", NULL, "SYSCLK" },
|
||||
|
||||
{ "Voice Control DSP", NULL, "DSP3" },
|
||||
{ "Voice Control DSP", NULL, "SYSCLK" },
|
||||
|
||||
{ "IN1L PGA", NULL, "IN1L" },
|
||||
{ "IN1R PGA", NULL, "IN1R" },
|
||||
|
||||
@ -901,7 +923,7 @@ static int cs47l24_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
|
||||
}
|
||||
}
|
||||
|
||||
#define CS47L24_RATES SNDRV_PCM_RATE_8000_192000
|
||||
#define CS47L24_RATES SNDRV_PCM_RATE_KNOT
|
||||
|
||||
#define CS47L24_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
|
||||
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
|
||||
@ -973,12 +995,68 @@ static struct snd_soc_dai_driver cs47l24_dai[] = {
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l24-cpu-voicectrl",
|
||||
.capture = {
|
||||
.stream_name = "Voice Control CPU",
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.rates = CS47L24_RATES,
|
||||
.formats = CS47L24_FORMATS,
|
||||
},
|
||||
.compress_new = snd_soc_new_compress,
|
||||
},
|
||||
{
|
||||
.name = "cs47l24-dsp-voicectrl",
|
||||
.capture = {
|
||||
.stream_name = "Voice Control DSP",
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.rates = CS47L24_RATES,
|
||||
.formats = CS47L24_FORMATS,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static int cs47l24_open(struct snd_compr_stream *stream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = stream->private_data;
|
||||
struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(rtd->codec);
|
||||
struct arizona *arizona = priv->core.arizona;
|
||||
int n_adsp;
|
||||
|
||||
if (strcmp(rtd->codec_dai->name, "cs47l24-dsp-voicectrl") == 0) {
|
||||
n_adsp = 2;
|
||||
} else {
|
||||
dev_err(arizona->dev,
|
||||
"No suitable compressed stream for DAI '%s'\n",
|
||||
rtd->codec_dai->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return wm_adsp_compr_open(&priv->core.adsp[n_adsp], stream);
|
||||
}
|
||||
|
||||
static irqreturn_t cs47l24_adsp2_irq(int irq, void *data)
|
||||
{
|
||||
struct cs47l24_priv *priv = data;
|
||||
struct arizona *arizona = priv->core.arizona;
|
||||
int ret;
|
||||
|
||||
ret = wm_adsp_compr_handle_irq(&priv->core.adsp[2]);
|
||||
if (ret == -ENODEV) {
|
||||
dev_err(arizona->dev, "Spurious compressed data IRQ\n");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int cs47l24_codec_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
|
||||
struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
struct arizona *arizona = priv->core.arizona;
|
||||
int ret;
|
||||
|
||||
priv->core.arizona->dapm = dapm;
|
||||
@ -987,6 +1065,14 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec)
|
||||
arizona_init_gpio(codec);
|
||||
arizona_init_mono(codec);
|
||||
|
||||
ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
|
||||
"ADSP2 Compressed IRQ", cs47l24_adsp2_irq,
|
||||
priv);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to request DSP IRQ: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wm_adsp2_codec_probe(&priv->core.adsp[1], codec);
|
||||
if (ret)
|
||||
goto err_adsp2_codec_probe;
|
||||
@ -1014,13 +1100,14 @@ err_adsp2_codec_probe:
|
||||
static int cs47l24_codec_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
struct arizona *arizona = priv->core.arizona;
|
||||
|
||||
wm_adsp2_codec_remove(&priv->core.adsp[1], codec);
|
||||
wm_adsp2_codec_remove(&priv->core.adsp[2], codec);
|
||||
|
||||
priv->core.arizona->dapm = NULL;
|
||||
|
||||
arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1057,6 +1144,19 @@ static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = {
|
||||
.num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes),
|
||||
};
|
||||
|
||||
static struct snd_compr_ops cs47l24_compr_ops = {
|
||||
.open = cs47l24_open,
|
||||
.free = wm_adsp_compr_free,
|
||||
.set_params = wm_adsp_compr_set_params,
|
||||
.get_caps = wm_adsp_compr_get_caps,
|
||||
.trigger = wm_adsp_compr_trigger,
|
||||
.pointer = wm_adsp_compr_pointer,
|
||||
.copy = wm_adsp_compr_copy,
|
||||
};
|
||||
|
||||
static struct snd_soc_platform_driver cs47l24_compr_platform = {
|
||||
.compr_ops = &cs47l24_compr_ops,
|
||||
};
|
||||
static int cs47l24_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
|
||||
@ -1120,12 +1220,25 @@ static int cs47l24_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_idle(&pdev->dev);
|
||||
|
||||
return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l24,
|
||||
ret = snd_soc_register_platform(&pdev->dev, &cs47l24_compr_platform);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l24,
|
||||
cs47l24_dai, ARRAY_SIZE(cs47l24_dai));
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cs47l24_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
|
@ -619,7 +619,7 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
|
||||
unsigned int v;
|
||||
unsigned int v = 0;
|
||||
int ret;
|
||||
|
||||
switch (event) {
|
||||
@ -654,7 +654,7 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
|
||||
break;
|
||||
}
|
||||
|
||||
return wm_adsp2_early_event(w, kcontrol, event);
|
||||
return wm_adsp2_early_event(w, kcontrol, event, v);
|
||||
}
|
||||
|
||||
static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol,
|
||||
@ -1408,7 +1408,7 @@ ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
|
||||
ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
|
||||
ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
|
||||
|
||||
WM_ADSP2_E("DSP1", 0, wm5102_adsp_power_ev),
|
||||
WM_ADSP2("DSP1", 0, wm5102_adsp_power_ev),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("HPOUT1L"),
|
||||
SND_SOC_DAPM_OUTPUT("HPOUT1R"),
|
||||
@ -1599,6 +1599,9 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
|
||||
{ "Slim2 Capture", NULL, "SYSCLK" },
|
||||
{ "Slim3 Capture", NULL, "SYSCLK" },
|
||||
|
||||
{ "Audio Trace DSP", NULL, "DSP1" },
|
||||
{ "Audio Trace DSP", NULL, "SYSCLK" },
|
||||
|
||||
{ "IN1L PGA", NULL, "IN1L" },
|
||||
{ "IN1R PGA", NULL, "IN1R" },
|
||||
|
||||
@ -1735,7 +1738,7 @@ static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
|
||||
}
|
||||
}
|
||||
|
||||
#define WM5102_RATES SNDRV_PCM_RATE_8000_192000
|
||||
#define WM5102_RATES SNDRV_PCM_RATE_KNOT
|
||||
|
||||
#define WM5102_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
|
||||
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
|
||||
@ -1864,14 +1867,67 @@ static struct snd_soc_dai_driver wm5102_dai[] = {
|
||||
},
|
||||
.ops = &arizona_simple_dai_ops,
|
||||
},
|
||||
{
|
||||
.name = "wm5102-cpu-trace",
|
||||
.capture = {
|
||||
.stream_name = "Audio Trace CPU",
|
||||
.channels_min = 1,
|
||||
.channels_max = 6,
|
||||
.rates = WM5102_RATES,
|
||||
.formats = WM5102_FORMATS,
|
||||
},
|
||||
.compress_new = snd_soc_new_compress,
|
||||
},
|
||||
{
|
||||
.name = "wm5102-dsp-trace",
|
||||
.capture = {
|
||||
.stream_name = "Audio Trace DSP",
|
||||
.channels_min = 1,
|
||||
.channels_max = 4,
|
||||
.rates = WM5102_RATES,
|
||||
.formats = WM5102_FORMATS,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static int wm5102_open(struct snd_compr_stream *stream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = stream->private_data;
|
||||
struct wm5102_priv *priv = snd_soc_codec_get_drvdata(rtd->codec);
|
||||
|
||||
return wm_adsp_compr_open(&priv->core.adsp[0], stream);
|
||||
}
|
||||
|
||||
static irqreturn_t wm5102_adsp2_irq(int irq, void *data)
|
||||
{
|
||||
struct wm5102_priv *priv = data;
|
||||
struct arizona *arizona = priv->core.arizona;
|
||||
int ret;
|
||||
|
||||
ret = wm_adsp_compr_handle_irq(&priv->core.adsp[0]);
|
||||
if (ret == -ENODEV) {
|
||||
dev_err(arizona->dev, "Spurious compressed data IRQ\n");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int wm5102_codec_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
|
||||
struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
struct arizona *arizona = priv->core.arizona;
|
||||
int ret;
|
||||
|
||||
ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
|
||||
"ADSP2 Compressed IRQ", wm5102_adsp2_irq,
|
||||
priv);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to request DSP IRQ: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wm_adsp2_codec_probe(&priv->core.adsp[0], codec);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -1946,6 +2002,20 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
|
||||
.num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes),
|
||||
};
|
||||
|
||||
static struct snd_compr_ops wm5102_compr_ops = {
|
||||
.open = wm5102_open,
|
||||
.free = wm_adsp_compr_free,
|
||||
.set_params = wm_adsp_compr_set_params,
|
||||
.get_caps = wm_adsp_compr_get_caps,
|
||||
.trigger = wm_adsp_compr_trigger,
|
||||
.pointer = wm_adsp_compr_pointer,
|
||||
.copy = wm_adsp_compr_copy,
|
||||
};
|
||||
|
||||
static struct snd_soc_platform_driver wm5102_compr_platform = {
|
||||
.compr_ops = &wm5102_compr_ops,
|
||||
};
|
||||
|
||||
static int wm5102_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
|
||||
@ -2005,12 +2075,25 @@ static int wm5102_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_idle(&pdev->dev);
|
||||
|
||||
return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5102,
|
||||
ret = snd_soc_register_platform(&pdev->dev, &wm5102_compr_platform);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5102,
|
||||
wm5102_dai, ARRAY_SIZE(wm5102_dai));
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wm5102_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
|
@ -191,6 +191,25 @@ static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm5110_adsp_power_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
|
||||
unsigned int v;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to read SYSCLK state: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
v = (v & ARIZONA_SYSCLK_FREQ_MASK) >> ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
|
||||
return wm_adsp2_early_event(w, kcontrol, event, v);
|
||||
}
|
||||
|
||||
static const struct reg_sequence wm5110_no_dre_left_enable[] = {
|
||||
{ 0x3024, 0xE410 },
|
||||
{ 0x3025, 0x0056 },
|
||||
@ -1179,10 +1198,10 @@ SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
|
||||
SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
|
||||
NULL, 0),
|
||||
|
||||
WM_ADSP2("DSP1", 0),
|
||||
WM_ADSP2("DSP2", 1),
|
||||
WM_ADSP2("DSP3", 2),
|
||||
WM_ADSP2("DSP4", 3),
|
||||
WM_ADSP2("DSP1", 0, wm5110_adsp_power_ev),
|
||||
WM_ADSP2("DSP2", 1, wm5110_adsp_power_ev),
|
||||
WM_ADSP2("DSP3", 2, wm5110_adsp_power_ev),
|
||||
WM_ADSP2("DSP4", 3, wm5110_adsp_power_ev),
|
||||
|
||||
SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,
|
||||
ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),
|
||||
@ -1809,6 +1828,9 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
|
||||
{ "Voice Control DSP", NULL, "DSP3" },
|
||||
{ "Voice Control DSP", NULL, "SYSCLK" },
|
||||
|
||||
{ "Audio Trace DSP", NULL, "DSP1" },
|
||||
{ "Audio Trace DSP", NULL, "SYSCLK" },
|
||||
|
||||
{ "IN1L PGA", NULL, "IN1L" },
|
||||
{ "IN1R PGA", NULL, "IN1R" },
|
||||
|
||||
@ -2002,7 +2024,7 @@ static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
|
||||
}
|
||||
}
|
||||
|
||||
#define WM5110_RATES SNDRV_PCM_RATE_8000_192000
|
||||
#define WM5110_RATES SNDRV_PCM_RATE_KNOT
|
||||
|
||||
#define WM5110_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
|
||||
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
|
||||
@ -2152,6 +2174,27 @@ static struct snd_soc_dai_driver wm5110_dai[] = {
|
||||
.formats = WM5110_FORMATS,
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "wm5110-cpu-trace",
|
||||
.capture = {
|
||||
.stream_name = "Audio Trace CPU",
|
||||
.channels_min = 1,
|
||||
.channels_max = 6,
|
||||
.rates = WM5110_RATES,
|
||||
.formats = WM5110_FORMATS,
|
||||
},
|
||||
.compress_new = snd_soc_new_compress,
|
||||
},
|
||||
{
|
||||
.name = "wm5110-dsp-trace",
|
||||
.capture = {
|
||||
.stream_name = "Audio Trace DSP",
|
||||
.channels_min = 1,
|
||||
.channels_max = 6,
|
||||
.rates = WM5110_RATES,
|
||||
.formats = WM5110_FORMATS,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static int wm5110_open(struct snd_compr_stream *stream)
|
||||
@ -2163,6 +2206,8 @@ static int wm5110_open(struct snd_compr_stream *stream)
|
||||
|
||||
if (strcmp(rtd->codec_dai->name, "wm5110-dsp-voicectrl") == 0) {
|
||||
n_adsp = 2;
|
||||
} else if (strcmp(rtd->codec_dai->name, "wm5110-dsp-trace") == 0) {
|
||||
n_adsp = 0;
|
||||
} else {
|
||||
dev_err(arizona->dev,
|
||||
"No suitable compressed stream for DAI '%s'\n",
|
||||
@ -2175,12 +2220,21 @@ static int wm5110_open(struct snd_compr_stream *stream)
|
||||
|
||||
static irqreturn_t wm5110_adsp2_irq(int irq, void *data)
|
||||
{
|
||||
struct wm5110_priv *florida = data;
|
||||
int ret;
|
||||
struct wm5110_priv *priv = data;
|
||||
struct arizona *arizona = priv->core.arizona;
|
||||
int serviced = 0;
|
||||
int i, ret;
|
||||
|
||||
ret = wm_adsp_compr_handle_irq(&florida->core.adsp[2]);
|
||||
if (ret == -ENODEV)
|
||||
for (i = 0; i < WM5110_NUM_ADSP; ++i) {
|
||||
ret = wm_adsp_compr_handle_irq(&priv->core.adsp[i]);
|
||||
if (ret != -ENODEV)
|
||||
serviced++;
|
||||
}
|
||||
|
||||
if (!serviced) {
|
||||
dev_err(arizona->dev, "Spurious compressed data IRQ\n");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@ -2366,7 +2420,7 @@ static int wm5110_probe(struct platform_device *pdev)
|
||||
ret = snd_soc_register_platform(&pdev->dev, &wm5110_compr_platform);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5110,
|
||||
@ -2376,7 +2430,6 @@ static int wm5110_probe(struct platform_device *pdev)
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
}
|
||||
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -943,7 +943,7 @@ static int wm8997_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
|
||||
}
|
||||
}
|
||||
|
||||
#define WM8997_RATES SNDRV_PCM_RATE_8000_192000
|
||||
#define WM8997_RATES SNDRV_PCM_RATE_KNOT
|
||||
|
||||
#define WM8997_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
|
||||
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
@ -1170,7 +1170,7 @@ static const struct snd_soc_dapm_route wm8998_dapm_routes[] = {
|
||||
{ "DRC1 Signal Activity", NULL, "DRC1R" },
|
||||
};
|
||||
|
||||
#define WM8998_RATES SNDRV_PCM_RATE_8000_192000
|
||||
#define WM8998_RATES SNDRV_PCM_RATE_KNOT
|
||||
|
||||
#define WM8998_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
|
||||
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
@ -32,9 +32,6 @@
|
||||
#include <sound/initval.h>
|
||||
#include <sound/tlv.h>
|
||||
|
||||
#include <linux/mfd/arizona/registers.h>
|
||||
|
||||
#include "arizona.h"
|
||||
#include "wm_adsp.h"
|
||||
|
||||
#define adsp_crit(_dsp, fmt, ...) \
|
||||
@ -295,6 +292,8 @@ struct wm_adsp_compr {
|
||||
|
||||
u32 *raw_buf;
|
||||
unsigned int copied_total;
|
||||
|
||||
unsigned int sample_rate;
|
||||
};
|
||||
|
||||
#define WM_ADSP_DATA_WORD_SIZE 3
|
||||
@ -328,7 +327,7 @@ struct wm_adsp_buffer_region_def {
|
||||
unsigned int size_offset;
|
||||
};
|
||||
|
||||
static struct wm_adsp_buffer_region_def ez2control_regions[] = {
|
||||
static const struct wm_adsp_buffer_region_def default_regions[] = {
|
||||
{
|
||||
.mem_type = WMFW_ADSP2_XM,
|
||||
.base_offset = HOST_BUFFER_FIELD(X_buf_base),
|
||||
@ -350,10 +349,10 @@ struct wm_adsp_fw_caps {
|
||||
u32 id;
|
||||
struct snd_codec_desc desc;
|
||||
int num_regions;
|
||||
struct wm_adsp_buffer_region_def *region_defs;
|
||||
const struct wm_adsp_buffer_region_def *region_defs;
|
||||
};
|
||||
|
||||
static const struct wm_adsp_fw_caps ez2control_caps[] = {
|
||||
static const struct wm_adsp_fw_caps ctrl_caps[] = {
|
||||
{
|
||||
.id = SND_AUDIOCODEC_BESPOKE,
|
||||
.desc = {
|
||||
@ -362,8 +361,26 @@ static const struct wm_adsp_fw_caps ez2control_caps[] = {
|
||||
.num_sample_rates = 1,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
},
|
||||
.num_regions = ARRAY_SIZE(ez2control_regions),
|
||||
.region_defs = ez2control_regions,
|
||||
.num_regions = ARRAY_SIZE(default_regions),
|
||||
.region_defs = default_regions,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct wm_adsp_fw_caps trace_caps[] = {
|
||||
{
|
||||
.id = SND_AUDIOCODEC_BESPOKE,
|
||||
.desc = {
|
||||
.max_ch = 8,
|
||||
.sample_rates = {
|
||||
4000, 8000, 11025, 12000, 16000, 22050,
|
||||
24000, 32000, 44100, 48000, 64000, 88200,
|
||||
96000, 176400, 192000
|
||||
},
|
||||
.num_sample_rates = 15,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
},
|
||||
.num_regions = ARRAY_SIZE(default_regions),
|
||||
.region_defs = default_regions,
|
||||
},
|
||||
};
|
||||
|
||||
@ -382,11 +399,16 @@ static const struct {
|
||||
[WM_ADSP_FW_CTRL] = {
|
||||
.file = "ctrl",
|
||||
.compr_direction = SND_COMPRESS_CAPTURE,
|
||||
.num_caps = ARRAY_SIZE(ez2control_caps),
|
||||
.caps = ez2control_caps,
|
||||
.num_caps = ARRAY_SIZE(ctrl_caps),
|
||||
.caps = ctrl_caps,
|
||||
},
|
||||
[WM_ADSP_FW_ASR] = { .file = "asr" },
|
||||
[WM_ADSP_FW_TRACE] = { .file = "trace" },
|
||||
[WM_ADSP_FW_TRACE] = {
|
||||
.file = "trace",
|
||||
.compr_direction = SND_COMPRESS_CAPTURE,
|
||||
.num_caps = ARRAY_SIZE(trace_caps),
|
||||
.caps = trace_caps,
|
||||
},
|
||||
[WM_ADSP_FW_SPK_PROT] = { .file = "spk-prot" },
|
||||
[WM_ADSP_FW_MISC] = { .file = "misc" },
|
||||
};
|
||||
@ -719,19 +741,19 @@ static int wm_coeff_write_control(struct wm_coeff_ctl *ctl,
|
||||
reg = ctl->alg_region.base + ctl->offset;
|
||||
reg = wm_adsp_region_to_reg(mem, reg);
|
||||
|
||||
scratch = kmemdup(buf, ctl->len, GFP_KERNEL | GFP_DMA);
|
||||
scratch = kmemdup(buf, len, GFP_KERNEL | GFP_DMA);
|
||||
if (!scratch)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = regmap_raw_write(dsp->regmap, reg, scratch,
|
||||
ctl->len);
|
||||
len);
|
||||
if (ret) {
|
||||
adsp_err(dsp, "Failed to write %zu bytes to %x: %d\n",
|
||||
ctl->len, reg, ret);
|
||||
len, reg, ret);
|
||||
kfree(scratch);
|
||||
return ret;
|
||||
}
|
||||
adsp_dbg(dsp, "Wrote %zu bytes to %x\n", ctl->len, reg);
|
||||
adsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg);
|
||||
|
||||
kfree(scratch);
|
||||
|
||||
@ -778,20 +800,20 @@ static int wm_coeff_read_control(struct wm_coeff_ctl *ctl,
|
||||
reg = ctl->alg_region.base + ctl->offset;
|
||||
reg = wm_adsp_region_to_reg(mem, reg);
|
||||
|
||||
scratch = kmalloc(ctl->len, GFP_KERNEL | GFP_DMA);
|
||||
scratch = kmalloc(len, GFP_KERNEL | GFP_DMA);
|
||||
if (!scratch)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = regmap_raw_read(dsp->regmap, reg, scratch, ctl->len);
|
||||
ret = regmap_raw_read(dsp->regmap, reg, scratch, len);
|
||||
if (ret) {
|
||||
adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n",
|
||||
ctl->len, reg, ret);
|
||||
len, reg, ret);
|
||||
kfree(scratch);
|
||||
return ret;
|
||||
}
|
||||
adsp_dbg(dsp, "Read %zu bytes from %x\n", ctl->len, reg);
|
||||
adsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg);
|
||||
|
||||
memcpy(buf, scratch, ctl->len);
|
||||
memcpy(buf, scratch, len);
|
||||
kfree(scratch);
|
||||
|
||||
return 0;
|
||||
@ -855,17 +877,18 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl)
|
||||
kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_READ;
|
||||
if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
|
||||
kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_VOLATILE;
|
||||
} else {
|
||||
kcontrol->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
|
||||
kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_VOLATILE;
|
||||
}
|
||||
|
||||
ret = snd_soc_add_card_controls(dsp->card,
|
||||
kcontrol, 1);
|
||||
ret = snd_soc_add_card_controls(dsp->card, kcontrol, 1);
|
||||
if (ret < 0)
|
||||
goto err_kcontrol;
|
||||
|
||||
kfree(kcontrol);
|
||||
|
||||
ctl->kcontrol = snd_soc_card_get_kcontrol(dsp->card,
|
||||
ctl->name);
|
||||
ctl->kcontrol = snd_soc_card_get_kcontrol(dsp->card, ctl->name);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -885,9 +908,7 @@ static int wm_coeff_init_control_caches(struct wm_adsp *dsp)
|
||||
if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
|
||||
continue;
|
||||
|
||||
ret = wm_coeff_read_control(ctl,
|
||||
ctl->cache,
|
||||
ctl->len);
|
||||
ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@ -904,9 +925,7 @@ static int wm_coeff_sync_controls(struct wm_adsp *dsp)
|
||||
if (!ctl->enabled)
|
||||
continue;
|
||||
if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) {
|
||||
ret = wm_coeff_write_control(ctl,
|
||||
ctl->cache,
|
||||
ctl->len);
|
||||
ret = wm_coeff_write_control(ctl, ctl->cache, ctl->len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@ -1502,8 +1521,7 @@ static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs,
|
||||
|
||||
ret = regmap_raw_read(dsp->regmap, pos, alg, len * 2);
|
||||
if (ret != 0) {
|
||||
adsp_err(dsp, "Failed to read algorithm list: %d\n",
|
||||
ret);
|
||||
adsp_err(dsp, "Failed to read algorithm list: %d\n", ret);
|
||||
kfree(alg);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
@ -2002,8 +2020,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
|
||||
goto err_mutex;
|
||||
}
|
||||
|
||||
val = (val & dsp->sysclk_mask)
|
||||
>> dsp->sysclk_shift;
|
||||
val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift;
|
||||
|
||||
ret = regmap_update_bits(dsp->regmap,
|
||||
dsp->base + ADSP1_CONTROL_31,
|
||||
@ -2096,8 +2113,7 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
|
||||
|
||||
/* Wait for the RAM to start, should be near instantaneous */
|
||||
for (count = 0; count < 10; ++count) {
|
||||
ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1,
|
||||
&val);
|
||||
ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@ -2123,30 +2139,9 @@ static void wm_adsp2_boot_work(struct work_struct *work)
|
||||
struct wm_adsp,
|
||||
boot_work);
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
mutex_lock(&dsp->pwr_lock);
|
||||
|
||||
/*
|
||||
* For simplicity set the DSP clock rate to be the
|
||||
* SYSCLK rate rather than making it configurable.
|
||||
*/
|
||||
ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
|
||||
if (ret != 0) {
|
||||
adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret);
|
||||
goto err_mutex;
|
||||
}
|
||||
val = (val & ARIZONA_SYSCLK_FREQ_MASK)
|
||||
>> ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
|
||||
ret = regmap_update_bits_async(dsp->regmap,
|
||||
dsp->base + ADSP2_CLOCKING,
|
||||
ADSP2_CLK_SEL_MASK, val);
|
||||
if (ret != 0) {
|
||||
adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
|
||||
goto err_mutex;
|
||||
}
|
||||
|
||||
ret = wm_adsp2_ena(dsp);
|
||||
if (ret != 0)
|
||||
goto err_mutex;
|
||||
@ -2186,8 +2181,21 @@ err_mutex:
|
||||
mutex_unlock(&dsp->pwr_lock);
|
||||
}
|
||||
|
||||
static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits_async(dsp->regmap,
|
||||
dsp->base + ADSP2_CLOCKING,
|
||||
ADSP2_CLK_SEL_MASK,
|
||||
freq << ADSP2_CLK_SEL_SHIFT);
|
||||
if (ret != 0)
|
||||
adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
|
||||
}
|
||||
|
||||
int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
struct snd_kcontrol *kcontrol, int event,
|
||||
unsigned int freq)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
|
||||
@ -2197,6 +2205,7 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
wm_adsp2_set_dspclk(dsp, freq);
|
||||
queue_work(system_unbound_wq, &dsp->boot_work);
|
||||
break;
|
||||
default:
|
||||
@ -2471,6 +2480,8 @@ int wm_adsp_compr_set_params(struct snd_compr_stream *stream,
|
||||
if (!compr->raw_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
compr->sample_rate = params->codec.sample_rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wm_adsp_compr_set_params);
|
||||
@ -2810,7 +2821,6 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp)
|
||||
mutex_lock(&dsp->pwr_lock);
|
||||
|
||||
if (!buf) {
|
||||
adsp_err(dsp, "Spurious buffer IRQ\n");
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
@ -2841,7 +2851,7 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (compr->stream)
|
||||
if (compr && compr->stream)
|
||||
snd_compr_fragment_elapsed(compr->stream);
|
||||
|
||||
out:
|
||||
@ -2911,6 +2921,7 @@ int wm_adsp_compr_pointer(struct snd_compr_stream *stream,
|
||||
|
||||
tstamp->copied_total = compr->copied_total;
|
||||
tstamp->copied_total += buf->avail * WM_ADSP_DATA_WORD_SIZE;
|
||||
tstamp->sampling_rate = compr->sample_rate;
|
||||
|
||||
out:
|
||||
mutex_unlock(&dsp->pwr_lock);
|
||||
|
@ -80,7 +80,7 @@ struct wm_adsp {
|
||||
SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
|
||||
wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
|
||||
|
||||
#define WM_ADSP2_E(wname, num, event_fn) \
|
||||
#define WM_ADSP2(wname, num, event_fn) \
|
||||
{ .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \
|
||||
.reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
|
||||
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \
|
||||
@ -88,9 +88,6 @@ struct wm_adsp {
|
||||
.reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \
|
||||
.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
|
||||
|
||||
#define WM_ADSP2(wname, num) \
|
||||
WM_ADSP2_E(wname, num, wm_adsp2_early_event)
|
||||
|
||||
extern const struct snd_kcontrol_new wm_adsp_fw_controls[];
|
||||
|
||||
int wm_adsp1_init(struct wm_adsp *dsp);
|
||||
@ -100,7 +97,8 @@ int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec);
|
||||
int wm_adsp1_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
struct snd_kcontrol *kcontrol, int event,
|
||||
unsigned int freq);
|
||||
int wm_adsp2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user