diff options
author | Stijn Tintel <stijn@linux-ipv6.be> | 2018-11-10 13:03:18 +0200 |
---|---|---|
committer | Stijn Tintel <stijn@linux-ipv6.be> | 2018-12-18 23:19:21 +0200 |
commit | f5919b65d4c671fd5083838c7a445f319f9a13c8 (patch) | |
tree | 2c791d2a5dea5bbbb0b85f86f74afce2647c0726 /target/linux/brcm2708/patches-4.14/950-0116-ASoC-bcm2835-Support-left-right-justified-and-DSP-mo.patch | |
parent | 822b4c3b250a254e74407056ccfd5c6aa38da162 (diff) | |
download | upstream-f5919b65d4c671fd5083838c7a445f319f9a13c8.tar.gz upstream-f5919b65d4c671fd5083838c7a445f319f9a13c8.tar.bz2 upstream-f5919b65d4c671fd5083838c7a445f319f9a13c8.zip |
brcm2708: add kernel 4.14 support
Patch generation process:
- rebase rpi/rpi-4.14.y on v4.14.89 from linux-stable
- git format-patch v4.14.89
Patches skipped during rebase:
- lan78xx: Read MAC address from DT if present
- lan78xx: Enable LEDs and auto-negotiation
- Revert "softirq: Let ksoftirqd do its job"
- sc16is7xx: Fix for multi-channel stall
- lan78xx: Ignore DT MAC address if already valid
- lan78xx: Simple patch to prevent some crashes
- tcp_write_queue_purge clears all the SKBs in the write queue
- Revert "lan78xx: Simple patch to prevent some crashes"
- lan78xx: Connect phy early
- Arm: mm: ftrace: Only set text back to ro after kernel has been marked ro
- Revert "Revert "softirq: Let ksoftirqd do its job""
- ASoC: cs4265: SOC_SINGLE register value error fix
- Revert "ASoC: cs4265: SOC_SINGLE register value error fix"
- Revert "net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends"
- Revert "Revert "net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends""
Patches dropped after rebase:
- net: Add non-mainline source for rtl8192cu wlan
- net: Fix rtl8192cu build errors on other platforms
- brcm: adds support for BCM43341 wifi
- brcmfmac: Mute expected startup 'errors'
- ARM64: Fix build break for RTL8187/RTL8192CU wifi
- ARM64: Enable RTL8187/RTL8192CU wifi in build config
- This is the driver for Sony CXD2880 DVB-T2/T tuner + demodulator
- brcmfmac: add CLM download support
- brcmfmac: request_firmware_direct is quieter
- Sets the BCDC priority to constant 0
- brcmfmac: Disable ARP offloading when promiscuous
- brcmfmac: Avoid possible out-of-bounds read
- brcmfmac: Delete redundant length check
- net: rtl8192cu: Normalize indentation
- net: rtl8192cu: Fix implicit fallthrough warnings
- Revert "Sets the BCDC priority to constant 0"
- media: cxd2880: Bump to match 4.18.y version
- media: cxd2880-spi: Bump to match 4.18.y version
- Revert "mm: alloc_contig: re-allow CMA to compact FS pages"
- Revert "Revert "mm: alloc_contig: re-allow CMA to compact FS pages""
- cxd2880: CXD2880_SPI_DRV should select DVB_CXD2880 with
MEDIA_SUBDRV_AUTOSELECT
- 950-0421-HID-hid-bigbenff-driver-for-BigBen-Interactive-PS3OF.patch
- 950-0453-Add-hid-bigbenff-to-list-of-have_special_driver-for-.patch
Make I2C built-in instead of modular as in upstream defconfig; also the
easiest way to get MFD_ARIZONA enabled, which is required by
kmod-sound-soc-rpi-cirrus.
Add missing compatible strings from
4.9/960-add-rasbperrypi-compatible.patch, using upstream names for
compute modules.
Add extra patch to enable the LEDs on lan78xx.
Compile-tested: bcm2708, bcm2709, bcm2710 (with CONFIG_ALL_KMODS=y)
Runtime-tested: bcm2708, bcm2710
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
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.patch | 246 |
1 files changed, 246 insertions, 0 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 new file mode 100644 index 0000000000..af002128fa --- /dev/null +++ b/target/linux/brcm2708/patches-4.14/950-0116-ASoC-bcm2835-Support-left-right-justified-and-DSP-mo.patch @@ -0,0 +1,246 @@ +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; + } + |