aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.14/950-0116-ASoC-bcm2835-Support-left-right-justified-and-DSP-mo.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-4.14/950-0116-ASoC-bcm2835-Support-left-right-justified-and-DSP-mo.patch')
-rw-r--r--target/linux/brcm2708/patches-4.14/950-0116-ASoC-bcm2835-Support-left-right-justified-and-DSP-mo.patch246
1 files changed, 0 insertions, 246 deletions
diff --git a/target/linux/brcm2708/patches-4.14/950-0116-ASoC-bcm2835-Support-left-right-justified-and-DSP-mo.patch b/target/linux/brcm2708/patches-4.14/950-0116-ASoC-bcm2835-Support-left-right-justified-and-DSP-mo.patch
deleted file mode 100644
index af002128fa..0000000000
--- a/target/linux/brcm2708/patches-4.14/950-0116-ASoC-bcm2835-Support-left-right-justified-and-DSP-mo.patch
+++ /dev/null
@@ -1,246 +0,0 @@
-From d56239568d5f3b2a5519e9b08cba847c1354ad54 Mon Sep 17 00:00:00 2001
-From: Matthias Reichl <hias@horus.com>
-Date: Sun, 7 May 2017 15:30:50 +0200
-Subject: [PATCH 116/454] 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>
----
- sound/soc/bcm/bcm2835-i2s.c | 152 +++++++++++++++++++++++-------------
- 1 file changed, 99 insertions(+), 53 deletions(-)
-
---- a/sound/soc/bcm/bcm2835-i2s.c
-+++ b/sound/soc/bcm/bcm2835-i2s.c
-@@ -344,6 +344,9 @@ static int bcm2835_i2s_hw_params(struct
- unsigned int rx_mask, tx_mask;
- unsigned int rx_ch1_pos, rx_ch2_pos, tx_ch1_pos, tx_ch2_pos;
- unsigned int mode, format;
-+ bool bit_clock_master = false;
-+ bool frame_sync_master = false;
-+ bool frame_start_falling_edge = false;
- uint32_t csreg;
- int ret = 0;
-
-@@ -387,16 +390,39 @@ static int bcm2835_i2s_hw_params(struct
- if (data_length > slot_width)
- return -EINVAL;
-
-- /* Clock should only be set up here if CPU is clock master */
-+ /* Check if CPU is bit clock master */
- switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- case SND_SOC_DAIFMT_CBS_CFM:
-- ret = clk_set_rate(dev->clk, bclk_rate);
-- if (ret)
-- return ret;
-+ bit_clock_master = true;
-+ break;
-+ case SND_SOC_DAIFMT_CBM_CFS:
-+ case SND_SOC_DAIFMT_CBM_CFM:
-+ bit_clock_master = false;
- break;
- default:
-+ return -EINVAL;
-+ }
-+
-+ /* Check if CPU is frame sync master */
-+ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-+ case SND_SOC_DAIFMT_CBS_CFS:
-+ case SND_SOC_DAIFMT_CBM_CFS:
-+ frame_sync_master = true;
-+ break;
-+ case SND_SOC_DAIFMT_CBS_CFM:
-+ case SND_SOC_DAIFMT_CBM_CFM:
-+ frame_sync_master = false;
- break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ /* Clock should only be set up here if CPU is clock master */
-+ if (bit_clock_master) {
-+ ret = clk_set_rate(dev->clk, bclk_rate);
-+ if (ret)
-+ return ret;
- }
-
- /* Setup the frame format */
-@@ -427,13 +453,41 @@ static int bcm2835_i2s_hw_params(struct
-
- /* Setup frame sync signal for 50% duty cycle */
- framesync_length = frame_length / 2;
-+ frame_start_falling_edge = true;
-+ break;
-+ case SND_SOC_DAIFMT_LEFT_J:
-+ if (slots & 1)
-+ return -EINVAL;
-+
-+ odd_slot_offset = slots >> 1;
-+ data_delay = 0;
-+ framesync_length = frame_length / 2;
-+ frame_start_falling_edge = false;
-+ break;
-+ case SND_SOC_DAIFMT_RIGHT_J:
-+ if (slots & 1)
-+ return -EINVAL;
-+
-+ /* Odd frame lengths aren't supported */
-+ if (frame_length & 1)
-+ return -EINVAL;
-+
-+ odd_slot_offset = slots >> 1;
-+ data_delay = slot_width - data_length;
-+ framesync_length = frame_length / 2;
-+ frame_start_falling_edge = false;
-+ break;
-+ case SND_SOC_DAIFMT_DSP_A:
-+ data_delay = 1;
-+ framesync_length = 1;
-+ frame_start_falling_edge = false;
-+ break;
-+ case SND_SOC_DAIFMT_DSP_B:
-+ data_delay = 0;
-+ framesync_length = 1;
-+ frame_start_falling_edge = false;
- break;
- default:
-- /*
-- * TODO
-- * Others are possible but are not implemented at the moment.
-- */
-- dev_err(dev->dev, "%s:bad format\n", __func__);
- return -EINVAL;
- }
-
-@@ -443,6 +497,15 @@ static int bcm2835_i2s_hw_params(struct
- tx_mask, slot_width, data_delay, odd_slot_offset);
-
- /*
-+ * Transmitting data immediately after frame start, eg
-+ * in left-justified or DSP mode A, only works stable
-+ * if bcm2835 is the frame clock master.
-+ */
-+ if ((!rx_ch1_pos || !tx_ch1_pos) && !frame_sync_master)
-+ dev_warn(dev->dev,
-+ "Unstable slave config detected, L/R may be swapped");
-+
-+ /*
- * Set format for both streams.
- * We cannot set another frame length
- * (and therefore word length) anyway,
-@@ -472,62 +535,38 @@ static int bcm2835_i2s_hw_params(struct
- mode |= BCM2835_I2S_FLEN(frame_length - 1);
- mode |= BCM2835_I2S_FSLEN(framesync_length);
-
-- /* Master or slave? */
-- switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-- case SND_SOC_DAIFMT_CBS_CFS:
-- /* CPU is master */
-- break;
-- case SND_SOC_DAIFMT_CBM_CFS:
-- /*
-- * CODEC is bit clock master
-- * CPU is frame master
-- */
-+ /* CLKM selects bcm2835 clock slave mode */
-+ if (!bit_clock_master)
- mode |= BCM2835_I2S_CLKM;
-- break;
-- case SND_SOC_DAIFMT_CBS_CFM:
-- /*
-- * CODEC is frame master
-- * CPU is bit clock master
-- */
-+
-+ /* FSM selects bcm2835 frame sync slave mode */
-+ if (!frame_sync_master)
- mode |= BCM2835_I2S_FSM;
-+
-+ /* CLKI selects normal clocking mode, sampling on rising edge */
-+ switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) {
-+ case SND_SOC_DAIFMT_NB_NF:
-+ case SND_SOC_DAIFMT_NB_IF:
-+ mode |= BCM2835_I2S_CLKI;
- break;
-- case SND_SOC_DAIFMT_CBM_CFM:
-- /* CODEC is master */
-- mode |= BCM2835_I2S_CLKM;
-- mode |= BCM2835_I2S_FSM;
-+ case SND_SOC_DAIFMT_IB_NF:
-+ case SND_SOC_DAIFMT_IB_IF:
- break;
- default:
-- dev_err(dev->dev, "%s:bad master\n", __func__);
- return -EINVAL;
- }
-
-- /*
-- * Invert clocks?
-- *
-- * The BCM approach seems to be inverted to the classical I2S approach.
-- */
-+ /* FSI selects frame start on falling edge */
- switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
-- /* None. Therefore, both for BCM */
-- mode |= BCM2835_I2S_CLKI;
-- mode |= BCM2835_I2S_FSI;
-- break;
-- case SND_SOC_DAIFMT_IB_IF:
-- /* Both. Therefore, none for BCM */
-+ case SND_SOC_DAIFMT_IB_NF:
-+ if (frame_start_falling_edge)
-+ mode |= BCM2835_I2S_FSI;
- break;
- case SND_SOC_DAIFMT_NB_IF:
-- /*
-- * Invert only frame sync. Therefore,
-- * invert only bit clock for BCM
-- */
-- mode |= BCM2835_I2S_CLKI;
-- break;
-- case SND_SOC_DAIFMT_IB_NF:
-- /*
-- * Invert only bit clock. Therefore,
-- * invert only frame sync for BCM
-- */
-- mode |= BCM2835_I2S_FSI;
-+ case SND_SOC_DAIFMT_IB_IF:
-+ if (!frame_start_falling_edge)
-+ mode |= BCM2835_I2S_FSI;
- break;
- default:
- return -EINVAL;
-@@ -563,6 +602,13 @@ static int bcm2835_i2s_hw_params(struct
- dev_dbg(dev->dev, "sampling rate: %d bclk rate: %d\n",
- params_rate(params), bclk_rate);
-
-+ dev_dbg(dev->dev, "CLKM: %d CLKI: %d FSM: %d FSI: %d frame start: %s edge\n",
-+ !!(mode & BCM2835_I2S_CLKM),
-+ !!(mode & BCM2835_I2S_CLKI),
-+ !!(mode & BCM2835_I2S_FSM),
-+ !!(mode & BCM2835_I2S_FSI),
-+ (mode & BCM2835_I2S_FSI) ? "falling" : "rising");
-+
- return ret;
- }
-