From 58cd33c0f375578cfda25a52ed280caa888b6254 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 29 Jul 2008 11:42:25 +0100 Subject: ALSA: ASoC: Allow codecs to override register display Some codecs have unusual features in their register maps such as very large registers representing arrays of coefficients. Support these codecs in the register cache sysfs file by allowing them to provide a function register_display() overriding the default output for register contents. Also ensure that we don't overflow PAGE_SIZE while writing out the register dump. Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/soc/soc-core.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'sound/soc/soc-core.c') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 83f1190293a..5d3bf731a4b 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -970,9 +970,29 @@ static ssize_t codec_reg_show(struct device *dev, step = codec->reg_cache_step; count += sprintf(buf, "%s registers\n", codec->name); - for (i = 0; i < codec->reg_cache_size; i += step) - count += sprintf(buf + count, "%2x: %4x\n", i, - codec->read(codec, i)); + for (i = 0; i < codec->reg_cache_size; i += step) { + count += sprintf(buf + count, "%2x: ", i); + if (count >= PAGE_SIZE - 1) + break; + + if (codec->display_register) + count += codec->display_register(codec, buf + count, + PAGE_SIZE - count, i); + else + count += snprintf(buf + count, PAGE_SIZE - count, + "%4x", codec->read(codec, i)); + + if (count >= PAGE_SIZE - 1) + break; + + count += snprintf(buf + count, PAGE_SIZE - count, "\n"); + if (count >= PAGE_SIZE - 1) + break; + } + + /* Truncate count; min() would cause a warning */ + if (count >= PAGE_SIZE) + count = PAGE_SIZE - 1; return count; } -- cgit v1.2.3 From 4eaa9819dc08d7bfd1065ce530e31b18a119dcaf Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Tue, 29 Jul 2008 11:42:26 +0100 Subject: ALSA: ASoC: Convert bitfields in ASoC into full int width Convert bitfields in ASoC into full int width. This is a simple mechanical conversion. Two places in the DAPM code were fixed to properly use mask. Signed-off-by: Jon Smirl Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/soc/soc-core.c | 86 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 34 deletions(-) (limited to 'sound/soc/soc-core.c') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 5d3bf731a4b..4b94f1f6ee2 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1454,9 +1454,11 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext); int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - int max = (kcontrol->private_value >> 16) & 0xff; - int shift = (kcontrol->private_value >> 8) & 0x0f; - int rshift = (kcontrol->private_value >> 12) & 0x0f; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int max = mc->max; + uint shift = mc->min; + uint rshift = mc->rshift; if (max == 1) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; @@ -1482,13 +1484,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw); int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0x0f; - int rshift = (kcontrol->private_value >> 12) & 0x0f; - int max = (kcontrol->private_value >> 16) & 0xff; - int mask = (1 << fls(max)) - 1; - int invert = (kcontrol->private_value >> 24) & 0x01; + uint reg = mc->reg; + uint shift = mc->shift; + uint rshift = mc->rshift; + int max = mc->max; + uint mask = (1 << fls(max)) - 1; + uint invert = mc->invert; ucontrol->value.integer.value[0] = (snd_soc_read(codec, reg) >> shift) & mask; @@ -1519,13 +1523,15 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw); int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0x0f; - int rshift = (kcontrol->private_value >> 12) & 0x0f; - int max = (kcontrol->private_value >> 16) & 0xff; - int mask = (1 << fls(max)) - 1; - int invert = (kcontrol->private_value >> 24) & 0x01; + uint reg = mc->reg; + uint shift = mc->shift; + uint rshift = mc->rshift; + int max = mc->max; + uint mask = (1 << fls(max)) - 1; + uint invert = mc->invert; unsigned short val, val2, val_mask; val = (ucontrol->value.integer.value[0] & mask); @@ -1557,7 +1563,9 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw); int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - int max = (kcontrol->private_value >> 12) & 0xff; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int max = mc->max; if (max == 1) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; @@ -1583,13 +1591,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r); int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int reg2 = (kcontrol->private_value >> 24) & 0xff; - int shift = (kcontrol->private_value >> 8) & 0x0f; - int max = (kcontrol->private_value >> 12) & 0xff; - int mask = (1<private_value >> 20) & 0x01; + uint reg = mc->reg; + uint reg2 = mc->rreg; + uint shift = mc->shift; + int max = mc->max; + uint mask = (1<invert; ucontrol->value.integer.value[0] = (snd_soc_read(codec, reg) >> shift) & mask; @@ -1618,13 +1628,15 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r); int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int reg2 = (kcontrol->private_value >> 24) & 0xff; - int shift = (kcontrol->private_value >> 8) & 0x0f; - int max = (kcontrol->private_value >> 12) & 0xff; - int mask = (1 << fls(max)) - 1; - int invert = (kcontrol->private_value >> 20) & 0x01; + uint reg = mc->reg; + uint reg2 = mc->rreg; + uint shift = mc->shift; + int max = mc->max; + uint mask = (1 << fls(max)) - 1; + uint invert = mc->invert; int err; unsigned short val, val2, val_mask; @@ -1661,8 +1673,10 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - int max = (signed char)((kcontrol->private_value >> 16) & 0xff); - int min = (signed char)((kcontrol->private_value >> 24) & 0xff); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int max = mc->max; + int min = mc->min; uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 2; @@ -1684,9 +1698,11 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8); int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int min = (signed char)((kcontrol->private_value >> 24) & 0xff); + uint reg = mc->reg; + int min = mc->min; int val = snd_soc_read(codec, reg); ucontrol->value.integer.value[0] = @@ -1709,9 +1725,11 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8); int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int min = (signed char)((kcontrol->private_value >> 24) & 0xff); + uint reg = mc->reg; + int min = mc->min; unsigned short val; val = (ucontrol->value.integer.value[0]+min) & 0xff; -- cgit v1.2.3 From f8ba0b7bfd06a2a5b3c49ff8d71cad31f57b0d51 Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Tue, 29 Jul 2008 11:42:27 +0100 Subject: ALSA: ASoC: Rename mask to max to reflect usage Most of the ASoC controls refer to the maximum value that can be set for a control as mask but there is no actual requirement for all bits to be set at the highest possible value making the name mask misleading. Change the code to use max instead. Signed-off-by: Jon Smirl Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/soc/soc-core.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'sound/soc/soc-core.c') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4b94f1f6ee2..11a881caba7 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1316,10 +1316,10 @@ int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = e->shift_l == e->shift_r ? 1 : 2; - uinfo->value.enumerated.items = e->mask; + uinfo->value.enumerated.items = e->max; - if (uinfo->value.enumerated.item > e->mask - 1) - uinfo->value.enumerated.item = e->mask - 1; + if (uinfo->value.enumerated.item > e->max - 1) + uinfo->value.enumerated.item = e->max - 1; strcpy(uinfo->value.enumerated.name, e->texts[uinfo->value.enumerated.item]); return 0; @@ -1342,7 +1342,7 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned short val, bitmask; - for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) + for (bitmask = 1; bitmask < e->max; bitmask <<= 1) ; val = snd_soc_read(codec, e->reg); ucontrol->value.enumerated.item[0] @@ -1372,14 +1372,14 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, unsigned short val; unsigned short mask, bitmask; - for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) + for (bitmask = 1; bitmask < e->max; bitmask <<= 1) ; - if (ucontrol->value.enumerated.item[0] > e->mask - 1) + if (ucontrol->value.enumerated.item[0] > e->max - 1) return -EINVAL; val = ucontrol->value.enumerated.item[0] << e->shift_l; mask = (bitmask - 1) << e->shift_l; if (e->shift_l != e->shift_r) { - if (ucontrol->value.enumerated.item[1] > e->mask - 1) + if (ucontrol->value.enumerated.item[1] > e->max - 1) return -EINVAL; val |= ucontrol->value.enumerated.item[1] << e->shift_r; mask |= (bitmask - 1) << e->shift_r; @@ -1406,10 +1406,10 @@ int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; - uinfo->value.enumerated.items = e->mask; + uinfo->value.enumerated.items = e->max; - if (uinfo->value.enumerated.item > e->mask - 1) - uinfo->value.enumerated.item = e->mask - 1; + if (uinfo->value.enumerated.item > e->max - 1) + uinfo->value.enumerated.item = e->max - 1; strcpy(uinfo->value.enumerated.name, e->texts[uinfo->value.enumerated.item]); return 0; -- cgit v1.2.3 From 815ecf8dec95d07e260a16ebe8409f4b7c0fdc0f Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Tue, 29 Jul 2008 10:22:24 -0400 Subject: ALSA: ASoC: convert use of uint to unsigned int ASOC: convert use of uint to unsigned int Signed-off-by: Jon Smirl Acked-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/soc/soc-core.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'sound/soc/soc-core.c') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 11a881caba7..1563ceedf61 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1457,8 +1457,8 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; int max = mc->max; - uint shift = mc->min; - uint rshift = mc->rshift; + unsigned int shift = mc->min; + unsigned int rshift = mc->rshift; if (max == 1) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; @@ -1487,12 +1487,12 @@ int snd_soc_get_volsw(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); - uint reg = mc->reg; - uint shift = mc->shift; - uint rshift = mc->rshift; + unsigned int reg = mc->reg; + unsigned int shift = mc->shift; + unsigned int rshift = mc->rshift; int max = mc->max; - uint mask = (1 << fls(max)) - 1; - uint invert = mc->invert; + unsigned int mask = (1 << fls(max)) - 1; + unsigned int invert = mc->invert; ucontrol->value.integer.value[0] = (snd_soc_read(codec, reg) >> shift) & mask; @@ -1526,12 +1526,12 @@ int snd_soc_put_volsw(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); - uint reg = mc->reg; - uint shift = mc->shift; - uint rshift = mc->rshift; + unsigned int reg = mc->reg; + unsigned int shift = mc->shift; + unsigned int rshift = mc->rshift; int max = mc->max; - uint mask = (1 << fls(max)) - 1; - uint invert = mc->invert; + unsigned int mask = (1 << fls(max)) - 1; + unsigned int invert = mc->invert; unsigned short val, val2, val_mask; val = (ucontrol->value.integer.value[0] & mask); @@ -1594,12 +1594,12 @@ int snd_soc_get_volsw_2r(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); - uint reg = mc->reg; - uint reg2 = mc->rreg; - uint shift = mc->shift; + unsigned int reg = mc->reg; + unsigned int reg2 = mc->rreg; + unsigned int shift = mc->shift; int max = mc->max; - uint mask = (1<invert; + unsigned int mask = (1<invert; ucontrol->value.integer.value[0] = (snd_soc_read(codec, reg) >> shift) & mask; @@ -1631,12 +1631,12 @@ int snd_soc_put_volsw_2r(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); - uint reg = mc->reg; - uint reg2 = mc->rreg; - uint shift = mc->shift; + unsigned int reg = mc->reg; + unsigned int reg2 = mc->rreg; + unsigned int shift = mc->shift; int max = mc->max; - uint mask = (1 << fls(max)) - 1; - uint invert = mc->invert; + unsigned int mask = (1 << fls(max)) - 1; + unsigned int invert = mc->invert; int err; unsigned short val, val2, val_mask; @@ -1701,7 +1701,7 @@ 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); - uint reg = mc->reg; + unsigned int reg = mc->reg; int min = mc->min; int val = snd_soc_read(codec, reg); @@ -1728,7 +1728,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); - uint reg = mc->reg; + unsigned int reg = mc->reg; int min = mc->min; unsigned short val; -- cgit v1.2.3 From 6010b2da1f11752dd58191423fc9878b0ce420c8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 6 Sep 2008 18:33:24 +0100 Subject: ALSA: ASoC: Use codec digital mute when stopping playback Muting the DAC masks artefacts introduced as the digital stream shuts down, for example when the input stops being clocked. Signed-off-by: Mark Brown Signed-off-by: Jaroslav Kysela --- sound/soc/soc-core.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/soc/soc-core.c') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 1563ceedf61..ad381138fc2 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -340,6 +340,12 @@ static int soc_codec_close(struct snd_pcm_substream *substream) } codec->active--; + /* Muting the DAC suppresses artifacts caused during digital + * shutdown, for example from stopping clocks. + */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + snd_soc_dai_digital_mute(codec_dai, 1); + if (cpu_dai->ops.shutdown) cpu_dai->ops.shutdown(substream); -- cgit v1.2.3