* [PATCH v4 0/5] ASoC: Move IO and kcontrols to the component level
@ 2014-04-22 11:23 Lars-Peter Clausen
2014-04-22 11:23 ` [PATCH v4 1/5] ASoC: Move IO abstraction " Lars-Peter Clausen
` (4 more replies)
0 siblings, 5 replies; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-04-22 11:23 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen
Changes since v3:
* Removed the omap-hdmi compile fix that slipped in by accident.
v3 cover letter:
The only change in v3 is the renaming of the component IO mutex from 'mutex' to
'io_mutex'.
v2 cover letter:
This series contains the remaining patches from the previous series that have
not been applied yet. The series has been rebased ontop of asoc/for-next and
depends on topic/sta350, topic/core, topic/dapm, topic/cache and
topic/component.
Some minor updates were made to the patches and three new patches:
* One new user of snd_kcontrol_chip() showed up, the patch converts it to
snd_soc_kcontrol_codec()
* Change return type of snd_soc_write() from unsigned int to int
* Remove ASoC level tracing
Original cover letter:
This series is the first step towards full componentisation of the ASoC core. It
moves both the IO abstraction layers within ASoC as well as the standard set of
kcontrols to the component level. This for example means we can get rid of
constructs like
if (w->codec)
snd_soc_read(....)
else if(w->platform)
snd_soc_platform_read(...)
Moving the kcontrols to the component level means we can use the same
implementation also for other non-CODEC components. E.g. there seems to be an
increasing amount of CPU components that have basic signal processing and things
like volume controls etc. whose register layout is similar to those used in
CODECs. Currently each CPU component driver re-implements these controls by
hand.
The first two patches introduce two new helper functions which hide the actual
implementation on how the CODEC or platform struct that register a control can
be obtained from the control. This means that when the actual implementation is
changed only the two helper functions need to be updated and not every single
driver. The patches that follow that are just cleanups removing unused IO stuff
and move all IO functions to soc-io.c. The next step is to make platforms also
components. And then finally first the IO abstraction layers in ASoC are unified
at the component level and then on top of that the kcontrol helpers are moved to
the component level.
The series depends on quite a few topic branches related to changes to the core
and cleanups for individual drivers. It is probably best to place it on top of
asoc-v3.15-2. The patch that moves the kcontrols to the component level also has
a runtime dependency on the not yet applied patches that move the ams-delta and
mfld_machine controls to the card level.
Lars-Peter Clausen (5):
ASoC: Move IO abstraction to the component level
ASoC: Move standard kcontrol helpers to the component level
ASoC: Remove snd_soc_update_bits_locked()
ASoC: dapm: Rename soc_widget_update_bits_locked() to
soc_widget_update_bits()
ASoC: Remove ASoC level IO tracing
include/sound/soc-dapm.h | 1 +
include/sound/soc.h | 51 +++++--
include/trace/events/asoc.h | 92 -------------
sound/soc/soc-core.c | 285 +++++++++++++++++++++++++-------------
sound/soc/soc-dapm.c | 91 ++----------
sound/soc/soc-io.c | 327 ++++++++++++++++++++++++++------------------
6 files changed, 447 insertions(+), 400 deletions(-)
--
1.8.0
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v4 1/5] ASoC: Move IO abstraction to the component level
2014-04-22 11:23 [PATCH v4 0/5] ASoC: Move IO and kcontrols to the component level Lars-Peter Clausen
@ 2014-04-22 11:23 ` Lars-Peter Clausen
2014-04-22 12:24 ` Mark Brown
2014-04-22 11:23 ` [PATCH v4 2/5] ASoC: Move standard kcontrol helpers " Lars-Peter Clausen
` (3 subsequent siblings)
4 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-04-22 11:23 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen
We currently have two very similar IO abstractions in ASoC, one for CODECs, the
other for platforms. Moving this to the component level will allow us to unify
those two. It will also enable us to move the standard kcontrol helpers as well
as DAPM support to the component level.
The new component level abstraction layer is primarily build around regmap.
There is a per component pointer for the regmap instance for the underlying
device. There are four new function snd_soc_component_read(),
snd_soc_component_write(), snd_soc_component_update_bits() and
snd_soc_component_update_bits_async(). They have the same signature as their
regmap counter-part and will internally forward the call one-to-one to regmap.
If the component it not using regmap it will fallback to using the custom IO
callbacks. This is done to be able to support drivers that haven't been
converted to regmap yet, but it is expected that this will eventually be removed
in the future once all component drivers have been converted to regmap.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
Changes since v2:
* Rename mutex to io_mutex
Changes since v1:
* Rebased onto asoc/for-next
* Add kernel doc for the new functions
* Rename snd_soc_component_set_cache_io() to snd_soc_component_init_io()
* Removed stubbed out version of snd_soc_component_init_io(), the only
regmap function in there that we use is regmap_get_val_bytes() and
that is already stubbed out perfectly fine by the regmap code (and
given that almost all CODECs require regmap chances that we build
without regmap support in the first place are quite low).
---
include/sound/soc-dapm.h | 1 +
include/sound/soc.h | 31 +++--
sound/soc/soc-core.c | 96 ++++++++++----
sound/soc/soc-dapm.c | 84 ++-----------
sound/soc/soc-io.c | 322 ++++++++++++++++++++++++++++++-----------------
5 files changed, 317 insertions(+), 217 deletions(-)
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 5ec03b5..b041fc6 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -594,6 +594,7 @@ struct snd_soc_dapm_context {
enum snd_soc_dapm_type, int);
struct device *dev; /* from parent - for debug */
+ struct snd_soc_component *component; /* parent component */
struct snd_soc_codec *codec; /* parent codec */
struct snd_soc_platform *platform; /* parent platform */
struct snd_soc_card *card; /* parent card */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index de62475..554c650 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -393,8 +393,6 @@ int devm_snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *cmpnt_drv,
struct snd_soc_dai_driver *dai_drv, int num_dai);
void snd_soc_unregister_component(struct device *dev);
-int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
- struct regmap *regmap);
int snd_soc_cache_sync(struct snd_soc_codec *codec);
int snd_soc_cache_init(struct snd_soc_codec *codec);
int snd_soc_cache_exit(struct snd_soc_codec *codec);
@@ -672,6 +670,14 @@ struct snd_soc_component {
const struct snd_soc_component_driver *driver;
struct list_head dai_list;
+
+ int (*read)(struct snd_soc_component *, unsigned int, unsigned int *);
+ int (*write)(struct snd_soc_component *, unsigned int, unsigned int);
+
+ struct regmap *regmap;
+ int val_bytes;
+
+ struct mutex io_mutex;
};
/* SoC Audio Codec device */
@@ -696,18 +702,14 @@ struct snd_soc_codec {
unsigned int ac97_registered:1; /* Codec has been AC97 registered */
unsigned int ac97_created:1; /* Codec has been created by SoC */
unsigned int cache_init:1; /* codec cache has been initialized */
- unsigned int using_regmap:1; /* using regmap access */
u32 cache_only; /* Suppress writes to hardware */
u32 cache_sync; /* Cache needs to be synced to hardware */
/* codec IO */
void *control_data; /* codec control (i2c/3wire) data */
hw_write_t hw_write;
- unsigned int (*read)(struct snd_soc_codec *, unsigned int);
- int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
void *reg_cache;
struct mutex cache_rw_mutex;
- int val_bytes;
/* component */
struct snd_soc_component component;
@@ -824,7 +826,6 @@ struct snd_soc_platform {
int id;
struct device *dev;
const struct snd_soc_platform_driver *driver;
- struct mutex mutex;
unsigned int suspended:1; /* platform is suspended */
unsigned int probed:1;
@@ -1129,6 +1130,22 @@ unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int val);
+/* component IO */
+int snd_soc_component_read(struct snd_soc_component *component,
+ unsigned int reg, unsigned int *val);
+int snd_soc_component_write(struct snd_soc_component *component,
+ unsigned int reg, unsigned int val);
+int snd_soc_component_update_bits(struct snd_soc_component *component,
+ unsigned int reg, unsigned int mask, unsigned int val);
+int snd_soc_component_update_bits_async(struct snd_soc_component *component,
+ unsigned int reg, unsigned int mask, unsigned int val);
+void snd_soc_component_async_complete(struct snd_soc_component *component);
+int snd_soc_component_test_bits(struct snd_soc_component *component,
+ unsigned int reg, unsigned int mask, unsigned int value);
+
+int snd_soc_component_init_io(struct snd_soc_component *component,
+ struct regmap *regmap);
+
/* device driver data */
static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a17c047..df3e293 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -656,8 +656,8 @@ int snd_soc_suspend(struct device *dev)
codec->driver->suspend(codec);
codec->suspended = 1;
codec->cache_sync = 1;
- if (codec->using_regmap)
- regcache_mark_dirty(codec->control_data);
+ if (codec->component.regmap)
+ regcache_mark_dirty(codec->component.regmap);
/* deactivate pins to sleep state */
pinctrl_pm_select_sleep_state(codec->dev);
break;
@@ -3033,7 +3033,7 @@ int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
struct soc_bytes *params = (void *)kcontrol->private_value;
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = params->num_regs * codec->val_bytes;
+ uinfo->count = params->num_regs * codec->component.val_bytes;
return 0;
}
@@ -3046,16 +3046,16 @@ int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
int ret;
- if (codec->using_regmap)
- ret = regmap_raw_read(codec->control_data, params->base,
+ if (codec->component.regmap)
+ ret = regmap_raw_read(codec->component.regmap, params->base,
ucontrol->value.bytes.data,
- params->num_regs * codec->val_bytes);
+ params->num_regs * codec->component.val_bytes);
else
ret = -EINVAL;
/* Hide any masked bytes to ensure consistent data reporting */
if (ret == 0 && params->mask) {
- switch (codec->val_bytes) {
+ switch (codec->component.val_bytes) {
case 1:
ucontrol->value.bytes.data[0] &= ~params->mask;
break;
@@ -3085,10 +3085,10 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
unsigned int val, mask;
void *data;
- if (!codec->using_regmap)
+ if (!codec->component.regmap)
return -EINVAL;
- len = params->num_regs * codec->val_bytes;
+ len = params->num_regs * codec->component.val_bytes;
data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
if (!data)
@@ -3100,27 +3100,27 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
* copy.
*/
if (params->mask) {
- ret = regmap_read(codec->control_data, params->base, &val);
+ ret = regmap_read(codec->component.regmap, params->base, &val);
if (ret != 0)
goto out;
val &= params->mask;
- switch (codec->val_bytes) {
+ switch (codec->component.val_bytes) {
case 1:
((u8 *)data)[0] &= ~params->mask;
((u8 *)data)[0] |= val;
break;
case 2:
mask = ~params->mask;
- ret = regmap_parse_val(codec->control_data,
+ ret = regmap_parse_val(codec->component.regmap,
&mask, &mask);
if (ret != 0)
goto out;
((u16 *)data)[0] &= mask;
- ret = regmap_parse_val(codec->control_data,
+ ret = regmap_parse_val(codec->component.regmap,
&val, &val);
if (ret != 0)
goto out;
@@ -3129,14 +3129,14 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
break;
case 4:
mask = ~params->mask;
- ret = regmap_parse_val(codec->control_data,
+ ret = regmap_parse_val(codec->component.regmap,
&mask, &mask);
if (ret != 0)
goto out;
((u32 *)data)[0] &= mask;
- ret = regmap_parse_val(codec->control_data,
+ ret = regmap_parse_val(codec->component.regmap,
&val, &val);
if (ret != 0)
goto out;
@@ -3149,7 +3149,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
}
}
- ret = regmap_raw_write(codec->control_data, params->base,
+ ret = regmap_raw_write(codec->component.regmap, params->base,
data, len);
out:
@@ -3205,7 +3205,7 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int regbase = mc->regbase;
unsigned int regcount = mc->regcount;
- unsigned int regwshift = codec->val_bytes * BITS_PER_BYTE;
+ unsigned int regwshift = codec->component.val_bytes * BITS_PER_BYTE;
unsigned int regwmask = (1<<regwshift)-1;
unsigned int invert = mc->invert;
unsigned long mask = (1UL<<mc->nbits)-1;
@@ -3251,7 +3251,7 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int regbase = mc->regbase;
unsigned int regcount = mc->regcount;
- unsigned int regwshift = codec->val_bytes * BITS_PER_BYTE;
+ unsigned int regwshift = codec->component.val_bytes * BITS_PER_BYTE;
unsigned int regwmask = (1<<regwshift)-1;
unsigned int invert = mc->invert;
unsigned long mask = (1UL<<mc->nbits)-1;
@@ -3899,6 +3899,8 @@ __snd_soc_register_component(struct device *dev,
return -ENOMEM;
}
+ mutex_init(&cmpnt->io_mutex);
+
cmpnt->name = fmt_single_name(dev, &cmpnt->id);
if (!cmpnt->name) {
dev_err(dev, "ASoC: Failed to simplifying name\n");
@@ -3979,6 +3981,24 @@ found:
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
+static int snd_soc_platform_drv_write(struct snd_soc_component *component,
+ unsigned int reg, unsigned int val)
+{
+ struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+ return platform->driver->write(platform, reg, val);
+}
+
+static int snd_soc_platform_drv_read(struct snd_soc_component *component,
+ unsigned int reg, unsigned int *val)
+{
+ struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+ *val = platform->driver->read(platform, reg);
+
+ return 0;
+}
+
/**
* snd_soc_add_platform - Add a platform to the ASoC core
* @dev: The parent device for the platform
@@ -3999,8 +4019,12 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
platform->driver = platform_drv;
platform->dapm.dev = dev;
platform->dapm.platform = platform;
+ platform->dapm.component = &platform->component;
platform->dapm.stream_event = platform_drv->stream_event;
- mutex_init(&platform->mutex);
+ if (platform_drv->write)
+ platform->component.write = snd_soc_platform_drv_write;
+ if (platform_drv->read)
+ platform->component.read = snd_soc_platform_drv_read;
/* register component */
ret = __snd_soc_register_component(dev, &platform->component,
@@ -4129,6 +4153,24 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
stream->formats |= codec_format_map[i];
}
+static int snd_soc_codec_drv_write(struct snd_soc_component *component,
+ unsigned int reg, unsigned int val)
+{
+ struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
+
+ return codec->driver->write(codec, reg, val);
+}
+
+static int snd_soc_codec_drv_read(struct snd_soc_component *component,
+ unsigned int reg, unsigned int *val)
+{
+ struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
+
+ *val = codec->driver->read(codec, reg);
+
+ return 0;
+}
+
/**
* snd_soc_register_codec - Register a codec with the ASoC core
*
@@ -4156,29 +4198,33 @@ int snd_soc_register_codec(struct device *dev,
goto fail_codec;
}
- codec->write = codec_drv->write;
- codec->read = codec_drv->read;
+ if (codec_drv->write)
+ codec->component.write = snd_soc_codec_drv_write;
+ if (codec_drv->read)
+ codec->component.read = snd_soc_codec_drv_read;
codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
codec->dapm.bias_level = SND_SOC_BIAS_OFF;
codec->dapm.dev = dev;
codec->dapm.codec = codec;
+ codec->dapm.component = &codec->component;
codec->dapm.seq_notifier = codec_drv->seq_notifier;
codec->dapm.stream_event = codec_drv->stream_event;
codec->dev = dev;
codec->driver = codec_drv;
codec->num_dai = num_dai;
- codec->val_bytes = codec_drv->reg_word_size;
+ codec->component.val_bytes = codec_drv->reg_word_size;
mutex_init(&codec->mutex);
- if (!codec->write) {
+ if (!codec->component.write) {
if (codec_drv->get_regmap)
regmap = codec_drv->get_regmap(dev);
else
regmap = dev_get_regmap(dev, NULL);
if (regmap) {
- ret = snd_soc_codec_set_cache_io(codec, regmap);
- if (ret && ret != -ENOTSUPP) {
+ ret = snd_soc_component_init_io(&codec->component,
+ regmap);
+ if (ret) {
dev_err(codec->dev,
"Failed to set cache I/O:%d\n",
ret);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index cdd5115..85a594f 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -378,86 +378,24 @@ static void dapm_reset(struct snd_soc_card *card)
static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg,
unsigned int *value)
{
- if (w->codec) {
- *value = snd_soc_read(w->codec, reg);
- return 0;
- } else if (w->platform) {
- *value = snd_soc_platform_read(w->platform, reg);
- return 0;
- }
-
- dev_err(w->dapm->dev, "ASoC: no valid widget read method\n");
- return -1;
-}
-
-static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg,
- unsigned int val)
-{
- if (w->codec)
- return snd_soc_write(w->codec, reg, val);
- else if (w->platform)
- return snd_soc_platform_write(w->platform, reg, val);
-
- dev_err(w->dapm->dev, "ASoC: no valid widget write method\n");
- return -1;
-}
-
-static inline void soc_widget_lock(struct snd_soc_dapm_widget *w)
-{
- if (w->codec && !w->codec->using_regmap)
- mutex_lock(&w->codec->mutex);
- else if (w->platform)
- mutex_lock(&w->platform->mutex);
+ if (!w->dapm->component)
+ return -EIO;
+ return snd_soc_component_read(w->dapm->component, reg, value);
}
-static inline void soc_widget_unlock(struct snd_soc_dapm_widget *w)
+static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
+ int reg, unsigned int mask, unsigned int value)
{
- if (w->codec && !w->codec->using_regmap)
- mutex_unlock(&w->codec->mutex);
- else if (w->platform)
- mutex_unlock(&w->platform->mutex);
+ if (!w->dapm->component)
+ return -EIO;
+ return snd_soc_component_update_bits_async(w->dapm->component, reg,
+ mask, value);
}
static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm)
{
- if (dapm->codec && dapm->codec->using_regmap)
- regmap_async_complete(dapm->codec->control_data);
-}
-
-static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
- int reg, unsigned int mask, unsigned int value)
-{
- bool change;
- unsigned int old, new;
- int ret;
-
- if (w->codec && w->codec->using_regmap) {
- ret = regmap_update_bits_check_async(w->codec->control_data,
- reg, mask, value,
- &change);
- if (ret != 0)
- return ret;
- } else {
- soc_widget_lock(w);
- ret = soc_widget_read(w, reg, &old);
- if (ret < 0) {
- soc_widget_unlock(w);
- return ret;
- }
-
- new = (old & ~mask) | (value & mask);
- change = old != new;
- if (change) {
- ret = soc_widget_write(w, reg, new);
- if (ret < 0) {
- soc_widget_unlock(w);
- return ret;
- }
- }
- soc_widget_unlock(w);
- }
-
- return change;
+ if (dapm->component)
+ snd_soc_component_async_complete(dapm->component);
}
/**
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index dc0c09d..ac64fd7 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -19,24 +19,205 @@
#include <trace/events/asoc.h>
-unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
+/**
+ * snd_soc_component_read() - Read register value
+ * @component: Component to read from
+ * @reg: Register to read
+ * @val: Pointer to where the read value is stored
+ *
+ * Return: 0 on success, a negative error code otherwise.
+ */
+int snd_soc_component_read(struct snd_soc_component *component,
+ unsigned int reg, unsigned int *val)
+{
+ int ret;
+
+ if (component->regmap)
+ ret = regmap_read(component->regmap, reg, val);
+ else if (component->read)
+ ret = component->read(component, reg, val);
+ else
+ ret = -EIO;
+
+ dev_dbg(component->dev, "read %x => %x\n", reg, *val);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(snd_soc_component_read);
+
+/**
+ * snd_soc_component_write() - Write register value
+ * @component: Component to write to
+ * @reg: Register to write
+ * @val: Value to write to the register
+ *
+ * Return: 0 on success, a negative error code otherwise.
+ */
+int snd_soc_component_write(struct snd_soc_component *component,
+ unsigned int reg, unsigned int val)
{
- unsigned int ret;
+ dev_dbg(component->dev, "write %x = %x\n", reg, val);
- ret = codec->read(codec, reg);
- dev_dbg(codec->dev, "read %x => %x\n", reg, ret);
- trace_snd_soc_reg_read(codec, reg, ret);
+ if (component->regmap)
+ return regmap_write(component->regmap, reg, val);
+ else if (component->write)
+ return component->write(component, reg, val);
+ else
+ return -EIO;
+}
+EXPORT_SYMBOL_GPL(snd_soc_component_write);
+
+static int snd_soc_component_update_bits_legacy(
+ struct snd_soc_component *component, unsigned int reg,
+ unsigned int mask, unsigned int val, bool *change)
+{
+ unsigned int old, new;
+ int ret;
+
+ if (!component->read || !component->write)
+ return -EIO;
+
+ mutex_lock(&component->io_mutex);
+
+ ret = component->read(component, reg, &old);
+ if (ret < 0)
+ goto out_unlock;
+
+ new = (old & ~mask) | (val & mask);
+ *change = old != new;
+ if (*change)
+ ret = component->write(component, reg, new);
+out_unlock:
+ mutex_unlock(&component->io_mutex);
return ret;
}
+
+/**
+ * snd_soc_component_update_bits() - Perform read/modify/write cycle
+ * @component: Component to update
+ * @reg: Register to update
+ * @mask: Mask that specifies which bits to update
+ * @val: New value for the bits specified by mask
+ *
+ * Return: 1 if the operation was successful and the value of the register
+ * changed, 0 if the operation was successful, but the value did not change.
+ * Returns a negative error code otherwise.
+ */
+int snd_soc_component_update_bits(struct snd_soc_component *component,
+ unsigned int reg, unsigned int mask, unsigned int val)
+{
+ bool change;
+ int ret;
+
+ if (component->regmap)
+ ret = regmap_update_bits_check(component->regmap, reg, mask,
+ val, &change);
+ else
+ ret = snd_soc_component_update_bits_legacy(component, reg,
+ mask, val, &change);
+
+ if (ret < 0)
+ return ret;
+ return change;
+}
+EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
+
+/**
+ * snd_soc_component_update_bits_async() - Perform asynchronous
+ * read/modify/write cycle
+ * @component: Component to update
+ * @reg: Register to update
+ * @mask: Mask that specifies which bits to update
+ * @val: New value for the bits specified by mask
+ *
+ * This function is similar to snd_soc_component_update_bits(), but the update
+ * operation is scheduled asynchronously. This means it may not be completed
+ * when the function returns. To make sure that all scheduled updates have been
+ * completed snd_soc_component_async_complete() must be called.
+ *
+ * Return: 1 if the operation was successful and the value of the register
+ * changed, 0 if the operation was successful, but the value did not change.
+ * Returns a negative error code otherwise.
+ */
+int snd_soc_component_update_bits_async(struct snd_soc_component *component,
+ unsigned int reg, unsigned int mask, unsigned int val)
+{
+ bool change;
+ int ret;
+
+ if (component->regmap)
+ ret = regmap_update_bits_check_async(component->regmap, reg,
+ mask, val, &change);
+ else
+ ret = snd_soc_component_update_bits_legacy(component, reg,
+ mask, val, &change);
+
+ if (ret < 0)
+ return ret;
+ return change;
+}
+EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
+
+/**
+ * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
+ * @component: Component for which to wait
+ *
+ * This function blocks until all asynchronous I/O which has previously been
+ * scheduled using snd_soc_component_update_bits_async() has completed.
+ */
+void snd_soc_component_async_complete(struct snd_soc_component *component)
+{
+ if (component->regmap)
+ regmap_async_complete(component->regmap);
+}
+EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
+
+/**
+ * snd_soc_component_test_bits - Test register for change
+ * @component: component
+ * @reg: Register to test
+ * @mask: Mask that specifies which bits to test
+ * @value: Value to test against
+ *
+ * Tests a register with a new value and checks if the new value is
+ * different from the old value.
+ *
+ * Return: 1 for change, otherwise 0.
+ */
+int snd_soc_component_test_bits(struct snd_soc_component *component,
+ unsigned int reg, unsigned int mask, unsigned int value)
+{
+ unsigned int old, new;
+ int ret;
+
+ ret = snd_soc_component_read(component, reg, &old);
+ if (ret < 0)
+ return ret;
+ new = (old & ~mask) | value;
+ return old != new;
+}
+EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
+
+unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
+{
+ unsigned int val;
+ int ret;
+
+ ret = snd_soc_component_read(&codec->component, reg, &val);
+ if (ret < 0)
+ return -1;
+ trace_snd_soc_reg_read(codec, reg, val);
+
+ return val;
+}
EXPORT_SYMBOL_GPL(snd_soc_read);
int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int val)
{
- dev_dbg(codec->dev, "write %x = %x\n", reg, val);
trace_snd_soc_reg_write(codec, reg, val);
- return codec->write(codec, reg, val);
+ return snd_soc_component_write(&codec->component, reg, val);
}
EXPORT_SYMBOL_GPL(snd_soc_write);
@@ -54,29 +235,8 @@ EXPORT_SYMBOL_GPL(snd_soc_write);
int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
unsigned int mask, unsigned int value)
{
- bool change;
- unsigned int old, new;
- int ret;
-
- if (codec->using_regmap) {
- ret = regmap_update_bits_check(codec->control_data, reg,
- mask, value, &change);
- } else {
- ret = snd_soc_read(codec, reg);
- if (ret < 0)
- return ret;
-
- old = ret;
- new = (old & ~mask) | (value & mask);
- change = old != new;
- if (change)
- ret = snd_soc_write(codec, reg, new);
- }
-
- if (ret < 0)
- return ret;
-
- return change;
+ return snd_soc_component_update_bits(&codec->component, reg, mask,
+ value);
}
EXPORT_SYMBOL_GPL(snd_soc_update_bits);
@@ -95,13 +255,8 @@ int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
unsigned int reg, unsigned int mask,
unsigned int value)
{
- int change;
-
- mutex_lock(&codec->mutex);
- change = snd_soc_update_bits(codec, reg, mask, value);
- mutex_unlock(&codec->mutex);
-
- return change;
+ return snd_soc_component_update_bits(&codec->component, reg, mask,
+ value);
}
EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked);
@@ -120,115 +275,58 @@ EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked);
int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
unsigned int mask, unsigned int value)
{
- int change;
- unsigned int old, new;
-
- old = snd_soc_read(codec, reg);
- new = (old & ~mask) | value;
- change = old != new;
-
- return change;
+ return snd_soc_component_test_bits(&codec->component, reg, mask, value);
}
EXPORT_SYMBOL_GPL(snd_soc_test_bits);
int snd_soc_platform_read(struct snd_soc_platform *platform,
unsigned int reg)
{
- unsigned int ret;
+ unsigned int val;
+ int ret;
- if (!platform->driver->read) {
- dev_err(platform->dev, "ASoC: platform has no read back\n");
+ ret = snd_soc_component_read(&platform->component, reg, &val);
+ if (ret < 0)
return -1;
- }
- ret = platform->driver->read(platform, reg);
- dev_dbg(platform->dev, "read %x => %x\n", reg, ret);
- trace_snd_soc_preg_read(platform, reg, ret);
+ trace_snd_soc_preg_read(platform, reg, val);
- return ret;
+ return val;
}
EXPORT_SYMBOL_GPL(snd_soc_platform_read);
int snd_soc_platform_write(struct snd_soc_platform *platform,
unsigned int reg, unsigned int val)
{
- if (!platform->driver->write) {
- dev_err(platform->dev, "ASoC: platform has no write back\n");
- return -1;
- }
-
- dev_dbg(platform->dev, "write %x = %x\n", reg, val);
trace_snd_soc_preg_write(platform, reg, val);
- return platform->driver->write(platform, reg, val);
+ return snd_soc_component_write(&platform->component, reg, val);
}
EXPORT_SYMBOL_GPL(snd_soc_platform_write);
-#ifdef CONFIG_REGMAP
-static int hw_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- return regmap_write(codec->control_data, reg, value);
-}
-
-static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
-{
- int ret;
- unsigned int val;
-
- ret = regmap_read(codec->control_data, reg, &val);
- if (ret == 0)
- return val;
- else
- return -1;
-}
-
/**
- * snd_soc_codec_set_cache_io: Set up standard I/O functions.
- *
- * @codec: CODEC to configure.
- * @map: Register map to write to
+ * snd_soc_component_init_io() - Initialize regmap IO
*
- * Register formats are frequently shared between many I2C and SPI
- * devices. In order to promote code reuse the ASoC core provides
- * some standard implementations of CODEC read and write operations
- * which can be set up using this function.
+ * @component: component to initialize
+ * @regmap: regmap instance to use for IO operations
*
- * The caller is responsible for allocating and initialising the
- * actual cache.
- *
- * Note that at present this code cannot be used by CODECs with
- * volatile registers.
+ * Return: 0 on success, a negative error code otherwise
*/
-int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
- struct regmap *regmap)
+int snd_soc_component_init_io(struct snd_soc_component *component,
+ struct regmap *regmap)
{
int ret;
if (!regmap)
return -EINVAL;
- /* Device has made its own regmap arrangements */
- codec->control_data = regmap;
-
- codec->write = hw_write;
- codec->read = hw_read;
-
- ret = regmap_get_val_bytes(codec->control_data);
+ ret = regmap_get_val_bytes(regmap);
/* Errors are legitimate for non-integer byte
* multiples */
if (ret > 0)
- codec->val_bytes = ret;
+ component->val_bytes = ret;
- codec->using_regmap = true;
+ component->regmap = regmap;
return 0;
}
-EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
-#else
-int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
- struct regmap *regmap)
-{
- return -ENOTSUPP;
-}
-EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
-#endif
+EXPORT_SYMBOL_GPL(snd_soc_component_init_io);
--
1.8.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-04-22 11:23 [PATCH v4 0/5] ASoC: Move IO and kcontrols to the component level Lars-Peter Clausen
2014-04-22 11:23 ` [PATCH v4 1/5] ASoC: Move IO abstraction " Lars-Peter Clausen
@ 2014-04-22 11:23 ` Lars-Peter Clausen
2014-04-22 12:38 ` Mark Brown
2014-05-09 15:00 ` Shawn Guo
2014-04-22 11:23 ` [PATCH v4 3/5] ASoC: Remove snd_soc_update_bits_locked() Lars-Peter Clausen
` (2 subsequent siblings)
4 siblings, 2 replies; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-04-22 11:23 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen
After moving the IO layer inside ASoC to the component level we can now easily
move the standard control helpers also to the component level. This allows to
reuse the same standard helper control implementations for other components.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
include/sound/soc.h | 20 ++++-
sound/soc/soc-core.c | 221 ++++++++++++++++++++++++++++++++-------------------
2 files changed, 156 insertions(+), 85 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 554c650..19a82ce 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1250,6 +1250,22 @@ static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec)
}
/**
+ * snd_soc_kcontrol_component() - Returns the component that registered the
+ * control
+ * @kcontrol: The control for which to get the component
+ *
+ * Note: This function will work correctly if the control has been registered
+ * for a component. Either with snd_soc_add_codec_controls() or
+ * snd_soc_add_platform_controls() or via table based setup for either a
+ * CODEC, a platform or component driver. Otherwise the behavior is undefined.
+ */
+static inline struct snd_soc_component *snd_soc_kcontrol_component(
+ struct snd_kcontrol *kcontrol)
+{
+ return snd_kcontrol_chip(kcontrol);
+}
+
+/**
* snd_soc_kcontrol_codec() - Returns the CODEC that registered the control
* @kcontrol: The control for which to get the CODEC
*
@@ -1260,7 +1276,7 @@ static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec)
static inline struct snd_soc_codec *snd_soc_kcontrol_codec(
struct snd_kcontrol *kcontrol)
{
- return snd_kcontrol_chip(kcontrol);
+ return snd_soc_component_to_codec(snd_soc_kcontrol_component(kcontrol));
}
/**
@@ -1274,7 +1290,7 @@ static inline struct snd_soc_codec *snd_soc_kcontrol_codec(
static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
struct snd_kcontrol *kcontrol)
{
- return snd_kcontrol_chip(kcontrol);
+ return snd_soc_component_to_platform(snd_soc_kcontrol_component(kcontrol));
}
int snd_soc_util_init(void);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index df3e293..d5cd80b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2353,7 +2353,7 @@ int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
struct snd_card *card = codec->card->snd_card;
return snd_soc_add_controls(card, codec->dev, controls, num_controls,
- codec->name_prefix, codec);
+ codec->name_prefix, &codec->component);
}
EXPORT_SYMBOL_GPL(snd_soc_add_codec_controls);
@@ -2373,7 +2373,7 @@ int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
struct snd_card *card = platform->card->snd_card;
return snd_soc_add_controls(card, platform->dev, controls, num_controls,
- NULL, platform);
+ NULL, &platform->component);
}
EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls);
@@ -2457,12 +2457,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_enum_double);
int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val, item;
unsigned int reg_val;
+ int ret;
- reg_val = snd_soc_read(codec, e->reg);
+ ret = snd_soc_component_read(component, e->reg, ®_val);
+ if (ret)
+ return ret;
val = (reg_val >> e->shift_l) & e->mask;
item = snd_soc_enum_val_to_item(e, val);
ucontrol->value.enumerated.item[0] = item;
@@ -2488,7 +2491,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_enum_double);
int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int *item = ucontrol->value.enumerated.item;
unsigned int val;
@@ -2505,38 +2508,48 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
mask |= e->mask << e->shift_r;
}
- return snd_soc_update_bits_locked(codec, e->reg, mask, val);
+ return snd_soc_component_update_bits(component, e->reg, mask, val);
}
EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
/**
* snd_soc_read_signed - Read a codec register and interprete as signed value
- * @codec: codec
+ * @component: component
* @reg: Register to read
* @mask: Mask to use after shifting the register value
* @shift: Right shift of register value
* @sign_bit: Bit that describes if a number is negative or not.
+ * @signed_val: Pointer to where the read value should be stored
*
* This functions reads a codec register. The register value is shifted right
* by 'shift' bits and masked with the given 'mask'. Afterwards it translates
* the given registervalue into a signed integer if sign_bit is non-zero.
*
- * Returns the register value as signed int.
+ * Returns 0 on sucess, otherwise an error value
*/
-static int snd_soc_read_signed(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int mask, unsigned int shift, unsigned int sign_bit)
+static int snd_soc_read_signed(struct snd_soc_component *component,
+ unsigned int reg, unsigned int mask, unsigned int shift,
+ unsigned int sign_bit, int *signed_val)
{
int ret;
unsigned int val;
- val = (snd_soc_read(codec, reg) >> shift) & mask;
+ ret = snd_soc_component_read(component, reg, &val);
+ if (ret < 0)
+ return ret;
+
+ val = (val >> shift) & mask;
- if (!sign_bit)
- return val;
+ if (!sign_bit) {
+ *signed_val = val;
+ return 0;
+ }
/* non-negative number */
- if (!(val & BIT(sign_bit)))
- return val;
+ if (!(val & BIT(sign_bit))) {
+ *signed_val = val;
+ return 0;
+ }
ret = val;
@@ -2548,7 +2561,9 @@ static int snd_soc_read_signed(struct snd_soc_codec *codec, unsigned int reg,
*/
ret |= ~((int)(BIT(sign_bit) - 1));
- return ret;
+ *signed_val = ret;
+
+ return 0;
}
/**
@@ -2597,9 +2612,9 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int reg = mc->reg;
unsigned int reg2 = mc->rreg;
unsigned int shift = mc->shift;
@@ -2609,25 +2624,32 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
int sign_bit = mc->sign_bit;
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
+ int val;
+ int ret;
if (sign_bit)
mask = BIT(sign_bit + 1) - 1;
- ucontrol->value.integer.value[0] = snd_soc_read_signed(codec, reg, mask,
- shift, sign_bit) - min;
+ ret = snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val);
+ if (ret)
+ return ret;
+
+ ucontrol->value.integer.value[0] = val - min;
if (invert)
ucontrol->value.integer.value[0] =
max - ucontrol->value.integer.value[0];
if (snd_soc_volsw_is_stereo(mc)) {
if (reg == reg2)
- ucontrol->value.integer.value[1] =
- snd_soc_read_signed(codec, reg, mask, rshift,
- sign_bit) - min;
+ ret = snd_soc_read_signed(component, reg, mask, rshift,
+ sign_bit, &val);
else
- ucontrol->value.integer.value[1] =
- snd_soc_read_signed(codec, reg2, mask, shift,
- sign_bit) - min;
+ ret = snd_soc_read_signed(component, reg2, mask, shift,
+ sign_bit, &val);
+ if (ret)
+ return ret;
+
+ ucontrol->value.integer.value[1] = val - min;
if (invert)
ucontrol->value.integer.value[1] =
max - ucontrol->value.integer.value[1];
@@ -2650,9 +2672,9 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw);
int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int reg = mc->reg;
unsigned int reg2 = mc->rreg;
unsigned int shift = mc->shift;
@@ -2687,12 +2709,13 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
type_2r = true;
}
}
- err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
+ err = snd_soc_component_update_bits(component, reg, val_mask, val);
if (err < 0)
return err;
if (type_2r)
- err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2);
+ err = snd_soc_component_update_bits(component, reg2, val_mask,
+ val2);
return err;
}
@@ -2711,10 +2734,9 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
-
unsigned int reg = mc->reg;
unsigned int reg2 = mc->rreg;
unsigned int shift = mc->shift;
@@ -2722,13 +2744,23 @@ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol,
int max = mc->max;
int min = mc->min;
int mask = (1 << (fls(min + max) - 1)) - 1;
+ unsigned int val;
+ int ret;
- ucontrol->value.integer.value[0] =
- ((snd_soc_read(codec, reg) >> shift) - min) & mask;
+ ret = snd_soc_component_read(component, reg, &val);
+ if (ret < 0)
+ return ret;
- if (snd_soc_volsw_is_stereo(mc))
- ucontrol->value.integer.value[1] =
- ((snd_soc_read(codec, reg2) >> rshift) - min) & mask;
+ ucontrol->value.integer.value[0] = ((val >> shift) - min) & mask;
+
+ if (snd_soc_volsw_is_stereo(mc)) {
+ ret = snd_soc_component_read(component, reg2, &val);
+ if (ret < 0)
+ return ret;
+
+ val = ((val >> rshift) - min) & mask;
+ ucontrol->value.integer.value[1] = val;
+ }
return 0;
}
@@ -2746,7 +2778,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx);
int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
@@ -2764,7 +2796,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
val = (ucontrol->value.integer.value[0] + min) & mask;
val = val << shift;
- err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
+ err = snd_soc_component_update_bits(component, reg, val_mask, val);
if (err < 0)
return err;
@@ -2773,10 +2805,10 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
val2 = (ucontrol->value.integer.value[1] + min) & mask;
val2 = val2 << rshift;
- if (snd_soc_update_bits_locked(codec, reg2, val_mask, val2))
- return err;
+ err = snd_soc_component_update_bits(component, reg2, val_mask,
+ val2);
}
- return 0;
+ return err;
}
EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx);
@@ -2823,10 +2855,15 @@ int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
{
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
unsigned int reg = mc->reg;
+ unsigned int val;
int min = mc->min;
- int val = snd_soc_read(codec, reg);
+ int ret;
+
+ ret = snd_soc_component_read(component, reg, &val);
+ if (ret)
+ return ret;
ucontrol->value.integer.value[0] =
((signed char)(val & 0xff))-min;
@@ -2850,7 +2887,7 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
{
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
unsigned int reg = mc->reg;
int min = mc->min;
unsigned int val;
@@ -2858,7 +2895,7 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
val = (ucontrol->value.integer.value[0]+min) & 0xff;
val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
- return snd_soc_update_bits_locked(codec, reg, 0xffff, val);
+ return snd_soc_component_update_bits(component, reg, 0xffff, val);
}
EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
@@ -2907,7 +2944,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
{
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
unsigned int reg = mc->reg;
unsigned int rreg = mc->rreg;
unsigned int shift = mc->shift;
@@ -2924,7 +2961,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
val_mask = mask << shift;
val = val << shift;
- ret = snd_soc_update_bits_locked(codec, reg, val_mask, val);
+ ret = snd_soc_component_update_bits(component, reg, val_mask, val);
if (ret < 0)
return ret;
@@ -2935,7 +2972,8 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
val_mask = mask << shift;
val = val << shift;
- ret = snd_soc_update_bits_locked(codec, rreg, val_mask, val);
+ ret = snd_soc_component_update_bits(component, rreg, val_mask,
+ val);
}
return ret;
@@ -2954,9 +2992,9 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range);
int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int reg = mc->reg;
unsigned int rreg = mc->rreg;
unsigned int shift = mc->shift;
@@ -2964,9 +3002,14 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,
int max = mc->max;
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
+ unsigned int val;
+ int ret;
- ucontrol->value.integer.value[0] =
- (snd_soc_read(codec, reg) >> shift) & mask;
+ ret = snd_soc_component_read(component, reg, &val);
+ if (ret)
+ return ret;
+
+ ucontrol->value.integer.value[0] = (val >> shift) & mask;
if (invert)
ucontrol->value.integer.value[0] =
max - ucontrol->value.integer.value[0];
@@ -2974,8 +3017,11 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[0] - min;
if (snd_soc_volsw_is_stereo(mc)) {
- ucontrol->value.integer.value[1] =
- (snd_soc_read(codec, rreg) >> shift) & mask;
+ ret = snd_soc_component_read(component, rreg, &val);
+ if (ret)
+ return ret;
+
+ ucontrol->value.integer.value[1] = (val >> shift) & mask;
if (invert)
ucontrol->value.integer.value[1] =
max - ucontrol->value.integer.value[1];
@@ -3029,11 +3075,11 @@ EXPORT_SYMBOL_GPL(snd_soc_limit_volume);
int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_bytes *params = (void *)kcontrol->private_value;
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = params->num_regs * codec->component.val_bytes;
+ uinfo->count = params->num_regs * component->val_bytes;
return 0;
}
@@ -3042,20 +3088,20 @@ EXPORT_SYMBOL_GPL(snd_soc_bytes_info);
int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_bytes *params = (void *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
int ret;
- if (codec->component.regmap)
- ret = regmap_raw_read(codec->component.regmap, params->base,
+ if (component->regmap)
+ ret = regmap_raw_read(component->regmap, params->base,
ucontrol->value.bytes.data,
- params->num_regs * codec->component.val_bytes);
+ params->num_regs * component->val_bytes);
else
ret = -EINVAL;
/* Hide any masked bytes to ensure consistent data reporting */
if (ret == 0 && params->mask) {
- switch (codec->component.val_bytes) {
+ switch (component->val_bytes) {
case 1:
ucontrol->value.bytes.data[0] &= ~params->mask;
break;
@@ -3079,16 +3125,16 @@ EXPORT_SYMBOL_GPL(snd_soc_bytes_get);
int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_bytes *params = (void *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
int ret, len;
unsigned int val, mask;
void *data;
- if (!codec->component.regmap)
+ if (!component->regmap)
return -EINVAL;
- len = params->num_regs * codec->component.val_bytes;
+ len = params->num_regs * component->val_bytes;
data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
if (!data)
@@ -3100,27 +3146,27 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
* copy.
*/
if (params->mask) {
- ret = regmap_read(codec->component.regmap, params->base, &val);
+ ret = regmap_read(component->regmap, params->base, &val);
if (ret != 0)
goto out;
val &= params->mask;
- switch (codec->component.val_bytes) {
+ switch (component->val_bytes) {
case 1:
((u8 *)data)[0] &= ~params->mask;
((u8 *)data)[0] |= val;
break;
case 2:
mask = ~params->mask;
- ret = regmap_parse_val(codec->component.regmap,
+ ret = regmap_parse_val(component->regmap,
&mask, &mask);
if (ret != 0)
goto out;
((u16 *)data)[0] &= mask;
- ret = regmap_parse_val(codec->component.regmap,
+ ret = regmap_parse_val(component->regmap,
&val, &val);
if (ret != 0)
goto out;
@@ -3129,14 +3175,14 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
break;
case 4:
mask = ~params->mask;
- ret = regmap_parse_val(codec->component.regmap,
+ ret = regmap_parse_val(component->regmap,
&mask, &mask);
if (ret != 0)
goto out;
((u32 *)data)[0] &= mask;
- ret = regmap_parse_val(codec->component.regmap,
+ ret = regmap_parse_val(component->regmap,
&val, &val);
if (ret != 0)
goto out;
@@ -3149,7 +3195,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
}
}
- ret = regmap_raw_write(codec->component.regmap, params->base,
+ ret = regmap_raw_write(component->regmap, params->base,
data, len);
out:
@@ -3200,24 +3246,27 @@ EXPORT_SYMBOL_GPL(snd_soc_info_xr_sx);
int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_mreg_control *mc =
(struct soc_mreg_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int regbase = mc->regbase;
unsigned int regcount = mc->regcount;
- unsigned int regwshift = codec->component.val_bytes * BITS_PER_BYTE;
+ unsigned int regwshift = component->val_bytes * BITS_PER_BYTE;
unsigned int regwmask = (1<<regwshift)-1;
unsigned int invert = mc->invert;
unsigned long mask = (1UL<<mc->nbits)-1;
long min = mc->min;
long max = mc->max;
long val = 0;
- unsigned long regval;
+ unsigned int regval;
unsigned int i;
+ int ret;
for (i = 0; i < regcount; i++) {
- regval = snd_soc_read(codec, regbase+i) & regwmask;
- val |= regval << (regwshift*(regcount-i-1));
+ ret = snd_soc_component_read(component, regbase+i, ®val);
+ if (ret)
+ return ret;
+ val |= (regval & regwmask) << (regwshift*(regcount-i-1));
}
val &= mask;
if (min < 0 && val > max)
@@ -3246,12 +3295,12 @@ EXPORT_SYMBOL_GPL(snd_soc_get_xr_sx);
int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_mreg_control *mc =
(struct soc_mreg_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int regbase = mc->regbase;
unsigned int regcount = mc->regcount;
- unsigned int regwshift = codec->component.val_bytes * BITS_PER_BYTE;
+ unsigned int regwshift = component->val_bytes * BITS_PER_BYTE;
unsigned int regwmask = (1<<regwshift)-1;
unsigned int invert = mc->invert;
unsigned long mask = (1UL<<mc->nbits)-1;
@@ -3266,7 +3315,7 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
for (i = 0; i < regcount; i++) {
regval = (val >> (regwshift*(regcount-i-1))) & regwmask;
regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask;
- err = snd_soc_update_bits_locked(codec, regbase+i,
+ err = snd_soc_component_update_bits(component, regbase+i,
regmask, regval);
if (err < 0)
return err;
@@ -3288,14 +3337,21 @@ EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx);
int snd_soc_get_strobe(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int reg = mc->reg;
unsigned int shift = mc->shift;
unsigned int mask = 1 << shift;
unsigned int invert = mc->invert != 0;
- unsigned int val = snd_soc_read(codec, reg) & mask;
+ unsigned int val;
+ int ret;
+
+ ret = snd_soc_component_read(component, reg, &val);
+ if (ret)
+ return ret;
+
+ val &= mask;
if (shift != 0 && val != 0)
val = val >> shift;
@@ -3318,9 +3374,9 @@ EXPORT_SYMBOL_GPL(snd_soc_get_strobe);
int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int reg = mc->reg;
unsigned int shift = mc->shift;
unsigned int mask = 1 << shift;
@@ -3330,12 +3386,11 @@ int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
unsigned int val2 = (strobe ^ invert) ? 0 : mask;
int err;
- err = snd_soc_update_bits_locked(codec, reg, mask, val1);
+ err = snd_soc_component_update_bits(component, reg, mask, val1);
if (err < 0)
return err;
- err = snd_soc_update_bits_locked(codec, reg, mask, val2);
- return err;
+ return snd_soc_component_update_bits(component, reg, mask, val2);
}
EXPORT_SYMBOL_GPL(snd_soc_put_strobe);
--
1.8.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v4 3/5] ASoC: Remove snd_soc_update_bits_locked()
2014-04-22 11:23 [PATCH v4 0/5] ASoC: Move IO and kcontrols to the component level Lars-Peter Clausen
2014-04-22 11:23 ` [PATCH v4 1/5] ASoC: Move IO abstraction " Lars-Peter Clausen
2014-04-22 11:23 ` [PATCH v4 2/5] ASoC: Move standard kcontrol helpers " Lars-Peter Clausen
@ 2014-04-22 11:23 ` Lars-Peter Clausen
2014-04-22 12:25 ` Mark Brown
2014-04-22 11:23 ` [PATCH v4 4/5] ASoC: dapm: Rename soc_widget_update_bits_locked() to soc_widget_update_bits() Lars-Peter Clausen
2014-04-22 11:23 ` [PATCH v4 5/5] ASoC: Remove ASoC level IO tracing Lars-Peter Clausen
4 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-04-22 11:23 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen
There are no users of snd_soc_update_bits_locked() left and it is identical to
snd_soc_update_bits(). So it can be removed.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
sound/soc/soc-io.c | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index ac64fd7..2ead9ed 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -241,26 +241,6 @@ int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
EXPORT_SYMBOL_GPL(snd_soc_update_bits);
/**
- * snd_soc_update_bits_locked - update codec register bits
- * @codec: audio codec
- * @reg: codec register
- * @mask: register mask
- * @value: new value
- *
- * Writes new register value, and takes the codec mutex.
- *
- * Returns 1 for change else 0.
- */
-int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int mask,
- unsigned int value)
-{
- return snd_soc_component_update_bits(&codec->component, reg, mask,
- value);
-}
-EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked);
-
-/**
* snd_soc_test_bits - test register for change
* @codec: audio codec
* @reg: codec register
--
1.8.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v4 4/5] ASoC: dapm: Rename soc_widget_update_bits_locked() to soc_widget_update_bits()
2014-04-22 11:23 [PATCH v4 0/5] ASoC: Move IO and kcontrols to the component level Lars-Peter Clausen
` (2 preceding siblings ...)
2014-04-22 11:23 ` [PATCH v4 3/5] ASoC: Remove snd_soc_update_bits_locked() Lars-Peter Clausen
@ 2014-04-22 11:23 ` Lars-Peter Clausen
2014-04-22 12:25 ` Mark Brown
2014-04-22 11:23 ` [PATCH v4 5/5] ASoC: Remove ASoC level IO tracing Lars-Peter Clausen
4 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-04-22 11:23 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen
There is no unlocked version of soc_widget_update_bits_locked() and there is no
plan to introduce it in the near future, so drop the _locked suffix.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
sound/soc/soc-dapm.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 85a594f..a2475e1 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -383,7 +383,7 @@ static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg,
return snd_soc_component_read(w->dapm->component, reg, value);
}
-static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
+static int soc_widget_update_bits(struct snd_soc_dapm_widget *w,
int reg, unsigned int mask, unsigned int value)
{
if (!w->dapm->component)
@@ -1070,7 +1070,7 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
else
val = w->off_val;
- soc_widget_update_bits_locked(w, -(w->reg + 1),
+ soc_widget_update_bits(w, -(w->reg + 1),
w->mask << w->shift, val << w->shift);
return 0;
@@ -1366,7 +1366,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card,
"pop test : Applying 0x%x/0x%x to %x in %dms\n",
value, mask, reg, card->pop_time);
pop_wait(card->pop_time);
- soc_widget_update_bits_locked(w, reg, mask, value);
+ soc_widget_update_bits(w, reg, mask, value);
}
list_for_each_entry(w, pending, power_list) {
@@ -1512,8 +1512,7 @@ static void dapm_widget_update(struct snd_soc_card *card)
if (!w)
return;
- ret = soc_widget_update_bits_locked(w, update->reg, update->mask,
- update->val);
+ ret = soc_widget_update_bits(w, update->reg, update->mask, update->val);
if (ret < 0)
dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n",
w->name, ret);
--
1.8.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v4 5/5] ASoC: Remove ASoC level IO tracing
2014-04-22 11:23 [PATCH v4 0/5] ASoC: Move IO and kcontrols to the component level Lars-Peter Clausen
` (3 preceding siblings ...)
2014-04-22 11:23 ` [PATCH v4 4/5] ASoC: dapm: Rename soc_widget_update_bits_locked() to soc_widget_update_bits() Lars-Peter Clausen
@ 2014-04-22 11:23 ` Lars-Peter Clausen
2014-04-22 12:25 ` Mark Brown
4 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-04-22 11:23 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen
The ASoC framework is in the process of migrating all IO operations to regmap.
regmap has its own more sophisticated tracing infrastructure for IO operations,
which means that the ASoC level IO tracing becomes redundant, hence this patch
removes them. There are still a handful of ASoC drivers left that do not use
regmap yet, but hopefully the removal of the ASoC IO tracing will be an
additional incentive to switch to regmap.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
New in v2
---
include/trace/events/asoc.h | 92 ---------------------------------------------
sound/soc/soc-io.c | 11 ------
2 files changed, 103 deletions(-)
diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h
index 03996b2..c75c795 100644
--- a/include/trace/events/asoc.h
+++ b/include/trace/events/asoc.h
@@ -11,102 +11,10 @@
struct snd_soc_jack;
struct snd_soc_codec;
-struct snd_soc_platform;
struct snd_soc_card;
struct snd_soc_dapm_widget;
struct snd_soc_dapm_path;
-/*
- * Log register events
- */
-DECLARE_EVENT_CLASS(snd_soc_reg,
-
- TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int val),
-
- TP_ARGS(codec, reg, val),
-
- TP_STRUCT__entry(
- __string( name, codec->name )
- __field( int, id )
- __field( unsigned int, reg )
- __field( unsigned int, val )
- ),
-
- TP_fast_assign(
- __assign_str(name, codec->name);
- __entry->id = codec->id;
- __entry->reg = reg;
- __entry->val = val;
- ),
-
- TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name),
- (int)__entry->id, (unsigned int)__entry->reg,
- (unsigned int)__entry->val)
-);
-
-DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write,
-
- TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int val),
-
- TP_ARGS(codec, reg, val)
-
-);
-
-DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read,
-
- TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int val),
-
- TP_ARGS(codec, reg, val)
-
-);
-
-DECLARE_EVENT_CLASS(snd_soc_preg,
-
- TP_PROTO(struct snd_soc_platform *platform, unsigned int reg,
- unsigned int val),
-
- TP_ARGS(platform, reg, val),
-
- TP_STRUCT__entry(
- __string( name, platform->name )
- __field( int, id )
- __field( unsigned int, reg )
- __field( unsigned int, val )
- ),
-
- TP_fast_assign(
- __assign_str(name, platform->name);
- __entry->id = platform->id;
- __entry->reg = reg;
- __entry->val = val;
- ),
-
- TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name),
- (int)__entry->id, (unsigned int)__entry->reg,
- (unsigned int)__entry->val)
-);
-
-DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write,
-
- TP_PROTO(struct snd_soc_platform *platform, unsigned int reg,
- unsigned int val),
-
- TP_ARGS(platform, reg, val)
-
-);
-
-DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read,
-
- TP_PROTO(struct snd_soc_platform *platform, unsigned int reg,
- unsigned int val),
-
- TP_ARGS(platform, reg, val)
-
-);
-
DECLARE_EVENT_CLASS(snd_soc_card,
TP_PROTO(struct snd_soc_card *card, int val),
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 2ead9ed..7767fbd 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -17,8 +17,6 @@
#include <linux/export.h>
#include <sound/soc.h>
-#include <trace/events/asoc.h>
-
/**
* snd_soc_component_read() - Read register value
* @component: Component to read from
@@ -39,8 +37,6 @@ int snd_soc_component_read(struct snd_soc_component *component,
else
ret = -EIO;
- dev_dbg(component->dev, "read %x => %x\n", reg, *val);
-
return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_component_read);
@@ -56,8 +52,6 @@ EXPORT_SYMBOL_GPL(snd_soc_component_read);
int snd_soc_component_write(struct snd_soc_component *component,
unsigned int reg, unsigned int val)
{
- dev_dbg(component->dev, "write %x = %x\n", reg, val);
-
if (component->regmap)
return regmap_write(component->regmap, reg, val);
else if (component->write)
@@ -207,7 +201,6 @@ unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
ret = snd_soc_component_read(&codec->component, reg, &val);
if (ret < 0)
return -1;
- trace_snd_soc_reg_read(codec, reg, val);
return val;
}
@@ -216,7 +209,6 @@ EXPORT_SYMBOL_GPL(snd_soc_read);
int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int val)
{
- trace_snd_soc_reg_write(codec, reg, val);
return snd_soc_component_write(&codec->component, reg, val);
}
EXPORT_SYMBOL_GPL(snd_soc_write);
@@ -269,8 +261,6 @@ int snd_soc_platform_read(struct snd_soc_platform *platform,
if (ret < 0)
return -1;
- trace_snd_soc_preg_read(platform, reg, val);
-
return val;
}
EXPORT_SYMBOL_GPL(snd_soc_platform_read);
@@ -278,7 +268,6 @@ EXPORT_SYMBOL_GPL(snd_soc_platform_read);
int snd_soc_platform_write(struct snd_soc_platform *platform,
unsigned int reg, unsigned int val)
{
- trace_snd_soc_preg_write(platform, reg, val);
return snd_soc_component_write(&platform->component, reg, val);
}
EXPORT_SYMBOL_GPL(snd_soc_platform_write);
--
1.8.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v4 1/5] ASoC: Move IO abstraction to the component level
2014-04-22 11:23 ` [PATCH v4 1/5] ASoC: Move IO abstraction " Lars-Peter Clausen
@ 2014-04-22 12:24 ` Mark Brown
0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-04-22 12:24 UTC (permalink / raw)
To: Lars-Peter Clausen; +Cc: alsa-devel, Liam Girdwood
[-- Attachment #1.1: Type: text/plain, Size: 373 bytes --]
On Tue, Apr 22, 2014 at 01:23:13PM +0200, Lars-Peter Clausen wrote:
> We currently have two very similar IO abstractions in ASoC, one for CODECs, the
> other for platforms. Moving this to the component level will allow us to unify
> those two. It will also enable us to move the standard kcontrol helpers as well
> as DAPM support to the component level.
Applied, thanks.
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 3/5] ASoC: Remove snd_soc_update_bits_locked()
2014-04-22 11:23 ` [PATCH v4 3/5] ASoC: Remove snd_soc_update_bits_locked() Lars-Peter Clausen
@ 2014-04-22 12:25 ` Mark Brown
0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-04-22 12:25 UTC (permalink / raw)
To: Lars-Peter Clausen; +Cc: alsa-devel, Liam Girdwood
[-- Attachment #1.1: Type: text/plain, Size: 214 bytes --]
On Tue, Apr 22, 2014 at 01:23:15PM +0200, Lars-Peter Clausen wrote:
> There are no users of snd_soc_update_bits_locked() left and it is identical to
> snd_soc_update_bits(). So it can be removed.
Applied, thanks.
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 4/5] ASoC: dapm: Rename soc_widget_update_bits_locked() to soc_widget_update_bits()
2014-04-22 11:23 ` [PATCH v4 4/5] ASoC: dapm: Rename soc_widget_update_bits_locked() to soc_widget_update_bits() Lars-Peter Clausen
@ 2014-04-22 12:25 ` Mark Brown
0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-04-22 12:25 UTC (permalink / raw)
To: Lars-Peter Clausen; +Cc: alsa-devel, Liam Girdwood
[-- Attachment #1.1: Type: text/plain, Size: 239 bytes --]
On Tue, Apr 22, 2014 at 01:23:16PM +0200, Lars-Peter Clausen wrote:
> There is no unlocked version of soc_widget_update_bits_locked() and there is no
> plan to introduce it in the near future, so drop the _locked suffix.
Applied, thanks.
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 5/5] ASoC: Remove ASoC level IO tracing
2014-04-22 11:23 ` [PATCH v4 5/5] ASoC: Remove ASoC level IO tracing Lars-Peter Clausen
@ 2014-04-22 12:25 ` Mark Brown
0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-04-22 12:25 UTC (permalink / raw)
To: Lars-Peter Clausen; +Cc: alsa-devel, Liam Girdwood
[-- Attachment #1.1: Type: text/plain, Size: 527 bytes --]
On Tue, Apr 22, 2014 at 01:23:17PM +0200, Lars-Peter Clausen wrote:
> The ASoC framework is in the process of migrating all IO operations to regmap.
> regmap has its own more sophisticated tracing infrastructure for IO operations,
> which means that the ASoC level IO tracing becomes redundant, hence this patch
> removes them. There are still a handful of ASoC drivers left that do not use
> regmap yet, but hopefully the removal of the ASoC IO tracing will be an
> additional incentive to switch to regmap.
Applied, thanks.
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-04-22 11:23 ` [PATCH v4 2/5] ASoC: Move standard kcontrol helpers " Lars-Peter Clausen
@ 2014-04-22 12:38 ` Mark Brown
2014-05-09 15:00 ` Shawn Guo
1 sibling, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-04-22 12:38 UTC (permalink / raw)
To: Lars-Peter Clausen; +Cc: alsa-devel, Liam Girdwood
[-- Attachment #1.1: Type: text/plain, Size: 373 bytes --]
On Tue, Apr 22, 2014 at 01:23:14PM +0200, Lars-Peter Clausen wrote:
> After moving the IO layer inside ASoC to the component level we can now easily
> move the standard control helpers also to the component level. This allows to
> reuse the same standard helper control implementations for other components.
Applied, thanks. This also depended on the multicodec changes.
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-04-22 11:23 ` [PATCH v4 2/5] ASoC: Move standard kcontrol helpers " Lars-Peter Clausen
2014-04-22 12:38 ` Mark Brown
@ 2014-05-09 15:00 ` Shawn Guo
2014-05-09 15:17 ` Lars-Peter Clausen
1 sibling, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2014-05-09 15:00 UTC (permalink / raw)
To: Lars-Peter Clausen; +Cc: alsa-devel, Mark Brown, Liam Girdwood
Hi Lars,
On Tue, Apr 22, 2014 at 01:23:14PM +0200, Lars-Peter Clausen wrote:
> After moving the IO layer inside ASoC to the component level we can now easily
> move the standard control helpers also to the component level. This allows to
> reuse the same standard helper control implementations for other components.
>
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
I'm running next-20140508 on imx6q-sabresd board and seeing repeated
'amixer: Mixer hw:0 load error: Device or resource busy' message with
Debian wheezy rootfs. The git bisect points me to this patch.
== message output before this patch ==
[....] Setting up ALSA...warning: 'alsactl restore' failed with error message 'Found hardware: "wm8962-audio" "" "" "" ""
Hardware is initialized using a generic method
[ ok tl: set_control:1328: failed to obtain info for control #117 (No such file or directory)'...done.
== message output after this patch ==
[....] Setting up ALSA...warning: 'alsactl restore' failed with error message 'Found hardware: "wm8962-audio" "" "" "" ""
Hardware is initialized using a generic method
alsactl: set_control:1328: failed to obtain info for control #117 (No such file or directory)'...amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
amixer: Mixer hw:0 load error: Device or resource busy
done.
Why do we start seeing such error message with your patch? Is this
a problem of rootfs or kernel?
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-09 15:00 ` Shawn Guo
@ 2014-05-09 15:17 ` Lars-Peter Clausen
2014-05-09 15:34 ` Fabio Estevam
0 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-05-09 15:17 UTC (permalink / raw)
To: Shawn Guo; +Cc: alsa-devel, Mark Brown, Liam Girdwood
On 05/09/2014 05:00 PM, Shawn Guo wrote:
> Hi Lars,
>
> On Tue, Apr 22, 2014 at 01:23:14PM +0200, Lars-Peter Clausen wrote:
>> After moving the IO layer inside ASoC to the component level we can now easily
>> move the standard control helpers also to the component level. This allows to
>> reuse the same standard helper control implementations for other components.
>>
>> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
>
> I'm running next-20140508 on imx6q-sabresd board and seeing repeated
> 'amixer: Mixer hw:0 load error: Device or resource busy' message with
> Debian wheezy rootfs. The git bisect points me to this patch.
>
> == message output before this patch ==
>
> [....] Setting up ALSA...warning: 'alsactl restore' failed with error message 'Found hardware: "wm8962-audio" "" "" "" ""
> Hardware is initialized using a generic method
> [ ok tl: set_control:1328: failed to obtain info for control #117 (No such file or directory)'...done.
>
> == message output after this patch ==
>
> [....] Setting up ALSA...warning: 'alsactl restore' failed with error message 'Found hardware: "wm8962-audio" "" "" "" ""
> Hardware is initialized using a generic method
> alsactl: set_control:1328: failed to obtain info for control #117 (No such file or directory)'...amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> amixer: Mixer hw:0 load error: Device or resource busy
> done.
>
> Why do we start seeing such error message with your patch? Is this
> a problem of rootfs or kernel?
The changes in the patch should mostly be transparent. But what changed is
how error reporting is handled. If there is a error reading/writing a
register in the kcontrol callbacks that error is passed on to userspace
whereas previously it was silently ignored.
There is also the possibility that there is a bug somewhere in the patch
causing this.
Does the board otherwise work fine?
I actually have the board here, if you tell me which devictree/defconfig I
can use with an upstream kernel I can give things a try.
- Lars
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-09 15:17 ` Lars-Peter Clausen
@ 2014-05-09 15:34 ` Fabio Estevam
2014-05-09 16:01 ` Lars-Peter Clausen
0 siblings, 1 reply; 28+ messages in thread
From: Fabio Estevam @ 2014-05-09 15:34 UTC (permalink / raw)
To: Lars-Peter Clausen
Cc: alsa-devel@alsa-project.org, Shawn Guo, Mark Brown, Liam Girdwood
On Fri, May 9, 2014 at 12:17 PM, Lars-Peter Clausen <lars@metafoo.de> wrote:
> The changes in the patch should mostly be transparent. But what changed is
> how error reporting is handled. If there is a error reading/writing a
> register in the kcontrol callbacks that error is passed on to userspace
> whereas previously it was silently ignored.
>
> There is also the possibility that there is a bug somewhere in the patch
> causing this.
>
> Does the board otherwise work fine?
>
> I actually have the board here, if you tell me which devictree/defconfig I
> can use with an upstream kernel I can give things a try.
make imx_v6_v7_defconfig
make imx6q-sabresd.dtb
Thanks
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-09 15:34 ` Fabio Estevam
@ 2014-05-09 16:01 ` Lars-Peter Clausen
2014-05-09 16:11 ` Fabio Estevam
2014-05-10 5:07 ` Shawn Guo
0 siblings, 2 replies; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-05-09 16:01 UTC (permalink / raw)
To: Fabio Estevam
Cc: alsa-devel@alsa-project.org, Shawn Guo, Mark Brown, Liam Girdwood
On 05/09/2014 05:34 PM, Fabio Estevam wrote:
> On Fri, May 9, 2014 at 12:17 PM, Lars-Peter Clausen <lars@metafoo.de> wrote:
>
>> The changes in the patch should mostly be transparent. But what changed is
>> how error reporting is handled. If there is a error reading/writing a
>> register in the kcontrol callbacks that error is passed on to userspace
>> whereas previously it was silently ignored.
>>
>> There is also the possibility that there is a bug somewhere in the patch
>> causing this.
>>
>> Does the board otherwise work fine?
>>
>> I actually have the board here, if you tell me which devictree/defconfig I
>> can use with an upstream kernel I can give things a try.
>
> make imx_v6_v7_defconfig
> make imx6q-sabresd.dtb
I just tried 907fe36a2c, e2c330b9b5 and next/master. I get the same behavior
with all 3, no errors when loading a state file and audio out on the
headphones works. I disabled DRM though since it deadlocked the system,
maybe that makes a difference.
Is it possible that the error is coming from the I2C driver? Can you build
the I2C driver with #define DEBUG and take a look at the output?
- Lars
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-09 16:01 ` Lars-Peter Clausen
@ 2014-05-09 16:11 ` Fabio Estevam
2014-05-10 5:07 ` Shawn Guo
1 sibling, 0 replies; 28+ messages in thread
From: Fabio Estevam @ 2014-05-09 16:11 UTC (permalink / raw)
To: Lars-Peter Clausen
Cc: alsa-devel@alsa-project.org, Shawn Guo, Mark Brown, Liam Girdwood
On Fri, May 9, 2014 at 1:01 PM, Lars-Peter Clausen <lars@metafoo.de> wrote:
> I just tried 907fe36a2c, e2c330b9b5 and next/master. I get the same behavior
> with all 3, no errors when loading a state file and audio out on the
> headphones works. I disabled DRM though since it deadlocked the system,
> maybe that makes a difference.
Here is the fix for this hang (which hasn't reached linux-next yet):
http://www.spinics.net/lists/arm-kernel/msg329063.html
>
> Is it possible that the error is coming from the I2C driver? Can you build
> the I2C driver with #define DEBUG and take a look at the output?
I will let Shawn to try it. With my minimal rootfs I do not see the
error messages when playing audio.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-09 16:01 ` Lars-Peter Clausen
2014-05-09 16:11 ` Fabio Estevam
@ 2014-05-10 5:07 ` Shawn Guo
2014-05-10 7:04 ` Lars-Peter Clausen
1 sibling, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2014-05-10 5:07 UTC (permalink / raw)
To: Lars-Peter Clausen
Cc: alsa-devel@alsa-project.org, Mark Brown, Fabio Estevam,
Liam Girdwood
On Fri, May 09, 2014 at 06:01:43PM +0200, Lars-Peter Clausen wrote:
> On 05/09/2014 05:34 PM, Fabio Estevam wrote:
> >On Fri, May 9, 2014 at 12:17 PM, Lars-Peter Clausen <lars@metafoo.de> wrote:
> >
> >>The changes in the patch should mostly be transparent. But what changed is
> >>how error reporting is handled. If there is a error reading/writing a
> >>register in the kcontrol callbacks that error is passed on to userspace
> >>whereas previously it was silently ignored.
> >>
> >>There is also the possibility that there is a bug somewhere in the patch
> >>causing this.
> >>
> >>Does the board otherwise work fine?
> >>
> >>I actually have the board here, if you tell me which devictree/defconfig I
> >>can use with an upstream kernel I can give things a try.
> >
> >make imx_v6_v7_defconfig
> >make imx6q-sabresd.dtb
>
> I just tried 907fe36a2c, e2c330b9b5 and next/master. I get the same
> behavior with all 3, no errors when loading a state file and audio
> out on the headphones works.
For me, e2c330b9b5 is good while 907fe36a2c and next/master expose this
error message.
> I disabled DRM though since it
> deadlocked the system, maybe that makes a difference.
It does not make a difference.
>
> Is it possible that the error is coming from the I2C driver? Can you
> build the I2C driver with #define DEBUG and take a look at the
> output?
I tried to turn on DEBUG in I2C driver, and did not notice any I2C
message when above error appears.
The error message only shows up with Debian wheezy and does not with
yocto rootfs. And even when the error message shows, the audio still
functions well on Debian wheezy. So it's just a noisy error message
for me which is only seen after your kernel patch.
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-10 5:07 ` Shawn Guo
@ 2014-05-10 7:04 ` Lars-Peter Clausen
2014-05-10 7:11 ` Lars-Peter Clausen
0 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-05-10 7:04 UTC (permalink / raw)
To: Shawn Guo
Cc: alsa-devel@alsa-project.org, Mark Brown, Fabio Estevam,
Liam Girdwood
On 05/10/2014 07:07 AM, Shawn Guo wrote:
> On Fri, May 09, 2014 at 06:01:43PM +0200, Lars-Peter Clausen wrote:
>> On 05/09/2014 05:34 PM, Fabio Estevam wrote:
>>> On Fri, May 9, 2014 at 12:17 PM, Lars-Peter Clausen <lars@metafoo.de> wrote:
>>>
>>>> The changes in the patch should mostly be transparent. But what changed is
>>>> how error reporting is handled. If there is a error reading/writing a
>>>> register in the kcontrol callbacks that error is passed on to userspace
>>>> whereas previously it was silently ignored.
>>>>
>>>> There is also the possibility that there is a bug somewhere in the patch
>>>> causing this.
>>>>
>>>> Does the board otherwise work fine?
>>>>
>>>> I actually have the board here, if you tell me which devictree/defconfig I
>>>> can use with an upstream kernel I can give things a try.
>>>
>>> make imx_v6_v7_defconfig
>>> make imx6q-sabresd.dtb
>>
>> I just tried 907fe36a2c, e2c330b9b5 and next/master. I get the same
>> behavior with all 3, no errors when loading a state file and audio
>> out on the headphones works.
>
> For me, e2c330b9b5 is good while 907fe36a2c and next/master expose this
> error message.
>
>> I disabled DRM though since it
>> deadlocked the system, maybe that makes a difference.
>
> It does not make a difference.
>
>>
>> Is it possible that the error is coming from the I2C driver? Can you
>> build the I2C driver with #define DEBUG and take a look at the
>> output?
>
> I tried to turn on DEBUG in I2C driver, and did not notice any I2C
> message when above error appears.
>
> The error message only shows up with Debian wheezy and does not with
> yocto rootfs. And even when the error message shows, the audio still
> functions well on Debian wheezy. So it's just a noisy error message
> for me which is only seen after your kernel patch.
The keyword here is "seen". The error quite likely predated the commit, but
it was silently discarded.
regmap_read() returns -EBUSY when there is no cached register value and
cache_only is set to true. But I'm not sure why that would happen, try to
add some printks to _regmap_read() to see if this is the source and if it is
why it is.
- Lars
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-10 7:04 ` Lars-Peter Clausen
@ 2014-05-10 7:11 ` Lars-Peter Clausen
2014-05-10 8:31 ` Shawn Guo
0 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-05-10 7:11 UTC (permalink / raw)
To: Shawn Guo
Cc: alsa-devel@alsa-project.org, Mark Brown, Fabio Estevam,
Liam Girdwood
On 05/10/2014 09:04 AM, Lars-Peter Clausen wrote:
[..]
>> The error message only shows up with Debian wheezy and does not with
>> yocto rootfs. And even when the error message shows, the audio still
>> functions well on Debian wheezy. So it's just a noisy error message
>> for me which is only seen after your kernel patch.
>
> The keyword here is "seen". The error quite likely predated the commit, but
> it was silently discarded.
>
> regmap_read() returns -EBUSY when there is no cached register value and
> cache_only is set to true. But I'm not sure why that would happen, try to
> add some printks to _regmap_read() to see if this is the source and if it is
> why it is.
Both SGTL5000_CHIP_ANA_ADC_CTRL and SGTL5000_CHIP_MIC_CTRL don't have an
entry in sgtl5000_reg_defaults. So if cache_only is true, controls which use
these registers will return -EBUSY when you try to read or write them.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-10 7:11 ` Lars-Peter Clausen
@ 2014-05-10 8:31 ` Shawn Guo
2014-05-10 8:37 ` Lars-Peter Clausen
0 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2014-05-10 8:31 UTC (permalink / raw)
To: Lars-Peter Clausen
Cc: alsa-devel@alsa-project.org, Mark Brown, Fabio Estevam,
Liam Girdwood
On Sat, May 10, 2014 at 09:11:04AM +0200, Lars-Peter Clausen wrote:
> On 05/10/2014 09:04 AM, Lars-Peter Clausen wrote:
> [..]
> >>The error message only shows up with Debian wheezy and does not with
> >>yocto rootfs. And even when the error message shows, the audio still
> >>functions well on Debian wheezy. So it's just a noisy error message
> >>for me which is only seen after your kernel patch.
> >
> >The keyword here is "seen". The error quite likely predated the commit, but
> >it was silently discarded.
> >
> >regmap_read() returns -EBUSY when there is no cached register value and
> >cache_only is set to true. But I'm not sure why that would happen, try to
> >add some printks to _regmap_read() to see if this is the source and if it is
> >why it is.
>
> Both SGTL5000_CHIP_ANA_ADC_CTRL and SGTL5000_CHIP_MIC_CTRL don't
> have an entry in sgtl5000_reg_defaults. So if cache_only is true,
> controls which use these registers will return -EBUSY when you try
> to read or write them.
Hmm, it's a wm8962 than sgtl5000 on board imx6q-sabresd.
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-10 8:31 ` Shawn Guo
@ 2014-05-10 8:37 ` Lars-Peter Clausen
2014-05-10 9:12 ` Shawn Guo
0 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-05-10 8:37 UTC (permalink / raw)
To: Shawn Guo
Cc: alsa-devel@alsa-project.org, Mark Brown, Fabio Estevam,
Liam Girdwood
On 05/10/2014 10:31 AM, Shawn Guo wrote:
> On Sat, May 10, 2014 at 09:11:04AM +0200, Lars-Peter Clausen wrote:
>> On 05/10/2014 09:04 AM, Lars-Peter Clausen wrote:
>> [..]
>>>> The error message only shows up with Debian wheezy and does not with
>>>> yocto rootfs. And even when the error message shows, the audio still
>>>> functions well on Debian wheezy. So it's just a noisy error message
>>>> for me which is only seen after your kernel patch.
>>>
>>> The keyword here is "seen". The error quite likely predated the commit, but
>>> it was silently discarded.
>>>
>>> regmap_read() returns -EBUSY when there is no cached register value and
>>> cache_only is set to true. But I'm not sure why that would happen, try to
>>> add some printks to _regmap_read() to see if this is the source and if it is
>>> why it is.
>>
>> Both SGTL5000_CHIP_ANA_ADC_CTRL and SGTL5000_CHIP_MIC_CTRL don't
>> have an entry in sgtl5000_reg_defaults. So if cache_only is true,
>> controls which use these registers will return -EBUSY when you try
>> to read or write them.
>
> Hmm, it's a wm8962 than sgtl5000 on board imx6q-sabresd.
Ok, misread the boardname. But the issue will be the same. cache_only = true
and trying to read/update a register that is not in the cache.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-10 8:37 ` Lars-Peter Clausen
@ 2014-05-10 9:12 ` Shawn Guo
2014-05-10 9:28 ` Lars-Peter Clausen
` (2 more replies)
0 siblings, 3 replies; 28+ messages in thread
From: Shawn Guo @ 2014-05-10 9:12 UTC (permalink / raw)
To: Lars-Peter Clausen
Cc: alsa-devel@alsa-project.org, Mark Brown, Fabio Estevam,
Liam Girdwood
On Sat, May 10, 2014 at 10:37:28AM +0200, Lars-Peter Clausen wrote:
> On 05/10/2014 10:31 AM, Shawn Guo wrote:
> >On Sat, May 10, 2014 at 09:11:04AM +0200, Lars-Peter Clausen wrote:
> >>On 05/10/2014 09:04 AM, Lars-Peter Clausen wrote:
> >>[..]
> >>>>The error message only shows up with Debian wheezy and does not with
> >>>>yocto rootfs. And even when the error message shows, the audio still
> >>>>functions well on Debian wheezy. So it's just a noisy error message
> >>>>for me which is only seen after your kernel patch.
> >>>
> >>>The keyword here is "seen". The error quite likely predated the commit, but
> >>>it was silently discarded.
> >>>
> >>>regmap_read() returns -EBUSY when there is no cached register value and
> >>>cache_only is set to true. But I'm not sure why that would happen, try to
> >>>add some printks to _regmap_read() to see if this is the source and if it is
> >>>why it is.
> >>
> >>Both SGTL5000_CHIP_ANA_ADC_CTRL and SGTL5000_CHIP_MIC_CTRL don't
> >>have an entry in sgtl5000_reg_defaults. So if cache_only is true,
> >>controls which use these registers will return -EBUSY when you try
> >>to read or write them.
> >
> >Hmm, it's a wm8962 than sgtl5000 on board imx6q-sabresd.
>
> Ok, misread the boardname. But the issue will be the same.
> cache_only = true and trying to read/update a register that is not
> in the cache.
Yea, you're right. When the error message shows up, _regmap_read()
returns -EBUSY for reg WM8962_CLASS_D_CONTROL_1. But how do I find out
why the reg is not in the cache?
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-10 9:12 ` Shawn Guo
@ 2014-05-10 9:28 ` Lars-Peter Clausen
2014-05-12 10:42 ` Charles Keepax
2014-05-12 10:52 ` Charles Keepax
2 siblings, 0 replies; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-05-10 9:28 UTC (permalink / raw)
To: Shawn Guo
Cc: Dimitris Papastamos, alsa-devel@alsa-project.org, patches,
Liam Girdwood, Mark Brown, Charles Keepax, Fabio Estevam
On 05/10/2014 11:12 AM, Shawn Guo wrote:
> On Sat, May 10, 2014 at 10:37:28AM +0200, Lars-Peter Clausen wrote:
>> On 05/10/2014 10:31 AM, Shawn Guo wrote:
>>> On Sat, May 10, 2014 at 09:11:04AM +0200, Lars-Peter Clausen wrote:
>>>> On 05/10/2014 09:04 AM, Lars-Peter Clausen wrote:
>>>> [..]
>>>>>> The error message only shows up with Debian wheezy and does not with
>>>>>> yocto rootfs. And even when the error message shows, the audio still
>>>>>> functions well on Debian wheezy. So it's just a noisy error message
>>>>>> for me which is only seen after your kernel patch.
>>>>>
>>>>> The keyword here is "seen". The error quite likely predated the commit, but
>>>>> it was silently discarded.
>>>>>
>>>>> regmap_read() returns -EBUSY when there is no cached register value and
>>>>> cache_only is set to true. But I'm not sure why that would happen, try to
>>>>> add some printks to _regmap_read() to see if this is the source and if it is
>>>>> why it is.
>>>>
>>>> Both SGTL5000_CHIP_ANA_ADC_CTRL and SGTL5000_CHIP_MIC_CTRL don't
>>>> have an entry in sgtl5000_reg_defaults. So if cache_only is true,
>>>> controls which use these registers will return -EBUSY when you try
>>>> to read or write them.
>>>
>>> Hmm, it's a wm8962 than sgtl5000 on board imx6q-sabresd.
>>
>> Ok, misread the boardname. But the issue will be the same.
>> cache_only = true and trying to read/update a register that is not
>> in the cache.
>
> Yea, you're right. When the error message shows up, _regmap_read()
> returns -EBUSY for reg WM8962_CLASS_D_CONTROL_1. But how do I find out
> why the reg is not in the cache?
The register is marked as volatile in the driver and volatile registers are
never cached. I don't know what the right fix is in this case though.
- Lars
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-10 9:12 ` Shawn Guo
2014-05-10 9:28 ` Lars-Peter Clausen
@ 2014-05-12 10:42 ` Charles Keepax
2014-05-12 11:03 ` Mark Brown
2014-05-12 10:52 ` Charles Keepax
2 siblings, 1 reply; 28+ messages in thread
From: Charles Keepax @ 2014-05-12 10:42 UTC (permalink / raw)
To: Shawn Guo
Cc: alsa-devel@alsa-project.org, Lars-Peter Clausen, Fabio Estevam,
Mark Brown, Liam Girdwood
On Sat, May 10, 2014 at 05:12:11PM +0800, Shawn Guo wrote:
> On Sat, May 10, 2014 at 10:37:28AM +0200, Lars-Peter Clausen wrote:
> > On 05/10/2014 10:31 AM, Shawn Guo wrote:
> > >On Sat, May 10, 2014 at 09:11:04AM +0200, Lars-Peter Clausen wrote:
> > >>On 05/10/2014 09:04 AM, Lars-Peter Clausen wrote:
> > >>[..]
> > >>>>The error message only shows up with Debian wheezy and does not with
> > >>>>yocto rootfs. And even when the error message shows, the audio still
> > >>>>functions well on Debian wheezy. So it's just a noisy error message
> > >>>>for me which is only seen after your kernel patch.
> > >>>
> > >>>The keyword here is "seen". The error quite likely predated the commit, but
> > >>>it was silently discarded.
> > >>>
> > >>>regmap_read() returns -EBUSY when there is no cached register value and
> > >>>cache_only is set to true. But I'm not sure why that would happen, try to
> > >>>add some printks to _regmap_read() to see if this is the source and if it is
> > >>>why it is.
> > >>
> > >>Both SGTL5000_CHIP_ANA_ADC_CTRL and SGTL5000_CHIP_MIC_CTRL don't
> > >>have an entry in sgtl5000_reg_defaults. So if cache_only is true,
> > >>controls which use these registers will return -EBUSY when you try
> > >>to read or write them.
> > >
> > >Hmm, it's a wm8962 than sgtl5000 on board imx6q-sabresd.
> >
> > Ok, misread the boardname. But the issue will be the same.
> > cache_only = true and trying to read/update a register that is not
> > in the cache.
>
> Yea, you're right. When the error message shows up, _regmap_read()
> returns -EBUSY for reg WM8962_CLASS_D_CONTROL_1. But how do I find out
> why the reg is not in the cache?
>From what I can see it doesn't look like this register should be
volatile. I am checking with the hardware guys here, incase I am
missing something, but otherwise I will wing out a patch to make
it non-volatile.
Thanks,
Charles
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-10 9:12 ` Shawn Guo
2014-05-10 9:28 ` Lars-Peter Clausen
2014-05-12 10:42 ` Charles Keepax
@ 2014-05-12 10:52 ` Charles Keepax
2014-05-13 3:19 ` Shawn Guo
2 siblings, 1 reply; 28+ messages in thread
From: Charles Keepax @ 2014-05-12 10:52 UTC (permalink / raw)
To: Shawn Guo
Cc: alsa-devel@alsa-project.org, Lars-Peter Clausen, Fabio Estevam,
Mark Brown, Liam Girdwood
On Sat, May 10, 2014 at 05:12:11PM +0800, Shawn Guo wrote:
> On Sat, May 10, 2014 at 10:37:28AM +0200, Lars-Peter Clausen wrote:
> > On 05/10/2014 10:31 AM, Shawn Guo wrote:
> > >On Sat, May 10, 2014 at 09:11:04AM +0200, Lars-Peter Clausen wrote:
> > >>On 05/10/2014 09:04 AM, Lars-Peter Clausen wrote:
> > >>[..]
> > >>>>The error message only shows up with Debian wheezy and does not with
> > >>>>yocto rootfs. And even when the error message shows, the audio still
> > >>>>functions well on Debian wheezy. So it's just a noisy error message
> > >>>>for me which is only seen after your kernel patch.
> > >>>
> > >>>The keyword here is "seen". The error quite likely predated the commit, but
> > >>>it was silently discarded.
> > >>>
> > >>>regmap_read() returns -EBUSY when there is no cached register value and
> > >>>cache_only is set to true. But I'm not sure why that would happen, try to
> > >>>add some printks to _regmap_read() to see if this is the source and if it is
> > >>>why it is.
> > >>
> > >>Both SGTL5000_CHIP_ANA_ADC_CTRL and SGTL5000_CHIP_MIC_CTRL don't
> > >>have an entry in sgtl5000_reg_defaults. So if cache_only is true,
> > >>controls which use these registers will return -EBUSY when you try
> > >>to read or write them.
> > >
> > >Hmm, it's a wm8962 than sgtl5000 on board imx6q-sabresd.
> >
> > Ok, misread the boardname. But the issue will be the same.
> > cache_only = true and trying to read/update a register that is not
> > in the cache.
>
> Yea, you're right. When the error message shows up, _regmap_read()
> returns -EBUSY for reg WM8962_CLASS_D_CONTROL_1. But how do I find out
> why the reg is not in the cache?
Looking at this a bit more can you let me know when it is
failing, I assume it is in relation to setting the "Speaker
Switch" control?
Thanks,
Charles
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-12 10:42 ` Charles Keepax
@ 2014-05-12 11:03 ` Mark Brown
2014-05-12 14:09 ` Charles Keepax
0 siblings, 1 reply; 28+ messages in thread
From: Mark Brown @ 2014-05-12 11:03 UTC (permalink / raw)
To: Charles Keepax
Cc: alsa-devel@alsa-project.org, Shawn Guo, Fabio Estevam,
Lars-Peter Clausen, Liam Girdwood
[-- Attachment #1.1: Type: text/plain, Size: 680 bytes --]
On Mon, May 12, 2014 at 11:42:04AM +0100, Charles Keepax wrote:
> > Yea, you're right. When the error message shows up, _regmap_read()
> > returns -EBUSY for reg WM8962_CLASS_D_CONTROL_1. But how do I find out
> > why the reg is not in the cache?
> From what I can see it doesn't look like this register should be
> volatile. I am checking with the hardware guys here, incase I am
> missing something, but otherwise I will wing out a patch to make
> it non-volatile.
IIRC at least one of the bits in the register also appears in another
register. They aren't volatile but the cache could get confused unless
something is open coded to keep the two cached registers in sync.
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-12 11:03 ` Mark Brown
@ 2014-05-12 14:09 ` Charles Keepax
0 siblings, 0 replies; 28+ messages in thread
From: Charles Keepax @ 2014-05-12 14:09 UTC (permalink / raw)
To: Mark Brown
Cc: alsa-devel@alsa-project.org, Shawn Guo, Fabio Estevam,
Lars-Peter Clausen, Liam Girdwood
On Mon, May 12, 2014 at 12:03:04PM +0100, Mark Brown wrote:
> On Mon, May 12, 2014 at 11:42:04AM +0100, Charles Keepax wrote:
>
> > > Yea, you're right. When the error message shows up, _regmap_read()
> > > returns -EBUSY for reg WM8962_CLASS_D_CONTROL_1. But how do I find out
> > > why the reg is not in the cache?
>
> > From what I can see it doesn't look like this register should be
> > volatile. I am checking with the hardware guys here, incase I am
> > missing something, but otherwise I will wing out a patch to make
> > it non-volatile.
>
> IIRC at least one of the bits in the register also appears in another
> register. They aren't volatile but the cache could get confused unless
> something is open coded to keep the two cached registers in sync.
Yup, just heard back from the hardware guys, this is exactly it.
The DAC_MUTE bit in registers R5 and R49 both control the same
thing. So if you change one it changes the other.
Looks like either something will need to be added to keep the two
registers in sync, or some manual caching of the speaker switch
until the device is enabled.
Thanks,
Charles
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v4 2/5] ASoC: Move standard kcontrol helpers to the component level
2014-05-12 10:52 ` Charles Keepax
@ 2014-05-13 3:19 ` Shawn Guo
0 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2014-05-13 3:19 UTC (permalink / raw)
To: Charles Keepax
Cc: alsa-devel@alsa-project.org, Lars-Peter Clausen, Fabio Estevam,
Mark Brown, Liam Girdwood
On Mon, May 12, 2014 at 11:52:57AM +0100, Charles Keepax wrote:
> Looking at this a bit more can you let me know when it is
> failing, I assume it is in relation to setting the "Speaker
> Switch" control?
Yes, it is.
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2014-05-13 3:19 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-22 11:23 [PATCH v4 0/5] ASoC: Move IO and kcontrols to the component level Lars-Peter Clausen
2014-04-22 11:23 ` [PATCH v4 1/5] ASoC: Move IO abstraction " Lars-Peter Clausen
2014-04-22 12:24 ` Mark Brown
2014-04-22 11:23 ` [PATCH v4 2/5] ASoC: Move standard kcontrol helpers " Lars-Peter Clausen
2014-04-22 12:38 ` Mark Brown
2014-05-09 15:00 ` Shawn Guo
2014-05-09 15:17 ` Lars-Peter Clausen
2014-05-09 15:34 ` Fabio Estevam
2014-05-09 16:01 ` Lars-Peter Clausen
2014-05-09 16:11 ` Fabio Estevam
2014-05-10 5:07 ` Shawn Guo
2014-05-10 7:04 ` Lars-Peter Clausen
2014-05-10 7:11 ` Lars-Peter Clausen
2014-05-10 8:31 ` Shawn Guo
2014-05-10 8:37 ` Lars-Peter Clausen
2014-05-10 9:12 ` Shawn Guo
2014-05-10 9:28 ` Lars-Peter Clausen
2014-05-12 10:42 ` Charles Keepax
2014-05-12 11:03 ` Mark Brown
2014-05-12 14:09 ` Charles Keepax
2014-05-12 10:52 ` Charles Keepax
2014-05-13 3:19 ` Shawn Guo
2014-04-22 11:23 ` [PATCH v4 3/5] ASoC: Remove snd_soc_update_bits_locked() Lars-Peter Clausen
2014-04-22 12:25 ` Mark Brown
2014-04-22 11:23 ` [PATCH v4 4/5] ASoC: dapm: Rename soc_widget_update_bits_locked() to soc_widget_update_bits() Lars-Peter Clausen
2014-04-22 12:25 ` Mark Brown
2014-04-22 11:23 ` [PATCH v4 5/5] ASoC: Remove ASoC level IO tracing Lars-Peter Clausen
2014-04-22 12:25 ` Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox