Since commit a729526720 ("ASoC: sgtl5000: add avc support") the
following kernel crash happens after running a 'reboot' command:
ALSA: Storing mixer settings...
[ 20.031604] Unable to handle kernel paging request at virtual address fffffffe
[ 20.039268] pgd = de2a0000
[ 20.041999] [fffffffe] *pgd=8fffd861, *pte=00000000, *ppte=00000000
[ 20.048387] Internal error: Oops: 80000007 [#1] SMP ARM
The function that takes a kcontrol parameter and returns the
codec that registered the control is snd_soc_kcontrol_codec(),
so use the correct function to fix the problem.
Fixes: a729526720 ("ASoC: sgtl5000: add avc support")
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Tested-by: Richard Leitner <richard.leitner@skidata.com>
Reviewed-by: Richard Leitner <richard.leitner@skidata.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
The sgtl5000 features an automatic volume control block (AVC), which
reduces loud signals and amplifies low level signals for easier
listening. This patch adds support for this AVC block to the driver.
Apart from the "AVC Switch" control which enables the block following
controls for the configuration of AVC are added:
+ AVC Threshold Volume: threshold where audio is compressed when
the measured level is above or expanded when below
+ AVC Max Gain Volume: maximum gain which can be applied when
the measured audio level is below threshold
+ AVC Hard Limiter Switch: when enabled the signal is limited to
the programmed threshold.
+ AVC Integrator Response: response time of the integrator
The AVC block is enabled and configured using the DAP_AVC_CTRL and
DAP_AVC_THRESHOLD registers.
Following 2 checkpatch.pl strict checks are ignored because the
indentation style is different for the struct snd_kcontrol_new
definition:
patch:147: CHECK: Alignment should match open parenthesis
patch:150: CHECK: Alignment should match open parenthesis
Signed-off-by: Richard Leitner <richard.leitner@skidata.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Introduce the "lrclk-strength" property to allow LRCLK pad drive strength
to be changed via device tree.
When running a stress playback loop test on a mx6dl wandboard channel
swap can be noticed on about 10% of the times.
While debugging this issue I noticed that when probing the SGTL5000
LRCLK pin with the scope the swap did not happen. After removing
the probe the swap started to happen again.
After changing the LRCLK pad drive strength to the maximum value the
issue is gone.
Same fix works on a mx6dl Colibri board as well.
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Tested-by: Max Krummenacher <max.krummenacher@toradex.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
These controls mute/unmute the LINEOUT and headphone outputs of SGTL5000
using its CHIP_ANA_CTRL register.
Signed-off-by: Richard Leitner <dev@g0hl1n.net>
Signed-off-by: Mark Brown <broonie@kernel.org>
codec driver and component driver has duplicated callback functions,
and codec side functions are just copied to component side when
register timing. This was quick-hack, but no longer needed.
This patch moves these functions from codec driver to component driver.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This controls the volume for the line out pins of SGTL5000.
Signed-off-by: Fabien Lahoudere <fabien.lahoudere@collabora.co.uk>
Signed-off-by: Mark Brown <broonie@kernel.org>
Disabling the SGTL5000 through regulators would certainly save more
power than simply disabling the reference voltages as described in the
data sheet, but won't properly restore things on resume.
This driver does not support active regulators. So we simply disable the
reference bias currents.
Signed-off-by: Eric Nelson <eric@nelint.com>
Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
To handle the soft reboot case, the internal PLL must be
disabled in SGTL5000_CHIP_CLK_CTRL before clearing bits
SGTL5000_VCOAMP_POWERUP and SGTL5000_PLL_POWERUP in
register SGTL5000_CHIP_ANA_POWER.
Signed-off-by: Eric Nelson <eric@nelint.com>
Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Initialize CHIP_ANA_POWER to match power on defaults, which disables
ADC, DAC, and charge pumps.
In the process, remove references to the following register/bitfields
from the sgtl5000_set_power_regs routine:
CHIP_ANA_POWER/LINREG_SIMPLE_POWERUP and
CHIP_LINREG_CTRL/LINREG_VDD_MASK
And remove CHIP_ANA_POWER and CHIP_LINREG_CTRL from the set of default
registers so they don't get clobbered by sgtl5000_fill_defaults().
Signed-off-by: Eric Nelson <eric@nelint.com>
Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
If an error occurs writing defaults, produce an error message but
continue writing other registers. The failure of a single write should
not cause catastrophic device failure.
In at least one occurrence, I2C writes of CHIP_ANA_POWER were nacked,
though continuing allowed the device to operate properly.
Signed-off-by: Eric Nelson <eric@nelint.com>
Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Regulator support on SGTL5000 is broken because the VDDIO and
VDDA and VDDD should be powered on before enabling MCLK as
shown in Figure 4 of [1]. This requires moving control of the
regulators from the codec block to the I2C block of the driver.
The bulk of this patch consists of swapping the codec device with
the i2c client. The new field num_supplies in struct sgtl5000_priv
is used instead of ARRAY_SIZE(supplies) to handle the special case
when the internal LDO is used instead of external VDDD.
Note that ER1 in the SGTL5000 Errata document [2] suggests that
all designs should use external VDDD.
Since the internal LDO can only be enabled after I2C is available,
there's no benefit in treating it as a regulator, so this patch
removes the regulator structure surrounding it.
Instead, a single block of code in sgtl5000_i2c_probe() performs
the initialization sequence in section 2.2.1.1 of [3] and page
26 of [1].
References:
[1] SGTL5000 data sheet
http://cache.nxp.com/files/analog/doc/data_sheet/SGTL5000.pdf
[2] SGTL5000 errata
http://cache.nxp.com/files/analog/doc/errata/SGTL5000ER.pdf
[3] SGTL5000 Initialization and programming app note
http://cache.nxp.com/files/analog/doc/app_note/AN3663.pdf
Signed-off-by: Eric Nelson <eric@nelint.com>
Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
All new designs should use external VDDD according to official
documentation. See ER1 in errata sheet:
http://cache.nxp.com/files/analog/doc/errata/SGTL5000ER.pdf
Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
When power up, a "pop" is heard on line-in and mic-in.
An analysis of the PCM shows it lasts ~400ms
and looks like a filter response.
VAG power up should be delayed by 400ms as VAG power down is.
Signed-off-by: Jean-Michel Hautbois <jean-michel.hautbois@veo-labs.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
DECLARE_TLV_DB_RANGE() has the advantage over using TLV_DB_RANGE_HEAD()
that it automatically calculates the number of items in the TLV and is
hence less prone to manual error.
Generate using the following coccinelle script
// <smpl>
@@
declarer name DECLARE_TLV_DB_RANGE;
identifier tlv;
constant x;
@@
-unsigned int tlv[] = {
- TLV_DB_RANGE_HEAD(x),
+DECLARE_TLV_DB_RANGE(tlv,
...
-};
+);
// </smpl>
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
i2c_driver does not need to set an owner because i2c_register_driver()
will set it.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
The dapm field of the snd_soc_codec struct is eventually going to be
removed, in preparation for this replace all manual access to
codec->dapm.bias_level with snd_soc_codec_get_bias_level().
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
All drivers have the same line at the end of the set_bias_level callback to
update the bias_level state. Move this update into
snd_soc_dapm_force_bias_level() and remove them from the drivers.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
Currently LO_VOL_* stays at it's default (0x4 each) but this should be
calculated after setting VAG_VAL and LO_VAGCNTRL.
LO_VOL_* = 40 * log10(VAG_VAL / LO_VAGCNTRL) + 15
To avoid the log10 operation a table for all valid register values is
precalculated which contains the corresponding value
(VAG_VAL * 100 / LO_VAGCNTRL).
Signed-off-by: Alexander Stein <alexander.stein@systec-electronic.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This is a preparation for calculating lo_vol which needs both vag
and lo_vag.
Signed-off-by: Alexander Stein <alexander.stein@systec-electronic.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
The SGTL5000_CHIP_ANA_POWER register is cached. Update the cached
value instead of writing it directly.
Patch inspired by Russell King's more colorful remarks in this
patch:
https://github.com/SolidRun/linux-imx6-3.14/commit/dd4bf6a
Signed-off-by: Eric Nelson <eric.nelson@boundarydevices.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
To quote from section 1.3.1 of the data sheet:
The SGTL5000 has an internal reset that is deasserted
8 SYS_MCLK cycles after all power rails have been brought
up. After this time, communication can start
...
1.0us represents 8 SYS_MCLK cycles at the minimum 8.0 MHz SYS_MCLK.
Signed-off-by: Eric Nelson <eric.nelson@boundarydevices.com>
Reviewed-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
Shift the I2S mode value by the necessary amount before writing the
registers. This makes Right Justified and PCM mode work in addition to
the default Left Justified mode.
Signed-off-by: Filip Brozovic <fbrozovic@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
The codec field of the snd_soc_widget struct is eventually going to be
removed, use snd_soc_dapm_to_codec(w->dapm) instead.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
When trying to play a 8kHz file with codec in slave mode we get the following
error on a mx28evk:
$ aplay -Dhw:0,0 stereo_8k.wav
Playing WAVE 'stereo_8k.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Stereo
[ 21.218647] sgtl5000 0-000a: PLL not supported in slave mode
[ 21.224559] sgtl5000 0-000a: 128 ratio is not supported. SYS_MCLK needs to be 256, 384 or 512 * fs
[ 21.233687] sgtl5000 0-000a: ASoC: can't set sgtl5000 hw params: -22
aplay: set_params:1123: Unable to install hw params:
This error happens because we are using 'sys_fs' instead of 'frame_rate' in the
valid ratio check.
Use the real'frame_rate' so that the ratio is correctly calculated and the
playback can run.
sgtl5000 codec manual states that in 'Synchronous SYS_MCLK input' mode that the
following SYS_CLK frequencies are allowed: 256*fs, 384*fs, 512*fs.
, where fs is the sampling frequency, which can be in the range of:
8, 11.025, 16, 22.5, 32, 44.1, 48, 96 kHz.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
According to the sgtl5000 datasheet the MCLK frequency range restriction of
8 to 27 MHz only applies when the PLL is used - synchronous SYS_MCLK input mode.
When running the codec as slave, the master should generate MCLK in the range of
256*fs, 384*fs or 512*fs, which is called asynchronous SYS_MCLK input mode.
In asynchronous SYS_MCLK we cannot have the 8 to 27 MHz check because if we
want to play a 8KHz sample rate track, with a MCLK of 8k * 512 = 4.096MHz the
current check would return -EINVAL, which is not correct.
Remove the 8 to 27MHz frequency check, since this only applies to the
synchronous SYS_MCLK input case.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
On a mx28evk with a sgtl5000 codec we notice a loud 'click' sound to happen
5 seconds after the end of a playback.
The SMALL_POP bit should fix this, but its definition is incorrect:
according to the sgtl5000 manual it is bit 0 of CHIP_REF_CTRL register, not
bit 1.
Fix the definition accordingly and enable the bit as intended per the code
comment.
After applying this change, no loud 'click' sound is heard after playback
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
According to Documentation/CodingStyle - Chapter 14:
"The preferred form for passing a size of a struct is the following:
p = kmalloc(sizeof(*p), ...);
The alternative form where struct name is spelled out hurts readability and
introduces an opportunity for a bug when the pointer variable type is changed
but the corresponding sizeof that is passed to a memory allocator is not."
So do it as recommeded.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Some systems may require to specify a bias different than default (1.25V).
This adds a property in sgtl5000 codec.
The property is specified in milli-volts so that it is coherent with datasheet.
Signed-off-by: Jean-Michel Hautbois <jean-michel.hautbois@vodalys.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Some systems may require a different resistor than the default one (4K).
This adds a property in sgtl5000 codec.
It keeps the default of 4K when nothing is specified so it does not break
existing code.
Signed-off-by: Jean-Michel Hautbois <jean-michel.hautbois@vodalys.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Fix grammar and typos.
Besides that, also fix the comment about the range of SYS_MCLK, which is from
8 to 27 MHz.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
According to the sgtl5000 datasheet the valid range for SYS_MCLK is from 8 to
27 MHz.
Add a sanity check prior to enabling SYS_MCLK.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
For sgtl5000 to operate in slave mode it can only work in "Synchronous
SYS_MCLK input" mode.
In this mode only the following rates can be supported: 256*Fs, 384*Fs, 512*Fs.
Improve the error message to give a better indication as to why the clocking
failed for slave mode:
[ 12.515399] sgtl5000 1-000a: PLL not supported in slave mode
[ 12.524124] sgtl5000 1-000a: 233 ratio is not supported. SYS_MCLK needs to be 256, 384 or 512 * fs
[ 12.535938] sgtl5000 1-000a: ASoC: can't set sgtl5000 hw params: -22
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Set the CODEC driver's suspend_bias_off flag rather than manually going to
SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes
the code a bit shorter and cleaner.
Since the ASoC core now takes care of setting the bias level to
SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually
anymore either.
The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe()
can also be removed as the core will automatically do this after the CODEC
has been probed.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
Using the sgtl5000 codec driver as a module and trying to remove it causes the
followig kernel oops:
root@freescale /$ rmmod snd-soc-imx-sgtl5000
[ 117.122920] ------------[ cut here ]------------
[ 117.127609] WARNING: CPU: 0 PID: 631 at drivers/regulator/core.c:3604 regula)
[ 117.137046] Modules linked in: snd_soc_imx_sgtl5000(-) snd_soc_sgtl5000 evbug
[ 117.144315] CPU: 0 PID: 631 Comm: rmmod Not tainted 3.16.0-rc3-next-201407043
[ 117.153366] Backtrace:
[ 117.155865] [<80011e5c>] (dump_backtrace) from [<80011ff8>] (show_stack+0x18)
[ 117.163484] r6:802fcc48 r5:00000000 r4:00000000 r3:00000000
[ 117.169228] [<80011fe0>] (show_stack) from [<80668cc0>] (dump_stack+0x88/0xa)
[ 117.176508] [<80668c38>] (dump_stack) from [<80029a38>] (warn_slowpath_commo)
[ 117.184696] r5:00000009 r4:00000000
[ 117.188322] [<800299c8>] (warn_slowpath_common) from [<80029a80>] (warn_slow)
[ 117.197150] r8:dd60d600 r7:ddfa6d00 r6:dd5d9064 r5:dd5e0f90 r4:dd5d9400
[ 117.203983] [<80029a5c>] (warn_slowpath_null) from [<802fcc48>] (regulator_u)
[ 117.212828] [<802fcb74>] (regulator_unregister) from [<7f0047c4>] (ldo_regul)
[ 117.223475] r4:dd59e300 r3:dd5e0f90
[ 117.227100] [<7f00479c>] (ldo_regulator_remove [snd_soc_sgtl5000]) from [<7f)
[ 117.238959] r4:dd5d8000 r3:ddd51420
[ 117.242623] [<7f0047dc>] (sgtl5000_remove [snd_soc_sgtl5000]) from [<804e5b1)
[ 117.252489] r5:00000000 r4:dd5d8000
[ 117.256111] [<804e5af8>] (soc_remove_codec) from [<804e5ed4>] (soc_remove_da)
[ 117.264933] r4:ddfb640c r3:00000000
[ 117.268555] [<804e5c10>] (soc_remove_dai_links) from [<804e5fbc>] (snd_soc_u)
[ 117.277810] r10:80359e48 r9:dd684000 r8:dd5ca800 r7:dd685e60 r6:00000001 r5c
[ 117.285761] r4:dd5d9064
[ 117.288329] [<804e5f28>] (snd_soc_unregister_card) from [<804f29f0>] (devm_c)
[ 117.297324] r6:00000004 r5:ddd0fc10 r4:dd5a7980 r3:804f29dc
[ 117.303095] [<804f29dc>] (devm_card_release) from [<8035a418>] (release_node)
[ 117.311369] [<8035a2a8>] (release_nodes) from [<8035aab4>] (devres_release_a)
[ 117.319583] r10:00000000 r9:dd684000 r8:8000ed64 r7:00000081 r6:ddd0fc44 r54
[ 117.327543] r4:ddd0fc10
[ 117.330108] [<8035aa7c>] (devres_release_all) from [<803571c8>] (__device_re)
[ 117.339214] r4:ddd0fc10 r3:dd5d9010
[ 117.342989] [<80357148>] (__device_release_driver) from [<80357a48>] (driver)
[ 117.351607] r5:7f00c9e4 r4:ddd0fc10
[ 117.355285] [<8035798c>] (driver_detach) from [<80357030>] (bus_remove_drive)
[ 117.363454] r6:00000880 r5:00000000 r4:7f00c9e4 r3:dd6c3a80
[ 117.369195] [<80356fdc>] (bus_remove_driver) from [<803580b8>] (driver_unreg)
[ 117.377683] r4:7f00c9e4 r3:dd60d480
[ 117.381305] [<80358088>] (driver_unregister) from [<80358bb4>] (platform_dri)
[ 117.390642] r4:7f00ca28 r3:7f00c35c
[ 117.394309] [<80358ba0>] (platform_driver_unregister) from [<7f00c370>] (imx)
[ 117.406188] [<7f00c35c>] (imx_sgtl5000_driver_exit [snd_soc_imx_sgtl5000]) f)
[ 117.417452] [<8008c2b8>] (SyS_delete_module) from [<8000eba0>] (ret_fast_sys)
[ 117.425753] r6:5f636f73 r5:5f646e73 r4:00016f40
[ 117.430428] ---[ end trace 8fd8a5cb39e46d0e ]---
This problem is well explained by Russell King:
"The sgtl5000 uses a two-stage initialisation process. The first stage
is when the platform driver is probed, where some resources are found
and initialised. The second stage is via the codec driver's probe
function, where regulators are found and initialised using the managed
resource support.
The problem here is that this works fine until the codec driver is
unbound. When this occurs, sgtl5000_remove() is called which is a no-op
as far as the managed resource code is concerned. The regulators remain
allocated, and their pointers in sgtl5000_priv remain valid.
If the codec is now re-probed, it will again try and find the regulators,
which will now be busy. This will fail.
That's not the only problem - if using the LDO regulator, the regulator
is unregistered from the regulator core code, but it still has a user.
When the user is cleaned up (eg, by removing the module) it hits the
free'd regulator, and this can oops the kernel.
This bug was originally introduced by 63e54cd9ca ("ASoC: sgtl5000:
Use devm_regulator_bulk_get()")."
This reverts commit 63e54cd9ca.
Tested on a imx53-qsb board.
Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Since commit e5d80e82e3 (ASoC: sgtl5000: Convert to use regmap directly) a
kernel oops is observed after a suspend/resume sequence.
The kernel oops happens inside sgtl5000_restore_regs() as codec->reg_cache is no
longer a valid pointer.
Add the remaining register entries into sgtl5000_reg_defaults[] and remove
sgtl5000_restore_regs() completely, which allows suspend/resume to work fine and
make the code simpler.
Tested on a im53-qsb board.
Reported-by: Shawn Guo <shawn.guo@freescale.com>
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Tested-by: Shawn Guo <shawn.guo@freescale.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Using devm_regulator_bulk_get() can make the code cleaner and smaller as we
do not need to call regulator_bulk_free() in the error and remove paths.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@linaro.org>