[alsa-devel] [PATCH 1/5] regmap: Add better support for devices without readback support
Currently regmap requires that a reg_read callback is supplied, otherwise a warning is emitted each time regmap_read() is called. This means a device or bus without readback support needs to supply dummy reg_read callback. Apart from that regmap_read() will still work fine if a cache is used.
Remove the warning and let regmap_readable() return false if not reg_read callback is supplied. This means a device no longer has to supply a dummy callback if it does not support readback and it also doesn't have to have a readable_reg callback that always returns false since this is now implicit.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- drivers/base/regmap/regmap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index dd63bcb..8acc837 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -93,6 +93,9 @@ bool regmap_writeable(struct regmap *map, unsigned int reg)
bool regmap_readable(struct regmap *map, unsigned int reg) { + if (!map->reg_read) + return false; + if (map->max_register && reg > map->max_register) return false;
@@ -2109,8 +2112,6 @@ static int _regmap_read(struct regmap *map, unsigned int reg, int ret; void *context = _regmap_map_get_context(map);
- WARN_ON(!map->reg_read); - if (!map->cache_bypass) { ret = regcache_read(map, reg, val); if (ret == 0)
Resource allocations should be done in the bus probe rather than the CODEC probe. Move the allocation of the drivers state struct there.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/uda134x.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-)
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 913edf2..a89f98a 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -478,8 +478,8 @@ static struct snd_soc_dai_driver uda134x_dai = { static int uda134x_soc_probe(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct uda134x_priv *uda134x; struct uda134x_platform_data *pd = codec->component.card->dev->platform_data; + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); const struct snd_soc_dapm_widget *widgets; unsigned num_widgets;
@@ -506,10 +506,6 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) return -EINVAL; }
- uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); - if (uda134x == NULL) - return -ENOMEM; - snd_soc_codec_set_drvdata(codec, uda134x);
codec->control_data = pd;
@@ -530,7 +526,6 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) if (ret) { printk(KERN_ERR "%s failed to register dapm controls: %d", __func__, ret); - kfree(uda134x); return ret; }
@@ -551,31 +546,19 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) default: printk(KERN_ERR "%s unknown codec type: %d", __func__, pd->model); - kfree(uda134x); return -EINVAL; }
if (ret < 0) { printk(KERN_ERR "UDA134X: failed to register controls\n"); - kfree(uda134x); return ret; }
return 0; }
-/* power down chip */ -static int uda134x_soc_remove(struct snd_soc_codec *codec) -{ - struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); - - kfree(uda134x); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_uda134x = { .probe = uda134x_soc_probe, - .remove = uda134x_soc_remove, .reg_cache_size = sizeof(uda134x_reg), .reg_word_size = sizeof(u8), .reg_cache_default = uda134x_reg, @@ -592,6 +575,14 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
static int uda134x_codec_probe(struct platform_device *pdev) { + struct uda134x_priv *uda134x; + + uda134x = devm_kzalloc(&pdev->dev, sizeof(*uda134x), GFP_KERNEL); + if (!uda134x) + return -ENOMEM; + + platform_set_drvdata(pdev, uda134x); + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_uda134x, &uda134x_dai, 1); }
The patch
ASoC: uda134x: Move state struct allocation to bus probe
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From f15c444e58ed5b5dfc6056249ef8a74d00118be3 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen lars@metafoo.de Date: Mon, 13 Jul 2015 12:26:45 +0200 Subject: [PATCH] ASoC: uda134x: Move state struct allocation to bus probe
Resource allocations should be done in the bus probe rather than the CODEC probe. Move the allocation of the drivers state struct there.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/uda134x.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-)
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 913edf283239..a89f98a773d6 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -478,8 +478,8 @@ static struct snd_soc_dai_driver uda134x_dai = { static int uda134x_soc_probe(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct uda134x_priv *uda134x; struct uda134x_platform_data *pd = codec->component.card->dev->platform_data; + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); const struct snd_soc_dapm_widget *widgets; unsigned num_widgets;
@@ -506,10 +506,6 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) return -EINVAL; }
- uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); - if (uda134x == NULL) - return -ENOMEM; - snd_soc_codec_set_drvdata(codec, uda134x);
codec->control_data = pd;
@@ -530,7 +526,6 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) if (ret) { printk(KERN_ERR "%s failed to register dapm controls: %d", __func__, ret); - kfree(uda134x); return ret; }
@@ -551,31 +546,19 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) default: printk(KERN_ERR "%s unknown codec type: %d", __func__, pd->model); - kfree(uda134x); return -EINVAL; }
if (ret < 0) { printk(KERN_ERR "UDA134X: failed to register controls\n"); - kfree(uda134x); return ret; }
return 0; }
-/* power down chip */ -static int uda134x_soc_remove(struct snd_soc_codec *codec) -{ - struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); - - kfree(uda134x); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_uda134x = { .probe = uda134x_soc_probe, - .remove = uda134x_soc_remove, .reg_cache_size = sizeof(uda134x_reg), .reg_word_size = sizeof(u8), .reg_cache_default = uda134x_reg, @@ -592,6 +575,14 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
static int uda134x_codec_probe(struct platform_device *pdev) { + struct uda134x_priv *uda134x; + + uda134x = devm_kzalloc(&pdev->dev, sizeof(*uda134x), GFP_KERNEL); + if (!uda134x) + return -ENOMEM; + + platform_set_drvdata(pdev, uda134x); + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_uda134x, &uda134x_dai, 1); }
The UDA134X family extends the rather limited L3 register set by using part of the register value as additional address bits.
These extra address bits are currently stored in the default register cache and rely on them remaining constant. While this works it is rather idiomatic and slightly confusing. Change it so that the additional address bits are explicitly added when writing a register.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/uda134x.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index a89f98a..d47da0e 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -39,12 +39,11 @@ struct uda134x_priv { struct snd_pcm_substream *slave_substream; };
-/* In-data addresses are hard-coded into the reg-cache values */ static const char uda134x_reg[UDA134X_REGS_NUM] = { /* Extended address registers */ 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, /* Status, data regs */ - 0x00, 0x83, 0x00, 0x40, 0x80, 0xC0, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, };
/* @@ -99,12 +98,14 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg, case UDA134X_STATUS0: case UDA134X_STATUS1: addr = UDA134X_STATUS_ADDR; + data |= (reg - UDA134X_STATUS0) << 7; break; case UDA134X_DATA000: case UDA134X_DATA001: case UDA134X_DATA010: case UDA134X_DATA011: addr = UDA134X_DATA0_ADDR; + data |= (reg - UDA134X_DATA000) << 6; break; case UDA134X_DATA1: addr = UDA134X_DATA1_ADDR;
The patch
ASoC: uda134x: Explicitly handle in-data addresses
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 82c7b531f3328dbbb7a53d0f1dc53b92846c411c Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen lars@metafoo.de Date: Mon, 13 Jul 2015 12:26:46 +0200 Subject: [PATCH] ASoC: uda134x: Explicitly handle in-data addresses
The UDA134X family extends the rather limited L3 register set by using part of the register value as additional address bits.
These extra address bits are currently stored in the default register cache and rely on them remaining constant. While this works it is rather idiomatic and slightly confusing. Change it so that the additional address bits are explicitly added when writing a register.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/uda134x.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index a89f98a773d6..d47da0ec8f47 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -39,12 +39,11 @@ struct uda134x_priv { struct snd_pcm_substream *slave_substream; };
-/* In-data addresses are hard-coded into the reg-cache values */ static const char uda134x_reg[UDA134X_REGS_NUM] = { /* Extended address registers */ 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, /* Status, data regs */ - 0x00, 0x83, 0x00, 0x40, 0x80, 0xC0, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, };
/* @@ -99,12 +98,14 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg, case UDA134X_STATUS0: case UDA134X_STATUS1: addr = UDA134X_STATUS_ADDR; + data |= (reg - UDA134X_STATUS0) << 7; break; case UDA134X_DATA000: case UDA134X_DATA001: case UDA134X_DATA010: case UDA134X_DATA011: addr = UDA134X_DATA0_ADDR; + data |= (reg - UDA134X_DATA000) << 6; break; case UDA134X_DATA1: addr = UDA134X_DATA1_ADDR;
Use regmap rather then the legacy ASoC IO for the uda134x driver.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/uda134x.c | 115 ++++++++++++++++++++++++--------------------- sound/soc/codecs/uda134x.h | 2 - 2 files changed, 62 insertions(+), 55 deletions(-)
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index d47da0e..d25a9f3 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -37,13 +37,27 @@ struct uda134x_priv {
struct snd_pcm_substream *master_substream; struct snd_pcm_substream *slave_substream; + + struct regmap *regmap; + struct uda134x_platform_data *pd; };
-static const char uda134x_reg[UDA134X_REGS_NUM] = { - /* Extended address registers */ - 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - /* Status, data regs */ - 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, +static const struct reg_default uda134x_reg_defaults[] = { + { UDA134X_EA000, 0x04 }, + { UDA134X_EA001, 0x04 }, + { UDA134X_EA010, 0x04 }, + { UDA134X_EA011, 0x00 }, + { UDA134X_EA100, 0x00 }, + { UDA134X_EA101, 0x00 }, + { UDA134X_EA110, 0x00 }, + { UDA134X_EA111, 0x00 }, + { UDA134X_STATUS0, 0x00 }, + { UDA134X_STATUS1, 0x03 }, + { UDA134X_DATA000, 0x00 }, + { UDA134X_DATA001, 0x00 }, + { UDA134X_DATA010, 0x00 }, + { UDA134X_DATA011, 0x00 }, + { UDA134X_DATA1, 0x00 }, };
/* @@ -52,47 +66,36 @@ static const char uda134x_reg[UDA134X_REGS_NUM] = { static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { - u8 *cache = codec->reg_cache; + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); + unsigned int val; + int ret;
- if (reg >= UDA134X_REGS_NUM) + ret = regmap_read(uda134x->regmap, reg, &val); + if (ret) return -1; - return cache[reg]; + + return val; }
-/* - * Write the register cache - */ -static inline void uda134x_write_reg_cache(struct snd_soc_codec *codec, - u8 reg, unsigned int value) +static void uda134x_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val) { - u8 *cache = codec->reg_cache; + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
- if (reg >= UDA134X_REGS_NUM) - return; - cache[reg] = value; + regmap_write(uda134x->regmap, reg, val); }
/* * Write to the uda134x registers * */ -static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg, +static int uda134x_regmap_write(void *context, unsigned int reg, unsigned int value) { + struct uda134x_platform_data *pd = context; int ret; u8 addr; u8 data = value; - struct uda134x_platform_data *pd = codec->control_data; - - pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value); - - if (reg >= UDA134X_REGS_NUM) { - printk(KERN_ERR "%s unknown register: reg: %u", - __func__, reg); - return -EINVAL; - } - - uda134x_write_reg_cache(codec, reg, value);
switch (reg) { case UDA134X_STATUS0: @@ -325,10 +328,8 @@ static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai, static int uda134x_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - struct uda134x_platform_data *pd = codec->control_data; - int i; - u8 *cache = codec->reg_cache; - + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); + struct uda134x_platform_data *pd = uda134x->pd; pr_debug("%s bias level %d\n", __func__, level);
switch (level) { @@ -338,17 +339,17 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec, /* power on */ if (pd->power) { pd->power(1); - /* Sync reg_cache with the hardware */ - for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++) - codec->driver->write(codec, i, *cache++); + regcache_sync(uda134x->regmap); } break; case SND_SOC_BIAS_STANDBY: break; case SND_SOC_BIAS_OFF: /* power off */ - if (pd->power) + if (pd->power) { pd->power(0); + regcache_mark_dirty(uda134x->regmap); + } break; } return 0; @@ -479,21 +480,14 @@ static struct snd_soc_dai_driver uda134x_dai = { static int uda134x_soc_probe(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct uda134x_platform_data *pd = codec->component.card->dev->platform_data; struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); + struct uda134x_platform_data *pd = uda134x->pd; const struct snd_soc_dapm_widget *widgets; unsigned num_widgets; - int ret;
printk(KERN_INFO "UDA134X SoC Audio Codec\n");
- if (!pd) { - printk(KERN_ERR "UDA134X SoC codec: " - "missing L3 bitbang function\n"); - return -ENODEV; - } - switch (pd->model) { case UDA134X_UDA1340: case UDA134X_UDA1341: @@ -507,9 +501,6 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) return -EINVAL; }
- - codec->control_data = pd; - if (pd->power) pd->power(1);
@@ -560,11 +551,6 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_dev_uda134x = { .probe = uda134x_soc_probe, - .reg_cache_size = sizeof(uda134x_reg), - .reg_word_size = sizeof(u8), - .reg_cache_default = uda134x_reg, - .reg_cache_step = 1, - .read = uda134x_read_reg_cache, .set_bias_level = uda134x_set_bias_level, .suspend_bias_off = true,
@@ -574,16 +560,39 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = { .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes), };
+static const struct regmap_config uda134x_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = UDA134X_DATA1, + .reg_defaults = uda134x_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(uda134x_reg_defaults), + .cache_type = REGCACHE_RBTREE, + + .reg_write = uda134x_regmap_write, +}; + static int uda134x_codec_probe(struct platform_device *pdev) { + struct uda134x_platform_data *pd = pdev->dev.platform_data; struct uda134x_priv *uda134x;
+ if (!pd) { + dev_err(&pdev->dev, "Missing L3 bitbang function\n"); + return -ENODEV; + } + uda134x = devm_kzalloc(&pdev->dev, sizeof(*uda134x), GFP_KERNEL); if (!uda134x) return -ENOMEM;
+ uda134x->pd = pd; platform_set_drvdata(pdev, uda134x);
+ uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd, + &uda134x_regmap_config); + if (IS_ERR(uda134x->regmap)) + return PTR_ERR(uda134x->regmap); + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_uda134x, &uda134x_dai, 1); } diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h index 9faae06..e41ab38 100644 --- a/sound/soc/codecs/uda134x.h +++ b/sound/soc/codecs/uda134x.h @@ -26,8 +26,6 @@ #define UDA134X_DATA011 13 #define UDA134X_DATA1 14
-#define UDA134X_REGS_NUM 15 - #define STATUS0_DAIFMT_MASK (~(7<<1)) #define STATUS0_SYSCLK_MASK (~(3<<4))
The patch
ASoC: uda134x: Convert to regmap
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From f33c340a51e81a2e6af316b1b8b9b769d32ce8b7 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen lars@metafoo.de Date: Mon, 13 Jul 2015 12:26:47 +0200 Subject: [PATCH] ASoC: uda134x: Convert to regmap
Use regmap rather then the legacy ASoC IO for the uda134x driver.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/uda134x.c | 115 ++++++++++++++++++++++++--------------------- sound/soc/codecs/uda134x.h | 2 - 2 files changed, 62 insertions(+), 55 deletions(-)
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index d47da0ec8f47..d25a9f3968d0 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -37,13 +37,27 @@ struct uda134x_priv {
struct snd_pcm_substream *master_substream; struct snd_pcm_substream *slave_substream; + + struct regmap *regmap; + struct uda134x_platform_data *pd; };
-static const char uda134x_reg[UDA134X_REGS_NUM] = { - /* Extended address registers */ - 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - /* Status, data regs */ - 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, +static const struct reg_default uda134x_reg_defaults[] = { + { UDA134X_EA000, 0x04 }, + { UDA134X_EA001, 0x04 }, + { UDA134X_EA010, 0x04 }, + { UDA134X_EA011, 0x00 }, + { UDA134X_EA100, 0x00 }, + { UDA134X_EA101, 0x00 }, + { UDA134X_EA110, 0x00 }, + { UDA134X_EA111, 0x00 }, + { UDA134X_STATUS0, 0x00 }, + { UDA134X_STATUS1, 0x03 }, + { UDA134X_DATA000, 0x00 }, + { UDA134X_DATA001, 0x00 }, + { UDA134X_DATA010, 0x00 }, + { UDA134X_DATA011, 0x00 }, + { UDA134X_DATA1, 0x00 }, };
/* @@ -52,47 +66,36 @@ static const char uda134x_reg[UDA134X_REGS_NUM] = { static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { - u8 *cache = codec->reg_cache; + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); + unsigned int val; + int ret;
- if (reg >= UDA134X_REGS_NUM) + ret = regmap_read(uda134x->regmap, reg, &val); + if (ret) return -1; - return cache[reg]; + + return val; }
-/* - * Write the register cache - */ -static inline void uda134x_write_reg_cache(struct snd_soc_codec *codec, - u8 reg, unsigned int value) +static void uda134x_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val) { - u8 *cache = codec->reg_cache; + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
- if (reg >= UDA134X_REGS_NUM) - return; - cache[reg] = value; + regmap_write(uda134x->regmap, reg, val); }
/* * Write to the uda134x registers * */ -static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg, +static int uda134x_regmap_write(void *context, unsigned int reg, unsigned int value) { + struct uda134x_platform_data *pd = context; int ret; u8 addr; u8 data = value; - struct uda134x_platform_data *pd = codec->control_data; - - pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value); - - if (reg >= UDA134X_REGS_NUM) { - printk(KERN_ERR "%s unknown register: reg: %u", - __func__, reg); - return -EINVAL; - } - - uda134x_write_reg_cache(codec, reg, value);
switch (reg) { case UDA134X_STATUS0: @@ -325,10 +328,8 @@ static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai, static int uda134x_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - struct uda134x_platform_data *pd = codec->control_data; - int i; - u8 *cache = codec->reg_cache; - + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); + struct uda134x_platform_data *pd = uda134x->pd; pr_debug("%s bias level %d\n", __func__, level);
switch (level) { @@ -338,17 +339,17 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec, /* power on */ if (pd->power) { pd->power(1); - /* Sync reg_cache with the hardware */ - for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++) - codec->driver->write(codec, i, *cache++); + regcache_sync(uda134x->regmap); } break; case SND_SOC_BIAS_STANDBY: break; case SND_SOC_BIAS_OFF: /* power off */ - if (pd->power) + if (pd->power) { pd->power(0); + regcache_mark_dirty(uda134x->regmap); + } break; } return 0; @@ -479,21 +480,14 @@ static struct snd_soc_dai_driver uda134x_dai = { static int uda134x_soc_probe(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct uda134x_platform_data *pd = codec->component.card->dev->platform_data; struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); + struct uda134x_platform_data *pd = uda134x->pd; const struct snd_soc_dapm_widget *widgets; unsigned num_widgets; - int ret;
printk(KERN_INFO "UDA134X SoC Audio Codec\n");
- if (!pd) { - printk(KERN_ERR "UDA134X SoC codec: " - "missing L3 bitbang function\n"); - return -ENODEV; - } - switch (pd->model) { case UDA134X_UDA1340: case UDA134X_UDA1341: @@ -507,9 +501,6 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) return -EINVAL; }
- - codec->control_data = pd; - if (pd->power) pd->power(1);
@@ -560,11 +551,6 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_dev_uda134x = { .probe = uda134x_soc_probe, - .reg_cache_size = sizeof(uda134x_reg), - .reg_word_size = sizeof(u8), - .reg_cache_default = uda134x_reg, - .reg_cache_step = 1, - .read = uda134x_read_reg_cache, .set_bias_level = uda134x_set_bias_level, .suspend_bias_off = true,
@@ -574,16 +560,39 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = { .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes), };
+static const struct regmap_config uda134x_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = UDA134X_DATA1, + .reg_defaults = uda134x_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(uda134x_reg_defaults), + .cache_type = REGCACHE_RBTREE, + + .reg_write = uda134x_regmap_write, +}; + static int uda134x_codec_probe(struct platform_device *pdev) { + struct uda134x_platform_data *pd = pdev->dev.platform_data; struct uda134x_priv *uda134x;
+ if (!pd) { + dev_err(&pdev->dev, "Missing L3 bitbang function\n"); + return -ENODEV; + } + uda134x = devm_kzalloc(&pdev->dev, sizeof(*uda134x), GFP_KERNEL); if (!uda134x) return -ENOMEM;
+ uda134x->pd = pd; platform_set_drvdata(pdev, uda134x);
+ uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd, + &uda134x_regmap_config); + if (IS_ERR(uda134x->regmap)) + return PTR_ERR(uda134x->regmap); + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_uda134x, &uda134x_dai, 1); } diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h index 9faae06972b3..e41ab38c6f69 100644 --- a/sound/soc/codecs/uda134x.h +++ b/sound/soc/codecs/uda134x.h @@ -26,8 +26,6 @@ #define UDA134X_DATA011 13 #define UDA134X_DATA1 14
-#define UDA134X_REGS_NUM 15 - #define STATUS0_DAIFMT_MASK (~(7<<1)) #define STATUS0_SYSCLK_MASK (~(3<<4))
Instead of doing the read-modify-update cycle by hand when updating a register use regmap_update_bits().
This also means we can now remove uda134x_read_reg_cache() and uda134x_write() since they are unused.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/uda134x.c | 57 ++++++++++++---------------------------------- 1 file changed, 14 insertions(+), 43 deletions(-)
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index d25a9f3..e190263 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -61,31 +61,6 @@ static const struct reg_default uda134x_reg_defaults[] = { };
/* - * The codec has no support for reading its registers except for peak level... - */ -static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); - unsigned int val; - int ret; - - ret = regmap_read(uda134x->regmap, reg, &val); - if (ret) - return -1; - - return val; -} - -static void uda134x_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int val) -{ - struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); - - regmap_write(uda134x->regmap, reg, val); -} - -/* * Write to the uda134x registers * */ @@ -137,27 +112,28 @@ static int uda134x_regmap_write(void *context, unsigned int reg,
static inline void uda134x_reset(struct snd_soc_codec *codec) { - u8 reset_reg = uda134x_read_reg_cache(codec, UDA134X_STATUS0); - uda134x_write(codec, UDA134X_STATUS0, reset_reg | (1<<6)); + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); + unsigned int mask = 1<<6; + + regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, mask, mask); msleep(1); - uda134x_write(codec, UDA134X_STATUS0, reset_reg & ~(1<<6)); + regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, mask, 0); }
static int uda134x_mute(struct snd_soc_dai *dai, int mute) { - struct snd_soc_codec *codec = dai->codec; - u8 mute_reg = uda134x_read_reg_cache(codec, UDA134X_DATA010); + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(dai->codec); + unsigned int mask = 1<<2; + unsigned int val;
pr_debug("%s mute: %d\n", __func__, mute);
if (mute) - mute_reg |= (1<<2); + val = mask; else - mute_reg &= ~(1<<2); - - uda134x_write(codec, UDA134X_DATA010, mute_reg); + val = 0;
- return 0; + return regmap_update_bits(uda134x->regmap, UDA134X_DATA010, mask, val); }
static int uda134x_startup(struct snd_pcm_substream *substream, @@ -209,7 +185,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_codec *codec = dai->codec; struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); - u8 hw_params; + unsigned int hw_params = 0;
if (substream == uda134x->slave_substream) { pr_debug("%s ignoring hw_params for slave substream\n", @@ -217,10 +193,6 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream, return 0; }
- hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0); - hw_params &= STATUS0_SYSCLK_MASK; - hw_params &= STATUS0_DAIFMT_MASK; - pr_debug("%s sysclk: %d, rate:%d\n", __func__, uda134x->sysclk, params_rate(params));
@@ -271,9 +243,8 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream, return -EINVAL; }
- uda134x_write(codec, UDA134X_STATUS0, hw_params); - - return 0; + return regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, + STATUS0_SYSCLK_MASK | STATUS0_DAIFMT_MASK, hw_params); }
static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
The patch
ASoC: uda134x: Use regmap_update_bits() were appropriate
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From ef3355d22046f4b2c00b0fdf964d6c92fd3f050d Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen lars@metafoo.de Date: Mon, 13 Jul 2015 12:26:48 +0200 Subject: [PATCH] ASoC: uda134x: Use regmap_update_bits() were appropriate
Instead of doing the read-modify-update cycle by hand when updating a register use regmap_update_bits().
This also means we can now remove uda134x_read_reg_cache() and uda134x_write() since they are unused.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/uda134x.c | 57 ++++++++++++---------------------------------- 1 file changed, 14 insertions(+), 43 deletions(-)
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index d25a9f3968d0..e19026380534 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -61,31 +61,6 @@ static const struct reg_default uda134x_reg_defaults[] = { };
/* - * The codec has no support for reading its registers except for peak level... - */ -static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); - unsigned int val; - int ret; - - ret = regmap_read(uda134x->regmap, reg, &val); - if (ret) - return -1; - - return val; -} - -static void uda134x_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int val) -{ - struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); - - regmap_write(uda134x->regmap, reg, val); -} - -/* * Write to the uda134x registers * */ @@ -137,27 +112,28 @@ static int uda134x_regmap_write(void *context, unsigned int reg,
static inline void uda134x_reset(struct snd_soc_codec *codec) { - u8 reset_reg = uda134x_read_reg_cache(codec, UDA134X_STATUS0); - uda134x_write(codec, UDA134X_STATUS0, reset_reg | (1<<6)); + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); + unsigned int mask = 1<<6; + + regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, mask, mask); msleep(1); - uda134x_write(codec, UDA134X_STATUS0, reset_reg & ~(1<<6)); + regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, mask, 0); }
static int uda134x_mute(struct snd_soc_dai *dai, int mute) { - struct snd_soc_codec *codec = dai->codec; - u8 mute_reg = uda134x_read_reg_cache(codec, UDA134X_DATA010); + struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(dai->codec); + unsigned int mask = 1<<2; + unsigned int val;
pr_debug("%s mute: %d\n", __func__, mute);
if (mute) - mute_reg |= (1<<2); + val = mask; else - mute_reg &= ~(1<<2); - - uda134x_write(codec, UDA134X_DATA010, mute_reg); + val = 0;
- return 0; + return regmap_update_bits(uda134x->regmap, UDA134X_DATA010, mask, val); }
static int uda134x_startup(struct snd_pcm_substream *substream, @@ -209,7 +185,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_codec *codec = dai->codec; struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); - u8 hw_params; + unsigned int hw_params = 0;
if (substream == uda134x->slave_substream) { pr_debug("%s ignoring hw_params for slave substream\n", @@ -217,10 +193,6 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream, return 0; }
- hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0); - hw_params &= STATUS0_SYSCLK_MASK; - hw_params &= STATUS0_DAIFMT_MASK; - pr_debug("%s sysclk: %d, rate:%d\n", __func__, uda134x->sysclk, params_rate(params));
@@ -271,9 +243,8 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream, return -EINVAL; }
- uda134x_write(codec, UDA134X_STATUS0, hw_params); - - return 0; + return regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, + STATUS0_SYSCLK_MASK | STATUS0_DAIFMT_MASK, hw_params); }
static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
On Mon, Jul 13, 2015 at 12:26:44PM +0200, Lars-Peter Clausen wrote:
Currently regmap requires that a reg_read callback is supplied, otherwise a warning is emitted each time regmap_read() is called. This means a device or bus without readback support needs to supply dummy reg_read callback. Apart from that regmap_read() will still work fine if a cache is used.
This really shouldn't be in the same series as the uda138x stuff, there's no real interdependency.
participants (2)
-
Lars-Peter Clausen
-
Mark Brown