summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/wm_adsp.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-04-02 19:51:39 +0200
committerTakashi Iwai <tiwai@suse.de>2018-04-02 19:51:39 +0200
commit903d271a3f83826ef810a4b5dbbd9842cf0465d6 (patch)
tree07fd60b1d7ad07ba36c82b2e83ece7c7eb6e6ce9 /sound/soc/codecs/wm_adsp.c
parentbc334cb61b9ee6e85b9bb01519989a3ae8fe03f6 (diff)
parent445bb423f6a3c50788529a33b82e45148001e855 (diff)
Merge tag 'asoc-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v4.17 This is a *very* big release for ASoC. Not much change in the core but there s the transition of all the individual drivers over to components which is intended to support further core work. The goal is to make it easier to do further core work by removing the need to special case all the different driver classes in the core, many of the devices end up being used in multiple roles in modern systems. We also have quite a lot of new drivers added this month of all kinds, quite a few for simple devices but also some more advanced ones with more substantial code. - The biggest thing is the huge series from Morimoto-san which converted everything over to components. This is a huge change by code volume but was fairly mechanical - Many fixes for some of the Realtek based Baytrail systems covering both the CODECs and the CPUs, contributed by Hans de Goode. - Lots of cleanups for Samsung based Odroid systems from Sylwester Nawrocki. - The Freescale SSI driver also got a lot of cleanups from Nicolin Chen. - The Blackfin drivers have been removed as part of the removal of the architecture. - New drivers for AKM AK4458 and AK5558, several AMD based machines, several Intel based machines, Maxim MAX9759, Motorola CPCAP, Socionext Uniphier SoCs, and TI PCM1789 and TDA7419
Diffstat (limited to 'sound/soc/codecs/wm_adsp.c')
-rw-r--r--sound/soc/codecs/wm_adsp.c99
1 files changed, 57 insertions, 42 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 989d093abda7..82b0927e6ed7 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -605,13 +605,13 @@ static const struct {
};
static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
- struct snd_soc_codec *codec)
+ struct snd_soc_component *component)
{
struct dentry *root = NULL;
char *root_name;
int i;
- if (!codec->component.debugfs_root) {
+ if (!component->debugfs_root) {
adsp_err(dsp, "No codec debugfs root\n");
goto err;
}
@@ -621,7 +621,7 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
goto err;
snprintf(root_name, PAGE_SIZE, "dsp%d", dsp->num);
- root = debugfs_create_dir(root_name, codec->component.debugfs_root);
+ root = debugfs_create_dir(root_name, component->debugfs_root);
kfree(root_name);
if (!root)
@@ -662,7 +662,7 @@ static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp)
}
#else
static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
- struct snd_soc_codec *codec)
+ struct snd_soc_component *component)
{
}
@@ -688,9 +688,9 @@ static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+ struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
ucontrol->value.enumerated.item[0] = dsp[e->shift_l].fw;
@@ -700,9 +700,9 @@ static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+ struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
int ret = 0;
if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw)
@@ -1215,7 +1215,7 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl)
break;
}
- ret = snd_soc_add_codec_controls(dsp->codec, kcontrol, 1);
+ ret = snd_soc_add_component_controls(dsp->component, kcontrol, 1);
if (ret < 0)
goto err_kcontrol;
@@ -1239,9 +1239,16 @@ 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);
- if (ret < 0)
- return ret;
+ /*
+ * For readable controls populate the cache from the DSP memory.
+ * For non-readable controls the cache was zero-filled when
+ * created so we don't need to do anything.
+ */
+ if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) {
+ ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
+ if (ret < 0)
+ return ret;
+ }
}
return 0;
@@ -2398,14 +2405,14 @@ int wm_adsp1_event(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 wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct wm_adsp *dsps = snd_soc_component_get_drvdata(component);
struct wm_adsp *dsp = &dsps[w->shift];
struct wm_coeff_ctl *ctl;
int ret;
unsigned int val;
- dsp->codec = codec;
+ dsp->component = component;
mutex_lock(&dsp->pwr_lock);
@@ -2635,8 +2642,8 @@ static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq)
int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
- struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+ struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
ucontrol->value.integer.value[0] = dsp->preloaded;
@@ -2647,9 +2654,9 @@ EXPORT_SYMBOL_GPL(wm_adsp2_preloader_get);
int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
- struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+ struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
+ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
char preload[32];
@@ -2685,8 +2692,8 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
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);
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct wm_adsp *dsps = snd_soc_component_get_drvdata(component);
struct wm_adsp *dsp = &dsps[w->shift];
struct wm_coeff_ctl *ctl;
@@ -2728,8 +2735,8 @@ EXPORT_SYMBOL_GPL(wm_adsp2_early_event);
int wm_adsp2_event(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 wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct wm_adsp *dsps = snd_soc_component_get_drvdata(component);
struct wm_adsp *dsp = &dsps[w->shift];
int ret;
@@ -2843,31 +2850,31 @@ err:
}
EXPORT_SYMBOL_GPL(wm_adsp2_event);
-int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec)
+int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component)
{
- struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
char preload[32];
snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", dsp->num);
snd_soc_dapm_disable_pin(dapm, preload);
- wm_adsp2_init_debugfs(dsp, codec);
+ wm_adsp2_init_debugfs(dsp, component);
- dsp->codec = codec;
+ dsp->component = component;
- return snd_soc_add_codec_controls(codec,
+ return snd_soc_add_component_controls(component,
&wm_adsp_fw_controls[dsp->num - 1],
1);
}
-EXPORT_SYMBOL_GPL(wm_adsp2_codec_probe);
+EXPORT_SYMBOL_GPL(wm_adsp2_component_probe);
-int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec)
+int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component)
{
wm_adsp2_cleanup_debugfs(dsp);
return 0;
}
-EXPORT_SYMBOL_GPL(wm_adsp2_codec_remove);
+EXPORT_SYMBOL_GPL(wm_adsp2_component_remove);
int wm_adsp2_init(struct wm_adsp *dsp)
{
@@ -3253,6 +3260,13 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf)
return 0;
}
+static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf)
+{
+ buf->irq_count = 0xFFFFFFFF;
+ buf->read_index = -1;
+ buf->avail = 0;
+}
+
static int wm_adsp_buffer_init(struct wm_adsp *dsp)
{
struct wm_adsp_compr_buf *buf;
@@ -3263,8 +3277,8 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp)
return -ENOMEM;
buf->dsp = dsp;
- buf->read_index = -1;
- buf->irq_count = 0xFFFFFFFF;
+
+ wm_adsp_buffer_clear(buf);
ret = wm_adsp_buffer_locate(buf);
if (ret < 0) {
@@ -3322,16 +3336,17 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd)
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- if (wm_adsp_compr_attached(compr))
- break;
-
- ret = wm_adsp_compr_attach(compr);
- if (ret < 0) {
- adsp_err(dsp, "Failed to link buffer and stream: %d\n",
- ret);
- break;
+ if (!wm_adsp_compr_attached(compr)) {
+ ret = wm_adsp_compr_attach(compr);
+ if (ret < 0) {
+ adsp_err(dsp, "Failed to link buffer and stream: %d\n",
+ ret);
+ break;
+ }
}
+ wm_adsp_buffer_clear(compr->buf);
+
/* Trigger the IRQ at one fragment of data */
ret = wm_adsp_buffer_write(compr->buf,
HOST_BUFFER_FIELD(high_water_mark),