Commit 202f5ecb authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/adau1977', 'asoc/topic/adav80x',...

Merge remote-tracking branches 'asoc/topic/adau1977', 'asoc/topic/adav80x', 'asoc/topic/arizona' and 'asoc/topic/atmel' into asoc-next
...@@ -78,11 +78,6 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, ...@@ -78,11 +78,6 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev,
if (ret != 0) if (ret != 0)
return ret; return ret;
ret = regmap_update_bits(regmap, ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
ARIZONA_SUBSYS_MAX_FREQ, val);
if (ret != 0)
return ret;
if (val) if (val)
return 0; return 0;
......
...@@ -6,27 +6,22 @@ config SND_ATMEL_SOC ...@@ -6,27 +6,22 @@ config SND_ATMEL_SOC
the ATMEL SSC interface. You will also need the ATMEL SSC interface. You will also need
to select the audio interfaces to support below. to select the audio interfaces to support below.
if SND_ATMEL_SOC
config SND_ATMEL_SOC_PDC config SND_ATMEL_SOC_PDC
tristate bool
depends on SND_ATMEL_SOC
config SND_ATMEL_SOC_DMA config SND_ATMEL_SOC_DMA
tristate bool
depends on SND_ATMEL_SOC
select SND_SOC_GENERIC_DMAENGINE_PCM select SND_SOC_GENERIC_DMAENGINE_PCM
config SND_ATMEL_SOC_SSC config SND_ATMEL_SOC_SSC
tristate tristate
depends on SND_ATMEL_SOC
help
Say Y or M if you want to add support for codecs the
ATMEL SSC interface. You will also needs to select the individual
machine drivers to support below.
config SND_AT91_SOC_SAM9G20_WM8731 config SND_AT91_SOC_SAM9G20_WM8731
tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
depends on ARCH_AT91 || COMPILE_TEST depends on ARCH_AT91 || COMPILE_TEST
depends on ATMEL_SSC && SND_ATMEL_SOC && SND_SOC_I2C_AND_SPI depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI
select SND_ATMEL_SOC_PDC select SND_ATMEL_SOC_PDC
select SND_ATMEL_SOC_SSC select SND_ATMEL_SOC_SSC
select SND_SOC_WM8731 select SND_SOC_WM8731
...@@ -37,7 +32,7 @@ config SND_AT91_SOC_SAM9G20_WM8731 ...@@ -37,7 +32,7 @@ config SND_AT91_SOC_SAM9G20_WM8731
config SND_ATMEL_SOC_WM8904 config SND_ATMEL_SOC_WM8904
tristate "Atmel ASoC driver for boards using WM8904 codec" tristate "Atmel ASoC driver for boards using WM8904 codec"
depends on ARCH_AT91 || COMPILE_TEST depends on ARCH_AT91 || COMPILE_TEST
depends on ATMEL_SSC && SND_ATMEL_SOC && I2C depends on ATMEL_SSC && I2C
select SND_ATMEL_SOC_SSC select SND_ATMEL_SOC_SSC
select SND_ATMEL_SOC_DMA select SND_ATMEL_SOC_DMA
select SND_SOC_WM8904 select SND_SOC_WM8904
...@@ -48,10 +43,11 @@ config SND_ATMEL_SOC_WM8904 ...@@ -48,10 +43,11 @@ config SND_ATMEL_SOC_WM8904
config SND_AT91_SOC_SAM9X5_WM8731 config SND_AT91_SOC_SAM9X5_WM8731
tristate "SoC Audio support for WM8731-based at91sam9x5 board" tristate "SoC Audio support for WM8731-based at91sam9x5 board"
depends on ARCH_AT91 || COMPILE_TEST depends on ARCH_AT91 || COMPILE_TEST
depends on ATMEL_SSC && SND_ATMEL_SOC && SND_SOC_I2C_AND_SPI depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI
select SND_ATMEL_SOC_SSC select SND_ATMEL_SOC_SSC
select SND_ATMEL_SOC_DMA select SND_ATMEL_SOC_DMA
select SND_SOC_WM8731 select SND_SOC_WM8731
help help
Say Y if you want to add support for audio SoC on an Say Y if you want to add support for audio SoC on an
at91sam9x5 based board that is using WM8731 codec. at91sam9x5 based board that is using WM8731 codec.
endif
# AT91 Platform Support # AT91 Platform Support
snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o snd-soc-atmel-pcm-$(CONFIG_SND_ATMEL_SOC_PDC) := atmel-pcm-pdc.o
snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o snd-soc-atmel-pcm-$(CONFIG_SND_ATMEL_SOC_DMA) += atmel-pcm-dma.o
snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o $(snd-soc-atmel-pcm-y)
obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o
obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
# AT91 Machine Support # AT91 Machine Support
......
...@@ -95,8 +95,9 @@ static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = { ...@@ -95,8 +95,9 @@ static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = {
static const struct snd_soc_dapm_route intercon[] = { static const struct snd_soc_dapm_route intercon[] = {
/* speaker connected to LHPOUT */ /* speaker connected to LHPOUT/RHPOUT */
{"Ext Spk", NULL, "LHPOUT"}, {"Ext Spk", NULL, "LHPOUT"},
{"Ext Spk", NULL, "RHPOUT"},
/* mic is connected to Mic Jack, with WM8731 Mic Bias */ /* mic is connected to Mic Jack, with WM8731 Mic Bias */
{"MICIN", NULL, "Mic Bias"}, {"MICIN", NULL, "Mic Bias"},
...@@ -108,9 +109,7 @@ static const struct snd_soc_dapm_route intercon[] = { ...@@ -108,9 +109,7 @@ static const struct snd_soc_dapm_route intercon[] = {
*/ */
static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
{ {
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret; int ret;
printk(KERN_DEBUG printk(KERN_DEBUG
...@@ -124,10 +123,6 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) ...@@ -124,10 +123,6 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
return ret; return ret;
} }
/* not connected */
snd_soc_dapm_nc_pin(dapm, "RLINEIN");
snd_soc_dapm_nc_pin(dapm, "LLINEIN");
#ifndef ENABLE_MIC_INPUT #ifndef ENABLE_MIC_INPUT
snd_soc_dapm_nc_pin(&rtd->card->dapm, "Int Mic"); snd_soc_dapm_nc_pin(&rtd->card->dapm, "Int Mic");
#endif #endif
...@@ -158,6 +153,7 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = { ...@@ -158,6 +153,7 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = {
.num_dapm_widgets = ARRAY_SIZE(at91sam9g20ek_dapm_widgets), .num_dapm_widgets = ARRAY_SIZE(at91sam9g20ek_dapm_widgets),
.dapm_routes = intercon, .dapm_routes = intercon,
.num_dapm_routes = ARRAY_SIZE(intercon), .num_dapm_routes = ARRAY_SIZE(intercon),
.fully_routed = true,
}; };
static int at91sam9g20ek_audio_probe(struct platform_device *pdev) static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
......
...@@ -202,7 +202,7 @@ static const struct snd_soc_dapm_route adau1977_dapm_routes[] = { ...@@ -202,7 +202,7 @@ static const struct snd_soc_dapm_route adau1977_dapm_routes[] = {
ADAU1977_REG_DC_HPF_CAL, (x) - 1, 1, 0) ADAU1977_REG_DC_HPF_CAL, (x) - 1, 1, 0)
#define ADAU1977_DC_SUB_SWITCH(x) \ #define ADAU1977_DC_SUB_SWITCH(x) \
SOC_SINGLE("ADC" #x " DC Substraction Capture Switch", \ SOC_SINGLE("ADC" #x " DC Subtraction Capture Switch", \
ADAU1977_REG_DC_HPF_CAL, (x) + 3, 1, 0) ADAU1977_REG_DC_HPF_CAL, (x) + 3, 1, 0)
static const struct snd_kcontrol_new adau1977_snd_controls[] = { static const struct snd_kcontrol_new adau1977_snd_controls[] = {
......
...@@ -539,7 +539,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, ...@@ -539,7 +539,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
unsigned int freq, int dir) unsigned int freq, int dir)
{ {
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
if (dir == SND_SOC_CLOCK_IN) { if (dir == SND_SOC_CLOCK_IN) {
switch (clk_id) { switch (clk_id) {
...@@ -622,6 +622,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, ...@@ -622,6 +622,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id, static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
int source, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
unsigned int pll_ctrl1 = 0; unsigned int pll_ctrl1 = 0;
unsigned int pll_ctrl2 = 0; unsigned int pll_ctrl2 = 0;
...@@ -687,7 +688,7 @@ static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id, ...@@ -687,7 +688,7 @@ static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
adav80x->pll_src = source; adav80x->pll_src = source;
snd_soc_dapm_sync(&codec->dapm); snd_soc_dapm_sync(dapm);
} }
return 0; return 0;
...@@ -800,11 +801,12 @@ static struct snd_soc_dai_driver adav80x_dais[] = { ...@@ -800,11 +801,12 @@ static struct snd_soc_dai_driver adav80x_dais[] = {
static int adav80x_probe(struct snd_soc_codec *codec) static int adav80x_probe(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
/* Force PLLs on for SYSCLK output */ /* Force PLLs on for SYSCLK output */
snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); snd_soc_dapm_force_enable_pin(dapm, "PLL1");
snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2"); snd_soc_dapm_force_enable_pin(dapm, "PLL2");
/* Power down S/PDIF receiver, since it is currently not supported */ /* Power down S/PDIF receiver, since it is currently not supported */
regmap_write(adav80x->regmap, ADAV80X_PLL_OUTE, 0x20); regmap_write(adav80x->regmap, ADAV80X_PLL_OUTE, 0x20);
......
...@@ -851,6 +851,134 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, ...@@ -851,6 +851,134 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w,
} }
EXPORT_SYMBOL_GPL(arizona_hp_ev); EXPORT_SYMBOL_GPL(arizona_hp_ev);
static int arizona_dvfs_enable(struct snd_soc_codec *codec)
{
const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = priv->arizona;
int ret;
ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
if (ret) {
dev_err(codec->dev, "Failed to boost DCVDD: %d\n", ret);
return ret;
}
ret = regmap_update_bits(arizona->regmap,
ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
ARIZONA_SUBSYS_MAX_FREQ,
ARIZONA_SUBSYS_MAX_FREQ);
if (ret) {
dev_err(codec->dev, "Failed to enable subsys max: %d\n", ret);
regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
return ret;
}
return 0;
}
static int arizona_dvfs_disable(struct snd_soc_codec *codec)
{
const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = priv->arizona;
int ret;
ret = regmap_update_bits(arizona->regmap,
ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
ARIZONA_SUBSYS_MAX_FREQ, 0);
if (ret) {
dev_err(codec->dev, "Failed to disable subsys max: %d\n", ret);
return ret;
}
ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
if (ret) {
dev_err(codec->dev, "Failed to unboost DCVDD: %d\n", ret);
return ret;
}
return 0;
}
int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags)
{
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
int ret = 0;
mutex_lock(&priv->dvfs_lock);
if (!priv->dvfs_cached && !priv->dvfs_reqs) {
ret = arizona_dvfs_enable(codec);
if (ret)
goto err;
}
priv->dvfs_reqs |= flags;
err:
mutex_unlock(&priv->dvfs_lock);
return ret;
}
EXPORT_SYMBOL_GPL(arizona_dvfs_up);
int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags)
{
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
unsigned int old_reqs;
int ret = 0;
mutex_lock(&priv->dvfs_lock);
old_reqs = priv->dvfs_reqs;
priv->dvfs_reqs &= ~flags;
if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
ret = arizona_dvfs_disable(codec);
mutex_unlock(&priv->dvfs_lock);
return ret;
}
EXPORT_SYMBOL_GPL(arizona_dvfs_down);
int arizona_dvfs_sysclk_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_priv *priv = snd_soc_codec_get_drvdata(codec);
int ret = 0;
mutex_lock(&priv->dvfs_lock);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
if (priv->dvfs_reqs)
ret = arizona_dvfs_enable(codec);
priv->dvfs_cached = false;
break;
case SND_SOC_DAPM_PRE_PMD:
/* We must ensure DVFS is disabled before the codec goes into
* suspend so that we are never in an illegal state of DVFS
* enabled without enough DCVDD
*/
priv->dvfs_cached = true;
if (priv->dvfs_reqs)
ret = arizona_dvfs_disable(codec);
break;
default:
break;
}
mutex_unlock(&priv->dvfs_lock);
return ret;
}
EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
void arizona_init_dvfs(struct arizona_priv *priv)
{
mutex_init(&priv->dvfs_lock);
}
EXPORT_SYMBOL_GPL(arizona_init_dvfs);
static unsigned int arizona_sysclk_48k_rates[] = { static unsigned int arizona_sysclk_48k_rates[] = {
6144000, 6144000,
12288000, 12288000,
...@@ -1266,7 +1394,7 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream, ...@@ -1266,7 +1394,7 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
int base = dai->driver->base; int base = dai->driver->base;
int i, sr_val; int i, sr_val, ret;
/* /*
* We will need to be more flexible than this in future, * We will need to be more flexible than this in future,
...@@ -1282,6 +1410,23 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream, ...@@ -1282,6 +1410,23 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
} }
sr_val = i; sr_val = i;
switch (priv->arizona->type) {
case WM5102:
case WM8997:
if (arizona_sr_vals[sr_val] >= 88200)
ret = arizona_dvfs_up(codec, ARIZONA_DVFS_SR1_RQ);
else
ret = arizona_dvfs_down(codec, ARIZONA_DVFS_SR1_RQ);
if (ret) {
arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
return ret;
}
break;
default:
break;
}
switch (dai_priv->clk) { switch (dai_priv->clk) {
case ARIZONA_CLK_SYSCLK: case ARIZONA_CLK_SYSCLK:
switch (priv->arizona->type) { switch (priv->arizona->type) {
......
...@@ -60,6 +60,9 @@ ...@@ -60,6 +60,9 @@
#define ARIZONA_MAX_DAI 6 #define ARIZONA_MAX_DAI 6
#define ARIZONA_MAX_ADSP 4 #define ARIZONA_MAX_ADSP 4
#define ARIZONA_DVFS_SR1_RQ 0x001
#define ARIZONA_DVFS_ADSP1_RQ 0x100
struct arizona; struct arizona;
struct wm_adsp; struct wm_adsp;
...@@ -84,6 +87,10 @@ struct arizona_priv { ...@@ -84,6 +87,10 @@ struct arizona_priv {
unsigned int spk_ena:2; unsigned int spk_ena:2;
unsigned int spk_ena_pending:1; unsigned int spk_ena_pending:1;
unsigned int dvfs_reqs;
struct mutex dvfs_lock;
bool dvfs_cached;
}; };
#define ARIZONA_NUM_MIXER_INPUTS 103 #define ARIZONA_NUM_MIXER_INPUTS 103
...@@ -107,8 +114,8 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ...@@ -107,8 +114,8 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
arizona_mixer_tlv) arizona_mixer_tlv)
#define ARIZONA_MUX_ENUM_DECL(name, reg) \ #define ARIZONA_MUX_ENUM_DECL(name, reg) \
SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \ SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL( \
arizona_mixer_texts, arizona_mixer_values) name, reg, 0, 0xff, arizona_mixer_texts, arizona_mixer_values)
#define ARIZONA_MUX_CTL_DECL(name) \ #define ARIZONA_MUX_CTL_DECL(name) \
const struct snd_kcontrol_new name##_mux = \ const struct snd_kcontrol_new name##_mux = \
...@@ -245,6 +252,12 @@ struct arizona_fll { ...@@ -245,6 +252,12 @@ struct arizona_fll {
char clock_ok_name[ARIZONA_FLL_NAME_LEN]; char clock_ok_name[ARIZONA_FLL_NAME_LEN];
}; };
extern int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags);
extern int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags);
extern int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
extern void arizona_init_dvfs(struct arizona_priv *priv);
extern int arizona_init_fll(struct arizona *arizona, int id, int base, extern int arizona_init_fll(struct arizona *arizona, int id, int base,
int lock_irq, int ok_irq, struct arizona_fll *fll); int lock_irq, int ok_irq, struct arizona_fll *fll);
extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source, extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
......
...@@ -605,12 +605,56 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, ...@@ -605,12 +605,56 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
regmap_write_async(regmap, patch[i].reg, regmap_write_async(regmap, patch[i].reg,
patch[i].def); patch[i].def);
break; break;
case SND_SOC_DAPM_PRE_PMD:
break;
default:
return 0;
}
return arizona_dvfs_sysclk_ev(w, kcontrol, event);
}
static int wm5102_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;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
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 -EIO;
}
v = (v & ARIZONA_SYSCLK_FREQ_MASK) >> ARIZONA_SYSCLK_FREQ_SHIFT;
if (v >= 3) {
ret = arizona_dvfs_up(codec, ARIZONA_DVFS_ADSP1_RQ);
if (ret) {
dev_err(codec->dev,
"Failed to raise DVFS: %d\n", ret);
return ret;
}
}
break;
case SND_SOC_DAPM_POST_PMD:
ret = arizona_dvfs_down(codec, ARIZONA_DVFS_ADSP1_RQ);
if (ret)
dev_warn(codec->dev,
"Failed to lower DVFS: %d\n", ret);
break;
default: default:
break; break;
} }
return 0; return wm_adsp2_early_event(w, kcontrol, event);
} }
static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol, static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol,
...@@ -1036,7 +1080,8 @@ static const struct snd_kcontrol_new wm5102_aec_loopback_mux = ...@@ -1036,7 +1080,8 @@ static const struct snd_kcontrol_new wm5102_aec_loopback_mux =
static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
0, wm5102_sysclk_ev, SND_SOC_DAPM_POST_PMU), 0, wm5102_sysclk_ev,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
...@@ -1367,7 +1412,7 @@ ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"), ...@@ -1367,7 +1412,7 @@ ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"), ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"), ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
WM_ADSP2("DSP1", 0), WM_ADSP2_E("DSP1", 0, wm5102_adsp_power_ev),
SND_SOC_DAPM_OUTPUT("HPOUT1L"), SND_SOC_DAPM_OUTPUT("HPOUT1L"),
SND_SOC_DAPM_OUTPUT("HPOUT1R"), SND_SOC_DAPM_OUTPUT("HPOUT1R"),
...@@ -1910,6 +1955,8 @@ static int wm5102_probe(struct platform_device *pdev) ...@@ -1910,6 +1955,8 @@ static int wm5102_probe(struct platform_device *pdev)
wm5102->core.arizona = arizona; wm5102->core.arizona = arizona;
wm5102->core.num_inputs = 6; wm5102->core.num_inputs = 6;
arizona_init_dvfs(&wm5102->core);
wm5102->core.adsp[0].part = "wm5102"; wm5102->core.adsp[0].part = "wm5102";
wm5102->core.adsp[0].num = 1; wm5102->core.adsp[0].num = 1;
wm5102->core.adsp[0].type = WMFW_ADSP2; wm5102->core.adsp[0].type = WMFW_ADSP2;
...@@ -1919,7 +1966,7 @@ static int wm5102_probe(struct platform_device *pdev) ...@@ -1919,7 +1966,7 @@ static int wm5102_probe(struct platform_device *pdev)
wm5102->core.adsp[0].mem = wm5102_dsp1_regions; wm5102->core.adsp[0].mem = wm5102_dsp1_regions;
wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions); wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions);
ret = wm_adsp2_init(&wm5102->core.adsp[0], true); ret = wm_adsp2_init(&wm5102->core.adsp[0]);
if (ret != 0) if (ret != 0)
return ret; return ret;
......
...@@ -1696,7 +1696,7 @@ static int wm5110_probe(struct platform_device *pdev) ...@@ -1696,7 +1696,7 @@ static int wm5110_probe(struct platform_device *pdev)
wm5110->core.adsp[i].num_mems wm5110->core.adsp[i].num_mems
= ARRAY_SIZE(wm5110_dsp1_regions); = ARRAY_SIZE(wm5110_dsp1_regions);
ret = wm_adsp2_init(&wm5110->core.adsp[i], false); ret = wm_adsp2_init(&wm5110->core.adsp[i]);
if (ret != 0) if (ret != 0)
return ret; return ret;
} }
......
...@@ -106,11 +106,13 @@ static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w, ...@@ -106,11 +106,13 @@ static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w,
regmap_write_async(regmap, patch[i].reg, regmap_write_async(regmap, patch[i].reg,
patch[i].def); patch[i].def);
break; break;
default: case SND_SOC_DAPM_PRE_PMD:
break; break;
default:
return 0;
} }
return 0; return arizona_dvfs_sysclk_ev(w, kcontrol, event);
} }
static const char *wm8997_osr_text[] = { static const char *wm8997_osr_text[] = {
...@@ -409,7 +411,8 @@ static const struct snd_kcontrol_new wm8997_aec_loopback_mux = ...@@ -409,7 +411,8 @@ static const struct snd_kcontrol_new wm8997_aec_loopback_mux =
static const struct snd_soc_dapm_widget wm8997_dapm_widgets[] = { static const struct snd_soc_dapm_widget wm8997_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
0, wm8997_sysclk_ev, SND_SOC_DAPM_POST_PMU), 0, wm8997_sysclk_ev,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
...@@ -1127,6 +1130,8 @@ static int wm8997_probe(struct platform_device *pdev) ...@@ -1127,6 +1130,8 @@ static int wm8997_probe(struct platform_device *pdev)
wm8997->core.arizona = arizona; wm8997->core.arizona = arizona;
wm8997->core.num_inputs = 4; wm8997->core.num_inputs = 4;
arizona_init_dvfs(&wm8997->core);
for (i = 0; i < ARRAY_SIZE(wm8997->fll); i++) for (i = 0; i < ARRAY_SIZE(wm8997->fll); i++)
wm8997->fll[i].vco_mult = 1; wm8997->fll[i].vco_mult = 1;
......
This diff is collapsed.
...@@ -18,8 +18,6 @@ ...@@ -18,8 +18,6 @@
#include "wmfw.h" #include "wmfw.h"
struct regulator;
struct wm_adsp_region { struct wm_adsp_region {
int type; int type;
unsigned int base; unsigned int base;
...@@ -30,7 +28,6 @@ struct wm_adsp_alg_region { ...@@ -30,7 +28,6 @@ struct wm_adsp_alg_region {
unsigned int alg; unsigned int alg;
int type; int type;
unsigned int base; unsigned int base;
size_t len;
}; };
struct wm_adsp { struct wm_adsp {
...@@ -54,10 +51,9 @@ struct wm_adsp { ...@@ -54,10 +51,9 @@ struct wm_adsp {
int num_mems; int num_mems;
int fw; int fw;
int fw_ver;
bool running; bool running;
struct regulator *dvfs;
struct list_head ctl_list; struct list_head ctl_list;
struct work_struct boot_work; struct work_struct boot_work;
...@@ -67,19 +63,22 @@ struct wm_adsp { ...@@ -67,19 +63,22 @@ struct wm_adsp {
SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ 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) wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
#define WM_ADSP2(wname, num) \ #define WM_ADSP2_E(wname, num, event_fn) \
{ .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \ { .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \
.reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_early_event, \ .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
.event_flags = SND_SOC_DAPM_PRE_PMU }, \ .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \
{ .id = snd_soc_dapm_out_drv, .name = wname, \ { .id = snd_soc_dapm_out_drv, .name = wname, \
.reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \ .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \
.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } .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_adsp1_fw_controls[]; extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];
extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];
int wm_adsp1_init(struct wm_adsp *adsp); int wm_adsp1_init(struct wm_adsp *dsp);
int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); int wm_adsp2_init(struct wm_adsp *dsp);
int wm_adsp1_event(struct snd_soc_dapm_widget *w, int wm_adsp1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event); struct snd_kcontrol *kcontrol, int event);
int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
......
...@@ -15,6 +15,17 @@ ...@@ -15,6 +15,17 @@
#include <linux/types.h> #include <linux/types.h>
#define WMFW_MAX_ALG_NAME 256
#define WMFW_MAX_ALG_DESCR_NAME 256
#define WMFW_MAX_COEFF_NAME 256
#define WMFW_MAX_COEFF_DESCR_NAME 256
#define WMFW_CTL_FLAG_SYS 0x8000
#define WMFW_CTL_FLAG_VOLATILE 0x0004
#define WMFW_CTL_FLAG_WRITEABLE 0x0002
#define WMFW_CTL_FLAG_READABLE 0x0001
struct wmfw_header { struct wmfw_header {
char magic[4]; char magic[4];
__le32 len; __le32 len;
...@@ -61,7 +72,7 @@ struct wmfw_adsp1_id_hdr { ...@@ -61,7 +72,7 @@ struct wmfw_adsp1_id_hdr {
struct wmfw_id_hdr fw; struct wmfw_id_hdr fw;
__be32 zm; __be32 zm;
__be32 dm; __be32 dm;
__be32 algs; __be32 n_algs;
} __packed; } __packed;
struct wmfw_adsp2_id_hdr { struct wmfw_adsp2_id_hdr {
...@@ -69,7 +80,7 @@ struct wmfw_adsp2_id_hdr { ...@@ -69,7 +80,7 @@ struct wmfw_adsp2_id_hdr {
__be32 zm; __be32 zm;
__be32 xm; __be32 xm;
__be32 ym; __be32 ym;
__be32 algs; __be32 n_algs;
} __packed; } __packed;
struct wmfw_alg_hdr { struct wmfw_alg_hdr {
...@@ -90,6 +101,28 @@ struct wmfw_adsp2_alg_hdr { ...@@ -90,6 +101,28 @@ struct wmfw_adsp2_alg_hdr {
__be32 ym; __be32 ym;
} __packed; } __packed;
struct wmfw_adsp_alg_data {
__le32 id;
u8 name[WMFW_MAX_ALG_NAME];
u8 descr[WMFW_MAX_ALG_DESCR_NAME];
__le32 ncoeff;
u8 data[];
} __packed;
struct wmfw_adsp_coeff_data {
struct {
__le16 offset;
__le16 type;
__le32 size;
} hdr;
u8 name[WMFW_MAX_COEFF_NAME];
u8 descr[WMFW_MAX_COEFF_DESCR_NAME];
__le16 ctl_type;
__le16 flags;
__le32 len;
u8 data[];
} __packed;
struct wmfw_coeff_hdr { struct wmfw_coeff_hdr {
u8 magic[4]; u8 magic[4];
__le32 len; __le32 len;
...@@ -117,9 +150,10 @@ struct wmfw_coeff_item { ...@@ -117,9 +150,10 @@ struct wmfw_coeff_item {
#define WMFW_ADSP1 1 #define WMFW_ADSP1 1
#define WMFW_ADSP2 2 #define WMFW_ADSP2 2
#define WMFW_ABSOLUTE 0xf0 #define WMFW_ABSOLUTE 0xf0
#define WMFW_NAME_TEXT 0xfe #define WMFW_ALGORITHM_DATA 0xf2
#define WMFW_INFO_TEXT 0xff #define WMFW_NAME_TEXT 0xfe
#define WMFW_INFO_TEXT 0xff
#define WMFW_ADSP1_PM 2 #define WMFW_ADSP1_PM 2
#define WMFW_ADSP1_DM 3 #define WMFW_ADSP1_DM 3
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment