Commit Graph

14 Commits

Author SHA1 Message Date
Matthias Reichl 8d5737a5f5
ASoC: bcm2835: fix hw_params error when device is in prepared state
If bcm2835 is configured as bitclock master calling hw_params()
after prepare() fails with EBUSY. This also makes it impossible to
use bcm2835 in full duplex mode.

The error is caused by the split clock setup: clk_set_rate
is called in hw_params, clk_prepare_enable in prepare. As hw_params
doesn't check if the clock was already enabled clk_set_rate
fails with EBUSY.

Fix this by moving clock startup from prepare to hw_params and
let hw_params properly deal with an already set up or enabled
clock.

Signed-off-by: Matthias Reichl <hias@horus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2018-01-18 11:21:17 +00:00
Matthias Reichl abd4f0e1c2
ASoC: bcm2835: Support left/right justified and DSP modes
DSP modes and left/right justified modes can be supported
on bcm2835 by configuring the frame sync polarity and
frame sync length registers and by adjusting the
channel data position registers.

Clock and frame sync polarity handling in hw_params has
been refactored to make the interaction between logical
rising/falling edge frame start and physical configuration
(changed by normal/inverted polarity modes) clearer.

Modes where the first active data bit is transmitted immediately
after frame start (eg DSP mode B with slot 0 active)
only work reliable if bcm2835 is configured as frame master.
In frame slave mode channel swap (or shift, this isn't quite
clear yet) can occur.

Currently the driver only warns if an unstable configuration
is detected but doensn't prevent using them.

Signed-off-by: Matthias Reichl <hias@horus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2017-11-10 21:26:07 +00:00
Matthias Reichl 3d2b3c707b
ASoC: bcm2835: Enforce full symmetry
bcm2835's configuration registers can't be changed when a stream
is running, which means asymmetric configurations aren't supported.

Channel and rate symmetry are already enforced by constraints
but samplebits had been missed.

As hw_params doesn't check for symmetry constraints by itself
and just returns success if a stream is running this led to
situations where asymmetric configurations were seeming to
succeed but of course didn't work because the hardware wasn't
configured at all.

Fix this by adding the missing samplerate symmetry constraint.

Signed-off-by: Matthias Reichl <hias@horus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2017-11-10 21:26:03 +00:00
Matthias Reichl 675c0ee514
ASoC: bcm2835: Support additional samplerates up to 384kHz
Sample rates are only restricted by the capabilities of the
clock driver, so use SNDRV_PCM_RATE_CONTINUOUS instead of
SNDRV_PCM_RATE_8000_192000.

Tests (eg with pcm5122) have shown that bcm2835 works fine
in 384kHz/32bit stereo mode, so change the maximum allowed
rate from 192kHz to 384kHz.

Signed-off-by: Matthias Reichl <hias@horus.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Mark Brown <broonie@kernel.org>
2017-11-10 21:24:34 +00:00
Matthias Reichl 9448572d98
ASoC: bcm2835: Add support for TDM modes
bcm2835 supports arbitrary positioning of channel data within
a frame and thus is capable of supporting TDM modes. Since
the driver is limited to 2-channel operations only TDM setups
with exactly 2 active slots are supported.

Logical TDM slot numbering follows the usual convention:

For I2S-like modes, with a 50% duty-cycle frame clock,
slots 0, 2, ... are transmitted in the first half of a frame,
slots 1, 3, ... are transmitted in the second half.

For DSP modes slot numbering is ascending: 0, 1, 2, 3, ...

Channel position calculation has been refactored to use
TDM info and moved out of hw_params.

set_tdm_slot, set_bclk_ratio and hw_params now check more
strictly if the configuration is valid. Illegal configurations
like odd number of slots in I2S mode, data lengths exceeding
slot width or frame sizes larger than the hardware limit of
1024 are rejected. Also hw_params now properly checks for
errors from clk_set_rate.

Allowed PCM formats are already guarded by stream constraints,
thus the formats check in hw_params has been removed and
data_length is now retrieved via params_width().

Also standard functions like snd_soc_params_to_bclk are now
being used instead of manual calculations to make the code
more readable.

Special care has been taken to ensure that set_bclk_ratio works
as before. The bclk ratio is mapped to a 2-channel TDM config
with a slot width of half the ratio. In order to support odd ratios,
which can't be expressed via a TDM config, the ratio (frame length)
is stored and used by hw_params.

Signed-off-by: Matthias Reichl <hias@horus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2017-11-10 21:24:30 +00:00
Matthias Reichl beff053c0e ASoC: bcm2835: Add S16_LE support via packed DMA transfers
The bcm2835-i2s driver already has support for the S16_LE format but
that format hasn't been made available because dmaengine_pcm didn't
support packed data transfers.

bcm2835-i2s needs 16-bit left+right channel data to be packed into
a 32-bit word, the FIFO register is 32-bit only and doesn't support
16-bit access.

Now that dmaengine_pcm supports packed transfers the format can
be made available by setting the SND_DMAENGINE_PCM_DAI_FLAG_PACK flag.

No further configuration is necessary:
- snd_dmaengine_dai_dma_data.addr_width is already set to
  DMA_SLAVE_BUSWIDTH_4_BYTES to force 32-bit DMA transfers
- dmaengine_pcm will pick up the S16_LE format from the DAI
  configuration and make it available since it's no longer
  masked out due to the PACK flag.
- there are no further corner cases to catch in hw_params,
  since the channel count is fixed at 2 we always have two
  16-bit stereo samples that can be transferred via 32-bit DMA

Signed-off-by: Matthias Reichl <hias@horus.com>
Tested-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
2016-04-27 17:35:53 +01:00
Matthias Reichl 60507fe191 ASoC: bcm2835: setup clock only if CPU is clock master
We only need to enable the clock if we are a clock master.

Code ported from bcm2708-i2s driver in Raspberry Pi tree.
Original work by Zoltan Szenczi.

Signed-off-by: Matthias Reichl <hias@horus.com>
Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
2016-04-25 17:39:11 +01:00
Matthias Reichl a34b027dca ASoC: bcm2835: add 24bit support
This adds 24 bit support to the I2S driver of the BCM2835

Code ported from bcm2708-i2s driver in Raspberry Pi tree.

Signed-off-by: Florian Meier <florian.meier@koalo.de>
Signed-off-by: Matthias Reichl <hias@horus.com>
Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
2016-04-25 17:39:05 +01:00
Martin Sperl 517e7a1537 ASoC: bcm2835: move to use the clock framework
Since the move to the new clock framework with commit 94cb7f76ca
("ARM: bcm2835: Switch to using the new clock driver support.")
this driver was no longer functional as it was manipulating the
clock registers locally without going true the framework.

This patch moves to use the new clock framework and also
moves away from the hardcoded address offsets for DMA getting
the dma-address directly from the device tree.

Note that the optimal bclk_ratio selection to avoid jitter
due to the use of fractional dividers, which is in the
current version has been removed, because not all devices
support these non power of 2 sized transfers, which resulted
in lots of (downstream) modules that use:
  snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
2016-01-15 18:09:10 +00:00
Martin Sperl 7905f08247 ASoC: bcm2835: cleanup includes by ordering them alphabetically
Cleanup of includes so that they are ordered alphabetically.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
2016-01-10 12:44:47 +00:00
Luis de Bethencourt 054bc835d2 ASoC: bcm2835-i2s: Fix module autoload for OF platform drivers
These platform drivers have a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Luis de Bethencourt <luis@debethencourt.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2015-08-27 20:22:47 +01:00
Wolfram Sang ea3bccab07 ASoC: bcm: drop owner assignment from platform_drivers
A platform_driver does not need to set an owner, it will be populated by the
driver core.

Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2014-10-20 16:22:04 +02:00
Lars-Peter Clausen 3990c516de ASoC: bcm2835-i2s: Use devm_snd_dmaengine_pcm_register()
Makes the code slightly shorter.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
2013-12-02 11:47:16 +00:00
Florian Meier c6aeb7de22 ASoC: Add support for BCM2835
This driver adds support for digital audio (I2S)
for the BCM2835 SoC that is used by the
Raspberry Pi. External audio codecs can be
connected to the Raspberry Pi via P5 header.

It relies on cyclic DMA engine support for BCM2835.

Signed-off-by: Florian Meier <florian.meier@koalo.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
2013-11-25 17:17:08 +00:00