Merge branch 'topic/adsp' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-arizona
This commit is contained in:
commit
0644128556
2 changed files with 100 additions and 2 deletions
|
@ -18,6 +18,7 @@
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
|
@ -102,8 +103,9 @@
|
||||||
#define ADSP1_START_SHIFT 0 /* DSP1_START */
|
#define ADSP1_START_SHIFT 0 /* DSP1_START */
|
||||||
#define ADSP1_START_WIDTH 1 /* DSP1_START */
|
#define ADSP1_START_WIDTH 1 /* DSP1_START */
|
||||||
|
|
||||||
#define ADSP2_CONTROL 0
|
#define ADSP2_CONTROL 0
|
||||||
#define ADSP2_STATUS1 4
|
#define ADSP2_CLOCKING 1
|
||||||
|
#define ADSP2_STATUS1 4
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADSP2 Control
|
* ADSP2 Control
|
||||||
|
@ -126,6 +128,13 @@
|
||||||
#define ADSP2_START_SHIFT 0 /* DSP1_START */
|
#define ADSP2_START_SHIFT 0 /* DSP1_START */
|
||||||
#define ADSP2_START_WIDTH 1 /* DSP1_START */
|
#define ADSP2_START_WIDTH 1 /* DSP1_START */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ADSP2 clocking
|
||||||
|
*/
|
||||||
|
#define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */
|
||||||
|
#define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */
|
||||||
|
#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADSP2 Status 1
|
* ADSP2 Status 1
|
||||||
*/
|
*/
|
||||||
|
@ -530,10 +539,41 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_soc_codec *codec = w->codec;
|
struct snd_soc_codec *codec = w->codec;
|
||||||
struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
|
struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
|
||||||
struct wm_adsp *dsp = &dsps[w->shift];
|
struct wm_adsp *dsp = &dsps[w->shift];
|
||||||
|
unsigned int val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
|
if (dsp->dvfs) {
|
||||||
|
ret = regmap_read(dsp->regmap,
|
||||||
|
dsp->base + ADSP2_CLOCKING, &val);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(dsp->dev,
|
||||||
|
"Failed to read clocking: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val & ADSP2_CLK_SEL_MASK >= 3) {
|
||||||
|
ret = regulator_enable(dsp->dvfs);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(dsp->dev,
|
||||||
|
"Failed to enable supply: %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regulator_set_voltage(dsp->dvfs,
|
||||||
|
1800000,
|
||||||
|
1800000);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(dsp->dev,
|
||||||
|
"Failed to raise supply: %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = wm_adsp2_ena(dsp);
|
ret = wm_adsp2_ena(dsp);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -556,6 +596,21 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
|
||||||
case SND_SOC_DAPM_PRE_PMD:
|
case SND_SOC_DAPM_PRE_PMD:
|
||||||
regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
|
regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
|
||||||
ADSP2_SYS_ENA | ADSP2_START, 0);
|
ADSP2_SYS_ENA | ADSP2_START, 0);
|
||||||
|
|
||||||
|
if (dsp->dvfs) {
|
||||||
|
ret = regulator_set_voltage(dsp->dvfs, 1200000,
|
||||||
|
1800000);
|
||||||
|
if (ret != 0)
|
||||||
|
dev_warn(dsp->dev,
|
||||||
|
"Failed to lower supply: %d\n",
|
||||||
|
ret);
|
||||||
|
|
||||||
|
ret = regulator_disable(dsp->dvfs);
|
||||||
|
if (ret != 0)
|
||||||
|
dev_err(dsp->dev,
|
||||||
|
"Failed to enable supply: %d\n",
|
||||||
|
ret);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -569,3 +624,41 @@ err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(wm_adsp2_event);
|
EXPORT_SYMBOL_GPL(wm_adsp2_event);
|
||||||
|
|
||||||
|
int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (dvfs) {
|
||||||
|
adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
|
||||||
|
if (IS_ERR(adsp->dvfs)) {
|
||||||
|
ret = PTR_ERR(adsp->dvfs);
|
||||||
|
dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regulator_enable(adsp->dvfs);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(adsp->dev, "Failed to enable DCVDD: %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(adsp->dev, "Failed to initialise DVFS: %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regulator_disable(adsp->dvfs);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(adsp->dev, "Failed to disable DCVDD: %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(wm_adsp2_init);
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
#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;
|
||||||
|
@ -34,6 +36,8 @@ struct wm_adsp {
|
||||||
|
|
||||||
const struct wm_adsp_region *mem;
|
const struct wm_adsp_region *mem;
|
||||||
int num_mems;
|
int num_mems;
|
||||||
|
|
||||||
|
struct regulator *dvfs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WM_ADSP1(wname, num) \
|
#define WM_ADSP1(wname, num) \
|
||||||
|
@ -46,6 +50,7 @@ struct wm_adsp {
|
||||||
.shift = num, .event = wm_adsp2_event, \
|
.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 }
|
||||||
|
|
||||||
|
int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs);
|
||||||
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_event(struct snd_soc_dapm_widget *w,
|
int wm_adsp2_event(struct snd_soc_dapm_widget *w,
|
||||||
|
|
Loading…
Add table
Reference in a new issue