Quite a few build coverage fixes in here among the usual small driver
fixes includling the sigmadsp change from Lars - moving the driver to
separate modules per bus (which is basically just code motion) avoids
issues with some combinations of buses being enabled.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJTosIbAAoJELSic+t+oim9IpQP/1+cf6AuaKNIlOKpnqE4i3xF
BZSNHp+8YGdsKuq2h5W2cTwDfPCOZIJnQJ82M3w9LRyMJFLmvp4HSw3Syt6z1EOM
Ib+pYKrsbUlj9DDv8Hox4gzGtqokWVrXDhe9HF5h0QE2959UXhVdFSUflBzg3mH/
hOGcgFQH7YztySZlO1qlPjYOs6ukgMSAL2eFNIxpCvFMJk9pMxF19CZqS8b9qpPo
5EBQRLeycabvXA2ubwbVEjH68XJ73Ib49vQGYrpb1tgkEECL/m/uz9CdKCxb3Kva
1Oss7B7qtHD4Db+WbGSSE3wWD+KciybcIVy8OtLNllx8V4ipjld2lwnwybpIDlVN
3yRWHH/wYqDbFSinKfKONaoDHB9Xm6LgFCglFRpogkc7TMd7KuKsLvVwTcYVl+tL
g+0ThA507ftggiJWjGMEio/zn/N2pFx8W04LCCj3iEo5HS3JMMRKUHacIMYYqdGa
/nV7VyVJvFn7KIWJXxsWJpDK9+tUB9gAGCKCBiprKgAdfNp/dHrrlgQiJ3DS59W9
MGieBHU02G7xW/vOBLsq2iFinv9f0b3XDktbNmhNDLIkB7JWBT76BD4UTnLcEqOy
vHuBAUKrcfd5+Vr0w6ARHX8903Vr8xUurP31b+DniJDdu50/N2m6t0CaGPn3PQ6a
hllVAza23w8Jn1EsJV9h
=O7yF
-----END PGP SIGNATURE-----
Merge tag 'asoc-v3.16-rc1' into asoc-linus
ASoC: Fixes for v3.16
Quite a few build coverage fixes in here among the usual small driver
fixes includling the sigmadsp change from Lars - moving the driver to
separate modules per bus (which is basically just code motion) avoids
issues with some combinations of buses being enabled.
# gpg: Signature made Thu 19 Jun 2014 11:57:31 BST using RSA key ID 7EA229BD
# gpg: Good signature from "Mark Brown <broonie@sirena.org.uk>"
# gpg: aka "Mark Brown <broonie@debian.org>"
# gpg: aka "Mark Brown <broonie@kernel.org>"
# gpg: aka "Mark Brown <broonie@tardis.ed.ac.uk>"
# gpg: aka "Mark Brown <broonie@linaro.org>"
# gpg: aka "Mark Brown <Mark.Brown@linaro.org>"
Stereo Headphone and LineOut volume mixers are now attached to HPA+HPB, LOA+LOB.
Reported-by: Ryan Harvey <ryan.harvey@cirrus.com>
Signed-off-by: Ryan Harvey <ryan.harvey@cirrus.com>
Signed-off-by: Brian Austin <brian.austin@cirrus.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
In the rx irq handling part, we should clear the flags in RCSR not TCSR.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
SAI will not clear their FIFOs after disabling TE/RE. Therfore, the driver
should take care the task so as not to let useless data remain in the FIFO.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
The third parameter for snd_pcm_format_set_silence needs the number
of samples instead of sample bytes.
Signed-off-by: Scott Jiang <scott.jiang.linux@gmail.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Cc: stable@vger.kernel.org
Add dummy read after each block enable, to workaround
SRAM write missing bytes issue.
Signed-off-by: Jie Yang <yang.jie@intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
This change removes unsupported formats from System,
Capture and Loopback FE DAIs.
Also it fixes S24_LE support on all DAIs.
While at this fix 24 bit flag for BYT as well.
Signed-off-by: Jie Yang <yang.jie@intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Cc: stable@vger.kernel.org
Pull slave-dmaengine fixes from Vinod Koul:
"We have two small fixes. First one from Daniel to handle 0-length
packets for usb cppi dma. Second by Russell for imx-sdam cyclic
residue reporting"
* 'fixes' of git://git.infradead.org/users/vkoul/slave-dma:
Update imx-sdma cyclic handling to report residue
dma: cppi41: handle 0-length packets
The platform_driver remove callback return type is int not void.
Fixes the following warning:
sound/soc/s6000/s6000-i2s.c:604:19: warning: incorrect type in initializer (different base types)
sound/soc/s6000/s6000-i2s.c:604:19: expected int ( *remove )( ... )
sound/soc/s6000/s6000-i2s.c:604:19: got void ( static [toplevel] *<noident>)( ... )
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
Since MODULE_LICENSE is missing the module load fails,
so add this for module.
Signed-off-by: Praveen Diwakar <praveen.diwakar@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Cc: stable@vger.kernel.org
For HSW/BDW display HD-A controller, hda_set_bclk() is defined to set BCLK
by programming the M/N values as per the core display clock (CDCLK) queried from
i915 display driver.
And the audio driver will also set BCLK in azx_first_init() since the display
driver can turn off the shared power in boot phase if only eDP is connected
and M/N values will be lost and must be reprogrammed.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Fix a long standing bug in the read register routing of adau1701.
The bytes arrive in the buffer in big-endian, so the result has to be
shifted before and-ing the bytes in the loop.
Signed-off-by: Daniel Mack <zonque@gmail.com>
Acked-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
Cc: stable@vger.kernel.org
I received a report this morning from one of the Novena developers that
the behaviour of the iMX6 ASoC codec driver (using imx-pcm-dma.c) was
sub-optimal under high system load.
While there are issues relating to system load remaining, upon reviewing
the ASoC imx-pcm-dma.c driver, it was noticed that it not using the
residue support, because SDMA doesn't support it. This has the effect
that SDMA has to make multiple calls into the ASoC and ALSA code, one
for each period.
Since ALSA's snd_pcm_elapsed() does not need to be called multiple times
and it is entirely sufficient to call it once to update ALSA with the
current buffer position via the pointer method, we can do better here.
We can also avoid stopping the DMA entirely, just like real cyclic DMA
implementations behave. While this means that we replay some old samples,
this is a nicer behaviour than having audio stop and restart.
The changes to achieve this are relatively minor - imx-sdma.c can track
where the DMA is to the nearest descriptor boundary - it does this
already when deciding how many callbacks to issue. In doing this,
buf_tail always points at the descriptor which will complete next.
The residue is defined by the bytes remaining to the end of the buffer,
when the buffer is viewed as a single block of memory [start...end].
So, when we start out, there's a full buffer worth of residue, and this
counts down as we approach the end of the buffer, eventually becoming
zero at the end, before returning to the full buffer worth when we
wrap back to the start.
Moving the walking of the descriptors into the interrupt handler means
that we can update the BD_DONE flag at interrupt time, thus avoiding
a delayed tasklet stopping the cyclic DMA.
This means that the residue can be calculated from (total descriptors -
buf_tail) * descriptor size. This is what the change below does. We
update imx-pcm-dma.c to remove the NO_RESIDUE flag since we now provide
the residue.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
In case of S24_LE/U24_LE modes we expect 24bits on the bus while the samples
are stored and transferred in memory on 32bits (lower 3 bytes of the 4
bytes).
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Tested-by: Daniel Mack <daniel@zonque.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
Avoid creating duplicate directories by prefixing codecs and platforms
with their separate identifiers. This avoids snd-soc-dummy (which can
appear both as a dummy platform and a dummy codec on the same card)
from clashing.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Mark Brown <broonie@linaro.org>
The similar fixup as T440 is needed for supporting the dock on T540.
Reported-by: Jim Minter <jminter@redhat.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Another quirk to make the headset mic work on some new Dell machines.
Cc: Hui Wang <hui.wang@canonical.com>
BugLink: https://bugs.launchpad.net/bugs/1297581
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
For Intel Haswell/Broadwell display HD-A controller, the 24MHz HD-A link BCLK
is converted from Core Display Clock (CDCLK): BCLK = CDCLK * M / N
And there are two registers EM4 and EM5 to program M, N value respectively.
The EM4/EM5 values will be lost and when the display power well is disabled.
BIOS programs CDCLK selected by OEM and EM4/EM5, but BIOS has no idea about
display power well on/off at runtime. So the M/N can be wrong if non-default
CDCLK is used when the audio controller resumes, which results in an invalid
BCLK and abnormal audio playback rate. So this patch saves and restores valid
M/N values on controller suspend/resume.
And 'struct hda_intel' is defined to contain standard HD-A 'struct azx' and
Intel specific fields, as Takashi suggested.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
When a USB-audio device is disconnected while PCM is still running, we
still see some race: the disconnect callback calls
snd_usb_endpoint_free() that calls release_urbs() and then kfree()
while a PCM stream would be closed at the same time and calls
stop_endpoints() that leads to wait_clear_urbs(). That is, the EP
object might be deallocated while a PCM stream is syncing with
wait_clear_urbs() with the same EP.
Basically calling multiple wait_clear_urbs() would work fine, also
calling wait_clear_urbs() and release_urbs() would work, too, as
wait_clear_urbs() just reads some fields in ep. The problem is the
succeeding kfree() in snd_pcm_endpoint_free().
This patch moves out the EP deallocation into the later point, the
destructor callback. At this stage, all PCMs must have been already
closed, so it's safe to free the objects.
Reported-by: Alan Stern <stern@rowland.harvard.edu>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
HP Spectre 13 has the IDT 92HD95 codec, and BIOS seems to set the
default high-pass filter in some "safer" range, which results in the
very soft tone from the built-in speakers in contrast to Windows.
Also, the mute LED control is missing, since 92HD95 codec still has no
HP-specific fixups for GPIO setups.
This patch adds these missing features: the HPF is adjusted by the
vendor-specific verb, and the LED is set up from a DMI string (but
with the default polarity = 0 assumption due to the incomplete BIOS on
the given machine).
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=74841
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
It turned out there is no need to enable microphone detection in MAX98090
codec. Headset microphone is anyway detected by a GPIO signal from another
chip and headset button presses cannot be detected either because a signal
needed for it is not connected.
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Pass actual jack type bitmask to snd_soc_jack_new() in order to report
also microphone detections and not only headphone. While at it change also
jack name and pass also SND_JACK_LINEOUT type.
Reported-by: Jin Yao <yao.jin@intel.com>
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Headset jack has only mono microphone input.
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Mic detect GPIO is active low when headset microphone is detected. Found
both by debugging and checking the schematics.
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Move "MICBIAS" as a supply widget to "Headset Mic" instead of keeping it
between input pin "IN34" and "Headset Mic".
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
This is cosmetical - it makes the pin quirk table look better.
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This is cosmetical - it makes the new pin quirk table look better.
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Two bug reporters with Dell XPS 15 report that they need to use the
dell-headset-multi model to get the headset mic working.
The two bug reporters have different PCI SSID (1028:05fd and 1028:05fe)
but this pin quirk matches both.
BugLink: https://bugs.launchpad.net/bugs/1331915
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
We need to call the proper init function in case it has been
overridden, as it might restore things that the generic routing
doesn't know anything about. E.g. AMD cards have special verbs
that need resetting.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=77901
Fixes: 5a61358433 ('ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support')
Signed-off-by: Pierre Ossman <pierre@ossman.eu>
Cc: <stable@vger.kernel.org> [v3.13+]
Signed-off-by: Takashi Iwai <tiwai@suse.de>
A recent refactoring broke the possibility to manually specify
model name as a module parameter. This patch restores the desired
functionality.
Fixes: c21c8cf77f ('ALSA: hda - Add fixup_forced flag')
Reported-by: Kent Baxley <kent.baxley@canonical.com>
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
On the wm5110 CODEC both the left and right channel must be powered
when an output is being used as a mono output, although no audio is
routed to the right output channel. This patch adds additional DAPM
routes to link the right channel to the left in the case where an output
is marked as mono. Audio must always be brought in on the left channel
for mono operation.
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
we need to release dapm widget list after dpcm_path_get in
soc_dpcm_runtime_update. otherwise, there will be potential memory
leak. add dpcm_path_put to fix it.
Signed-off-by: Qiao Zhou <zhouqiao@marvell.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Cc: stable@vger.kernel.org
Fixes build with SND_DAVINCI_SOC or SND_OMAP_SOC alone and adds build
dependecy to SND_DAVINCI_SOC or SND_OMAP_SOC.
Signed-off-by: Jyri Sarha <jsarha@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
max98090.c doesn't free the threaded interrupt it requests. This causes
an oops when doing "cat /proc/interrupts" after snd-soc-max98090.ko is
unloaded.
Fix this by requesting the interrupt by using devm_request_threaded_irq().
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: Stable <stable@vger.kernel.org> # 3.10+
Signed-off-by: Mark Brown <broonie@linaro.org>
Quite a few build coverage fixes in here among the usual small driver
fixes includling the sigmadsp change from Lars - moving the driver to
separate modules per bus (which is basically just code motion) avoids
issues with some combinations of buses being enabled.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJToCEOAAoJELSic+t+oim9hS8P/jtMAdaR3JO5R1qtg8qj1tO8
ati7DEhkKHn+9rSv4rBtfjqFk0Tdy4r9ulQAS88D9k3WGWpZgUf8wdfMWdL94s5I
WRJbvtcss7VGarfOAEreaqd3/PJ0buVLeUm+JNap794WW74BqPlfw6+JveWCAL1V
UfRlkQ+PwbU4f7ieXKrtpinOpffFY6hB6N19l+nPqyy0aCn5S/rv4SXUkcJ77slG
jOjM1yxg2/RR25LDRqm6uyi2032KwhQZEyP3OccxcRWIROzltqNa+biPJwjdpUlo
aVHQ2vICFovOC1WsWSEwjntkLvgYOJGP/50ecC2SqgL6QmvR03isUqSKzkIxigog
2+fMEeXEn7gtjQNpZFDk2Ku9DDbDR22SaRlrjaMOa/YMCc8ylSY1IXuL51IkEfip
tSWGOGvg7veYhVQtnxu7wSxtnK/Gb53ugRxFYba1f44bxOKl5KByPfSY22e65e2X
hVFqVDbikEszcU7AJxMVKvGb1bPF+RGTmlfL20IXnxs/OtGVx0FURZGKLAMagVXr
3Um0W4HzAipmCBW5NmbQu+gAWoOa17c9rILOc4IaIW5zCvv+V8AURaiwT5sHtUhU
JAeNIPIVadO7Lps+bgGT/Auisa8loFiYXFGOJecgcXPiMnZ+2jp7Gb3EgG5Gl8YQ
boxQMUoCp3d+I2+uAqpm
=oF1h
-----END PGP SIGNATURE-----
Merge tag 'asoc-v3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v3.16
Quite a few build coverage fixes in here among the usual small driver
fixes includling the sigmadsp change from Lars - moving the driver to
separate modules per bus (which is basically just code motion) avoids
issues with some combinations of buses being enabled.
The ALSA control code expects that the range of assigned indices to a control is
continuous and does not overflow. Currently there are no checks to enforce this.
If a control with a overflowing index range is created that control becomes
effectively inaccessible and unremovable since snd_ctl_find_id() will not be
able to find it. This patch adds a check that makes sure that controls with a
overflowing index range can not be created.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Jaroslav Kysela <perex@perex.cz>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Each control gets automatically assigned its numids when the control is created.
The allocation is done by incrementing the numid by the amount of allocated
numids per allocation. This means that excessive creation and destruction of
controls (e.g. via SNDRV_CTL_IOCTL_ELEM_ADD/REMOVE) can cause the id to
eventually overflow. Currently when this happens for the control that caused the
overflow kctl->id.numid + kctl->count will also over flow causing it to be
smaller than kctl->id.numid. Most of the code assumes that this is something
that can not happen, so we need to make sure that it won't happen
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Jaroslav Kysela <perex@perex.cz>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
A control that is visible on the card->controls list can be freed at any time.
This means we must not access any of its memory while not holding the
controls_rw_lock. Otherwise we risk a use after free access.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Jaroslav Kysela <perex@perex.cz>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
There are two issues with the current implementation for replacing user
controls. The first is that the code does not check if the control is actually a
user control and neither does it check if the control is owned by the process
that tries to remove it. That allows userspace applications to remove arbitrary
controls, which can cause a user after free if a for example a driver does not
expect a control to be removed from under its feed.
The second issue is that on one hand when a control is replaced the
user_ctl_count limit is not checked and on the other hand the user_ctl_count is
increased (even though the number of user controls does not change). This allows
userspace, once the user_ctl_count limit as been reached, to repeatedly replace
a control until user_ctl_count overflows. Once that happens new controls can be
added effectively bypassing the user_ctl_count limit.
Both issues can be fixed by instead of open-coding the removal of the control
that is to be replaced to use snd_ctl_remove_user_ctl(). This function does
proper permission checks as well as decrements user_ctl_count after the control
has been removed.
Note that by using snd_ctl_remove_user_ctl() the check which returns -EBUSY at
beginning of the function if the control already exists is removed. This is not
a problem though since the check is quite useless, because the lock that is
protecting the control list is released between the check and before adding the
new control to the list, which means that it is possible that a different
control with the same settings is added to the list after the check. Luckily
there is another check that is done while holding the lock in snd_ctl_add(), so
we'll rely on that to make sure that the same control is not added twice.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Jaroslav Kysela <perex@perex.cz>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The user-control put and get handlers as well as the tlv do not protect against
concurrent access from multiple threads. Since the state of the control is not
updated atomically it is possible that either two write operations or a write
and a read operation race against each other. Both can lead to arbitrary memory
disclosure. This patch introduces a new lock that protects user-controls from
concurrent access. Since applications typically access controls sequentially
than in parallel a single lock per card should be fine.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Jaroslav Kysela <perex@perex.cz>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Current dma name search loop didn't care about SSI index
This patch fixes it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
ad32d0c7b0
(ASoC: rsnd: add rsnd_gen_dma_addr() for DMAC addr)
added rsnd_gen_dma_addr() to calculate DMA addr,
but, it is necessary only for Gen2.
This patch ignores Gen1 case.
Kernel will be panic without this patch.
Special thanks to Simon
Reported-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Mark Brown <broonie@linaro.org>
Building the pxa/mmp audio driver without support for the mmp
sram driver enabled results in this link error:
sound/built-in.o: In function `mmp_pcm_free_dma_buffers':
:(.text+0x3e734): undefined reference to `sram_get_gpool'
sound/built-in.o: In function `mmp_pcm_new':
:(.text+0x3e7c0): undefined reference to `sram_get_gpool'
The sram driver is cannot be manually enabled and needs to
be turned on by selecting MMP_SRAM from each module that
needs it, which is what this patch does.
Ideally, MMP should move over to the generic SRAM support, but
for the moment, we can avoid the build error.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Mark Brown <broonie@linaro.org>