Merge series "Rockchip I2S/TDM controller" from Nicolas Frattaroli <frattaroli.nicolas@gmail.com>:
Hello, this is version 5 of the I2S/TDM driver patchset. A big thanks to everyone who has provided their valuable feedback so far. Changes in v5: driver: - change comment style of the first comment to C++ style - make refcount non-atomic, as it's only ever used inside a spinlock - use newer SND_SOC_DAIFMT_CB* defines - change ternary statements to if/else conditions - make _clk_compensation_put return 1 if clock changed - implement set_bclk_ratio callback - always set half frame sync mode in TDM mode - automatically enable mclk-calibrate mode when the clocks for it are specified in the device tree bindings: - add Reviewed-by: Rob Herring - drop rockchip,frame-width property (done by set_bclk_ratio) - drop rockchip,fsync-half-frame property - drop rockchip,mclk-calibrate property dts: - drop empty codec block from Quartz64 device tree Changes in v4: driver: - factor TDE/RDE enable/disable into their own inlined functions - add an RDE disable in a location where it looks like it was forgotten (rxctrl else), judging by corresponding TDE code - remove parentheses around CLK_PPM_MIN/MAX values - wording + titlecasing in the clock compensation control - use if statement in precious_reg instead - refactor rockchip_i2s_io_multiplex to have the switch statements in a function call to make the function less unwieldy - get rid of IS_ERR checks around clk enable/disable calls where already checked before by the probe - reworded some error message strings - fix potential deadlock in txrxctrl found by Sugar Zhang using spin_lock_irqsave - fix potential deadlock in trcm_mode found by Sugar Zhang using spin_lock_irqsave - use devm_platform_get_and_ioremap_resource in probe - only set DMA things if controller has capture/playback ability. Did not move this into init_dai because I'd then need to pass in the res and probe it earlier in the function, and it's also used elsewhere in the probe function - use _get_optional_exclusive for reset controls, as some controllers only have capture or playback capability bindings: - remove status = "okay" since that's the default - change the path configs to be an enum - rename "foo" to "bus" - make resets optional as controller may lack either playback or capture capability, and therefore also doesn't have a reset. At least one reset is still required, because a controller with no playback and no capture is not very useful Changes in v3: driver: - alphabetically sort includes - check pm_runtime_get_sync return value, act on it - remove unnecessary initialisers in set_fmt - use udelay(15) in retry code: 10 retries * 15 = 150, so at worst we wait the full i2s register access delay - fix some weird returns to return directly - use __maybe_unused instead of #ifdef CONFIG_PM_SLEEP, also put __maybe_unused on the runtime callbacks - use (foo) instead of foo in header macros for precedence reasons - when using mclk-calibrate, also turn off/on those clocks during suspend and resume operations - remove mclk_tx and mclk_rx reenablement code in remove - move hclk enablement further down the probe, and disable it on probe failure - make reset controls mandatory, since the bindings state this too - use _exclusive for getting the reset controls - change reset assert/deassert delays to both be 10 usec (thank you Sugar Zhang!) - properly prepare and enable all mclks in probe, especially before calling clk_get_rate on them - if registering PCM fails, also use the cleanup error path instead of returning directly - bring back playback and capture only but in the way Sugar Zhang suggested it: set those modes depending on dma-names - rework clock enablement in general. Probe now always enables these, instead of relying on the pm resume thing - add myself to MAINTAINERS for this driver dt bindings: - fix a description still mentioning clk-trcm in the schema - document rockchip,io-multiplex, a property that describes the hardware as having multiplexed I2S GPIOs so direction needs to be changed dynamically - document rockchip,mclk-calibrate, which allows specifying different clocks for the two sample rate bases and switch between them as needed - dma-names now doesn't have a set order and items can be absent to indicate that the controller doesn't support this mode - add myself to MAINTAINERS for these bindings Changes in v2: - remove ad-hoc writeq and needless (and broken) optimisation in reset assert/deassert. This wouldn't have worked on Big Endian, and would've been pointless on any other platform, as the overhead for saving one write was comparatively big - fix various checkpatch issues - get rid of leftover clk-trcm in schema - set status = "okay" in example in schema instead of "disabled" - change dma-names so rx is first, adjust device trees as necessary - properly reference uint32-array for rx-route and tx-route instead of uint32 - replace trcm-sync with two boolean properties, adjust DT changes accordingly and also get rid of the header file - get rid of rockchip,no-dmaengine. This was only needed for some downstream driver and shouldn't be in the DT - get rid of rockchip,capture-only/playback-only. Rationale being that I have no way to test whether they're needed, and unconditionally setting channels_min to 0 breaks everything - change hclk description in "clocks" Nicolas Frattaroli (4): ASoC: rockchip: add support for i2s-tdm controller ASoC: dt-bindings: rockchip: add i2s-tdm bindings arm64: dts: rockchip: add i2s1 on rk356x arm64: dts: rockchip: add analog audio on Quartz64 .../bindings/sound/rockchip,i2s-tdm.yaml | 198 ++ MAINTAINERS | 7 + .../boot/dts/rockchip/rk3566-quartz64-a.dts | 31 +- arch/arm64/boot/dts/rockchip/rk356x.dtsi | 26 + sound/soc/rockchip/Kconfig | 11 + sound/soc/rockchip/Makefile | 2 + sound/soc/rockchip/rockchip_i2s_tdm.c | 1848 +++++++++++++++++ sound/soc/rockchip/rockchip_i2s_tdm.h | 398 ++++ 8 files changed, 2520 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.c create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.h -- 2.33.0
This commit is contained in:
commit
43b058698f
198
Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
Normal file
198
Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
Normal file
@ -0,0 +1,198 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/rockchip,i2s-tdm.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Rockchip I2S/TDM Controller
|
||||
|
||||
description:
|
||||
The Rockchip I2S/TDM Controller is a Time Division Multiplexed
|
||||
audio interface found in various Rockchip SoCs, allowing up
|
||||
to 8 channels of audio over a serial interface.
|
||||
|
||||
maintainers:
|
||||
- Nicolas Frattaroli <frattaroli.nicolas@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- rockchip,px30-i2s-tdm
|
||||
- rockchip,rk1808-i2s-tdm
|
||||
- rockchip,rk3308-i2s-tdm
|
||||
- rockchip,rk3568-i2s-tdm
|
||||
- rockchip,rv1126-i2s-tdm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
dmas:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
dma-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
enum:
|
||||
- rx
|
||||
- tx
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
items:
|
||||
- description: clock for TX
|
||||
- description: clock for RX
|
||||
- description: AHB clock driving the interface
|
||||
- description:
|
||||
Parent clock for mclk_tx (only required when using mclk-calibrate)
|
||||
- description:
|
||||
Parent clock for mclk_rx (only required when using mclk-calibrate)
|
||||
- description:
|
||||
Clock for sample rates that are an integer multiple of 8000
|
||||
(only required when using mclk-calibrate)
|
||||
- description:
|
||||
Clock for sample rates that are an integer multiple of 11025
|
||||
(only required when using mclk-calibrate)
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
items:
|
||||
- const: mclk_tx
|
||||
- const: mclk_rx
|
||||
- const: hclk
|
||||
- const: mclk_tx_src
|
||||
- const: mclk_rx_src
|
||||
- const: mclk_root0
|
||||
- const: mclk_root1
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
description: resets for the tx and rx directions
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
enum:
|
||||
- tx-m
|
||||
- rx-m
|
||||
|
||||
rockchip,cru:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
The phandle of the cru.
|
||||
Required if neither trcm-sync-tx-only nor trcm-sync-rx-only are specified.
|
||||
|
||||
rockchip,grf:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
The phandle of the syscon node for the GRF register.
|
||||
|
||||
rockchip,trcm-sync-tx-only:
|
||||
type: boolean
|
||||
description: Use TX BCLK/LRCK for both TX and RX.
|
||||
|
||||
rockchip,trcm-sync-rx-only:
|
||||
type: boolean
|
||||
description: Use RX BCLK/LRCK for both TX and RX.
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
rockchip,i2s-rx-route:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
Defines the mapping of I2S RX sdis to I2S data bus lines.
|
||||
By default, they are mapped one-to-one.
|
||||
rockchip,i2s-rx-route = <3> would mean sdi3 is receiving from data0.
|
||||
maxItems: 4
|
||||
items:
|
||||
- enum: [0, 1, 2, 3]
|
||||
|
||||
rockchip,i2s-tx-route:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
Defines the mapping of I2S TX sdos to I2S data bus lines.
|
||||
By default, they are mapped one-to-one.
|
||||
rockchip,i2s-tx-route = <3> would mean sdo3 is sending to data0.
|
||||
maxItems: 4
|
||||
items:
|
||||
- enum: [0, 1, 2, 3]
|
||||
|
||||
rockchip,io-multiplex:
|
||||
description:
|
||||
Specify that the GPIO lines on the I2S bus are multiplexed such that
|
||||
the direction (input/output) needs to be dynamically adjusted.
|
||||
type: boolean
|
||||
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- dmas
|
||||
- dma-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- rockchip,grf
|
||||
- "#sound-dai-cells"
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
rockchip,trcm-sync-tx-only: false
|
||||
rockchip,trcm-sync-rx-only: false
|
||||
then:
|
||||
required:
|
||||
- rockchip,cru
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/rk3568-cru.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
|
||||
bus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
i2s@fe410000 {
|
||||
compatible = "rockchip,rk3568-i2s-tdm";
|
||||
reg = <0x0 0xfe410000 0x0 0x1000>;
|
||||
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
|
||||
<&cru HCLK_I2S1_8CH>;
|
||||
clock-names = "mclk_tx", "mclk_rx", "hclk";
|
||||
dmas = <&dmac1 3>, <&dmac1 2>;
|
||||
dma-names = "rx", "tx";
|
||||
resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
|
||||
reset-names = "tx-m", "rx-m";
|
||||
rockchip,trcm-sync-tx-only;
|
||||
rockchip,cru = <&cru>;
|
||||
rockchip,grf = <&grf>;
|
||||
#sound-dai-cells = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 =
|
||||
<&i2s1m0_sclktx
|
||||
&i2s1m0_sclkrx
|
||||
&i2s1m0_lrcktx
|
||||
&i2s1m0_lrckrx
|
||||
&i2s1m0_sdi0
|
||||
&i2s1m0_sdi1
|
||||
&i2s1m0_sdi2
|
||||
&i2s1m0_sdi3
|
||||
&i2s1m0_sdo0
|
||||
&i2s1m0_sdo1
|
||||
&i2s1m0_sdo2
|
||||
&i2s1m0_sdo3>;
|
||||
};
|
||||
};
|
@ -16108,6 +16108,13 @@ F: Documentation/ABI/*/sysfs-driver-hid-roccat*
|
||||
F: drivers/hid/hid-roccat*
|
||||
F: include/linux/hid-roccat*
|
||||
|
||||
ROCKCHIP I2S TDM DRIVER
|
||||
M: Nicolas Frattaroli <frattaroli.nicolas@gmail.com>
|
||||
L: linux-rockchip@lists.infradead.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
|
||||
F: sound/soc/rockchip/rockchip_i2s_tdm.*
|
||||
|
||||
ROCKCHIP ISP V1 DRIVER
|
||||
M: Helen Koike <helen.koike@collabora.com>
|
||||
M: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
||||
|
@ -16,6 +16,17 @@ config SND_SOC_ROCKCHIP_I2S
|
||||
Rockchip I2S device. The device supports upto maximum of
|
||||
8 channels each for play and record.
|
||||
|
||||
config SND_SOC_ROCKCHIP_I2S_TDM
|
||||
tristate "Rockchip I2S/TDM Device Driver"
|
||||
depends on HAVE_CLK && SND_SOC_ROCKCHIP
|
||||
select SND_SOC_GENERIC_DMAENGINE_PCM
|
||||
help
|
||||
Say Y or M if you want to add support for the I2S/TDM driver for
|
||||
Rockchip I2S/TDM devices, found in Rockchip SoCs. These devices
|
||||
interface between the AHB bus and the I2S bus, and support up to a
|
||||
maximum of 8 channels each for playback and recording.
|
||||
|
||||
|
||||
config SND_SOC_ROCKCHIP_PDM
|
||||
tristate "Rockchip PDM Controller Driver"
|
||||
depends on HAVE_CLK && SND_SOC_ROCKCHIP
|
||||
|
@ -1,11 +1,13 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# ROCKCHIP Platform Support
|
||||
snd-soc-rockchip-i2s-objs := rockchip_i2s.o
|
||||
snd-soc-rockchip-i2s-tdm-objs := rockchip_i2s_tdm.o
|
||||
snd-soc-rockchip-pcm-objs := rockchip_pcm.o
|
||||
snd-soc-rockchip-pdm-objs := rockchip_pdm.o
|
||||
snd-soc-rockchip-spdif-objs := rockchip_spdif.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-rockchip-i2s.o snd-soc-rockchip-pcm.o
|
||||
obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S_TDM) += snd-soc-rockchip-i2s-tdm.o
|
||||
obj-$(CONFIG_SND_SOC_ROCKCHIP_PDM) += snd-soc-rockchip-pdm.o
|
||||
obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o
|
||||
|
||||
|
1848
sound/soc/rockchip/rockchip_i2s_tdm.c
Normal file
1848
sound/soc/rockchip/rockchip_i2s_tdm.c
Normal file
File diff suppressed because it is too large
Load Diff
398
sound/soc/rockchip/rockchip_i2s_tdm.h
Normal file
398
sound/soc/rockchip/rockchip_i2s_tdm.h
Normal file
@ -0,0 +1,398 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* ALSA SoC Audio Layer - Rockchip I2S/TDM Controller driver
|
||||
*
|
||||
* Copyright (c) 2018 Rockchip Electronics Co. Ltd.
|
||||
* Author: Sugar Zhang <sugar.zhang@rock-chips.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ROCKCHIP_I2S_TDM_H
|
||||
#define _ROCKCHIP_I2S_TDM_H
|
||||
|
||||
/*
|
||||
* TXCR
|
||||
* transmit operation control register
|
||||
*/
|
||||
#define I2S_TXCR_PATH_SHIFT(x) (23 + (x) * 2)
|
||||
#define I2S_TXCR_PATH_MASK(x) (0x3 << I2S_TXCR_PATH_SHIFT(x))
|
||||
#define I2S_TXCR_PATH(x, v) ((v) << I2S_TXCR_PATH_SHIFT(x))
|
||||
#define I2S_TXCR_RCNT_SHIFT 17
|
||||
#define I2S_TXCR_RCNT_MASK (0x3f << I2S_TXCR_RCNT_SHIFT)
|
||||
#define I2S_TXCR_CSR_SHIFT 15
|
||||
#define I2S_TXCR_CSR(x) ((x) << I2S_TXCR_CSR_SHIFT)
|
||||
#define I2S_TXCR_CSR_MASK (3 << I2S_TXCR_CSR_SHIFT)
|
||||
#define I2S_TXCR_HWT BIT(14)
|
||||
#define I2S_TXCR_SJM_SHIFT 12
|
||||
#define I2S_TXCR_SJM_R (0 << I2S_TXCR_SJM_SHIFT)
|
||||
#define I2S_TXCR_SJM_L (1 << I2S_TXCR_SJM_SHIFT)
|
||||
#define I2S_TXCR_FBM_SHIFT 11
|
||||
#define I2S_TXCR_FBM_MSB (0 << I2S_TXCR_FBM_SHIFT)
|
||||
#define I2S_TXCR_FBM_LSB (1 << I2S_TXCR_FBM_SHIFT)
|
||||
#define I2S_TXCR_IBM_SHIFT 9
|
||||
#define I2S_TXCR_IBM_NORMAL (0 << I2S_TXCR_IBM_SHIFT)
|
||||
#define I2S_TXCR_IBM_LSJM (1 << I2S_TXCR_IBM_SHIFT)
|
||||
#define I2S_TXCR_IBM_RSJM (2 << I2S_TXCR_IBM_SHIFT)
|
||||
#define I2S_TXCR_IBM_MASK (3 << I2S_TXCR_IBM_SHIFT)
|
||||
#define I2S_TXCR_PBM_SHIFT 7
|
||||
#define I2S_TXCR_PBM_MODE(x) ((x) << I2S_TXCR_PBM_SHIFT)
|
||||
#define I2S_TXCR_PBM_MASK (3 << I2S_TXCR_PBM_SHIFT)
|
||||
#define I2S_TXCR_TFS_SHIFT 5
|
||||
#define I2S_TXCR_TFS_I2S (0 << I2S_TXCR_TFS_SHIFT)
|
||||
#define I2S_TXCR_TFS_PCM (1 << I2S_TXCR_TFS_SHIFT)
|
||||
#define I2S_TXCR_TFS_TDM_PCM (2 << I2S_TXCR_TFS_SHIFT)
|
||||
#define I2S_TXCR_TFS_TDM_I2S (3 << I2S_TXCR_TFS_SHIFT)
|
||||
#define I2S_TXCR_TFS_MASK (3 << I2S_TXCR_TFS_SHIFT)
|
||||
#define I2S_TXCR_VDW_SHIFT 0
|
||||
#define I2S_TXCR_VDW(x) (((x) - 1) << I2S_TXCR_VDW_SHIFT)
|
||||
#define I2S_TXCR_VDW_MASK (0x1f << I2S_TXCR_VDW_SHIFT)
|
||||
|
||||
/*
|
||||
* RXCR
|
||||
* receive operation control register
|
||||
*/
|
||||
#define I2S_RXCR_PATH_SHIFT(x) (17 + (x) * 2)
|
||||
#define I2S_RXCR_PATH_MASK(x) (0x3 << I2S_RXCR_PATH_SHIFT(x))
|
||||
#define I2S_RXCR_PATH(x, v) ((v) << I2S_RXCR_PATH_SHIFT(x))
|
||||
#define I2S_RXCR_CSR_SHIFT 15
|
||||
#define I2S_RXCR_CSR(x) ((x) << I2S_RXCR_CSR_SHIFT)
|
||||
#define I2S_RXCR_CSR_MASK (3 << I2S_RXCR_CSR_SHIFT)
|
||||
#define I2S_RXCR_HWT BIT(14)
|
||||
#define I2S_RXCR_SJM_SHIFT 12
|
||||
#define I2S_RXCR_SJM_R (0 << I2S_RXCR_SJM_SHIFT)
|
||||
#define I2S_RXCR_SJM_L (1 << I2S_RXCR_SJM_SHIFT)
|
||||
#define I2S_RXCR_FBM_SHIFT 11
|
||||
#define I2S_RXCR_FBM_MSB (0 << I2S_RXCR_FBM_SHIFT)
|
||||
#define I2S_RXCR_FBM_LSB (1 << I2S_RXCR_FBM_SHIFT)
|
||||
#define I2S_RXCR_IBM_SHIFT 9
|
||||
#define I2S_RXCR_IBM_NORMAL (0 << I2S_RXCR_IBM_SHIFT)
|
||||
#define I2S_RXCR_IBM_LSJM (1 << I2S_RXCR_IBM_SHIFT)
|
||||
#define I2S_RXCR_IBM_RSJM (2 << I2S_RXCR_IBM_SHIFT)
|
||||
#define I2S_RXCR_IBM_MASK (3 << I2S_RXCR_IBM_SHIFT)
|
||||
#define I2S_RXCR_PBM_SHIFT 7
|
||||
#define I2S_RXCR_PBM_MODE(x) ((x) << I2S_RXCR_PBM_SHIFT)
|
||||
#define I2S_RXCR_PBM_MASK (3 << I2S_RXCR_PBM_SHIFT)
|
||||
#define I2S_RXCR_TFS_SHIFT 5
|
||||
#define I2S_RXCR_TFS_I2S (0 << I2S_RXCR_TFS_SHIFT)
|
||||
#define I2S_RXCR_TFS_PCM (1 << I2S_RXCR_TFS_SHIFT)
|
||||
#define I2S_RXCR_TFS_TDM_PCM (2 << I2S_RXCR_TFS_SHIFT)
|
||||
#define I2S_RXCR_TFS_TDM_I2S (3 << I2S_RXCR_TFS_SHIFT)
|
||||
#define I2S_RXCR_TFS_MASK (3 << I2S_RXCR_TFS_SHIFT)
|
||||
#define I2S_RXCR_VDW_SHIFT 0
|
||||
#define I2S_RXCR_VDW(x) (((x) - 1) << I2S_RXCR_VDW_SHIFT)
|
||||
#define I2S_RXCR_VDW_MASK (0x1f << I2S_RXCR_VDW_SHIFT)
|
||||
|
||||
/*
|
||||
* CKR
|
||||
* clock generation register
|
||||
*/
|
||||
#define I2S_CKR_TRCM_SHIFT 28
|
||||
#define I2S_CKR_TRCM(x) ((x) << I2S_CKR_TRCM_SHIFT)
|
||||
#define I2S_CKR_TRCM_TXRX (0 << I2S_CKR_TRCM_SHIFT)
|
||||
#define I2S_CKR_TRCM_TXONLY (1 << I2S_CKR_TRCM_SHIFT)
|
||||
#define I2S_CKR_TRCM_RXONLY (2 << I2S_CKR_TRCM_SHIFT)
|
||||
#define I2S_CKR_TRCM_MASK (3 << I2S_CKR_TRCM_SHIFT)
|
||||
#define I2S_CKR_MSS_SHIFT 27
|
||||
#define I2S_CKR_MSS_MASTER (0 << I2S_CKR_MSS_SHIFT)
|
||||
#define I2S_CKR_MSS_SLAVE (1 << I2S_CKR_MSS_SHIFT)
|
||||
#define I2S_CKR_MSS_MASK (1 << I2S_CKR_MSS_SHIFT)
|
||||
#define I2S_CKR_CKP_SHIFT 26
|
||||
#define I2S_CKR_CKP_NORMAL (0 << I2S_CKR_CKP_SHIFT)
|
||||
#define I2S_CKR_CKP_INVERTED (1 << I2S_CKR_CKP_SHIFT)
|
||||
#define I2S_CKR_CKP_MASK (1 << I2S_CKR_CKP_SHIFT)
|
||||
#define I2S_CKR_RLP_SHIFT 25
|
||||
#define I2S_CKR_RLP_NORMAL (0 << I2S_CKR_RLP_SHIFT)
|
||||
#define I2S_CKR_RLP_INVERTED (1 << I2S_CKR_RLP_SHIFT)
|
||||
#define I2S_CKR_RLP_MASK (1 << I2S_CKR_RLP_SHIFT)
|
||||
#define I2S_CKR_TLP_SHIFT 24
|
||||
#define I2S_CKR_TLP_NORMAL (0 << I2S_CKR_TLP_SHIFT)
|
||||
#define I2S_CKR_TLP_INVERTED (1 << I2S_CKR_TLP_SHIFT)
|
||||
#define I2S_CKR_TLP_MASK (1 << I2S_CKR_TLP_SHIFT)
|
||||
#define I2S_CKR_MDIV_SHIFT 16
|
||||
#define I2S_CKR_MDIV(x) (((x) - 1) << I2S_CKR_MDIV_SHIFT)
|
||||
#define I2S_CKR_MDIV_MASK (0xff << I2S_CKR_MDIV_SHIFT)
|
||||
#define I2S_CKR_RSD_SHIFT 8
|
||||
#define I2S_CKR_RSD(x) (((x) - 1) << I2S_CKR_RSD_SHIFT)
|
||||
#define I2S_CKR_RSD_MASK (0xff << I2S_CKR_RSD_SHIFT)
|
||||
#define I2S_CKR_TSD_SHIFT 0
|
||||
#define I2S_CKR_TSD(x) (((x) - 1) << I2S_CKR_TSD_SHIFT)
|
||||
#define I2S_CKR_TSD_MASK (0xff << I2S_CKR_TSD_SHIFT)
|
||||
|
||||
/*
|
||||
* FIFOLR
|
||||
* FIFO level register
|
||||
*/
|
||||
#define I2S_FIFOLR_RFL_SHIFT 24
|
||||
#define I2S_FIFOLR_RFL_MASK (0x3f << I2S_FIFOLR_RFL_SHIFT)
|
||||
#define I2S_FIFOLR_TFL3_SHIFT 18
|
||||
#define I2S_FIFOLR_TFL3_MASK (0x3f << I2S_FIFOLR_TFL3_SHIFT)
|
||||
#define I2S_FIFOLR_TFL2_SHIFT 12
|
||||
#define I2S_FIFOLR_TFL2_MASK (0x3f << I2S_FIFOLR_TFL2_SHIFT)
|
||||
#define I2S_FIFOLR_TFL1_SHIFT 6
|
||||
#define I2S_FIFOLR_TFL1_MASK (0x3f << I2S_FIFOLR_TFL1_SHIFT)
|
||||
#define I2S_FIFOLR_TFL0_SHIFT 0
|
||||
#define I2S_FIFOLR_TFL0_MASK (0x3f << I2S_FIFOLR_TFL0_SHIFT)
|
||||
|
||||
/*
|
||||
* DMACR
|
||||
* DMA control register
|
||||
*/
|
||||
#define I2S_DMACR_RDE_SHIFT 24
|
||||
#define I2S_DMACR_RDE_DISABLE (0 << I2S_DMACR_RDE_SHIFT)
|
||||
#define I2S_DMACR_RDE_ENABLE (1 << I2S_DMACR_RDE_SHIFT)
|
||||
#define I2S_DMACR_RDL_SHIFT 16
|
||||
#define I2S_DMACR_RDL(x) (((x) - 1) << I2S_DMACR_RDL_SHIFT)
|
||||
#define I2S_DMACR_RDL_MASK (0x1f << I2S_DMACR_RDL_SHIFT)
|
||||
#define I2S_DMACR_TDE_SHIFT 8
|
||||
#define I2S_DMACR_TDE_DISABLE (0 << I2S_DMACR_TDE_SHIFT)
|
||||
#define I2S_DMACR_TDE_ENABLE (1 << I2S_DMACR_TDE_SHIFT)
|
||||
#define I2S_DMACR_TDL_SHIFT 0
|
||||
#define I2S_DMACR_TDL(x) ((x) << I2S_DMACR_TDL_SHIFT)
|
||||
#define I2S_DMACR_TDL_MASK (0x1f << I2S_DMACR_TDL_SHIFT)
|
||||
|
||||
/*
|
||||
* INTCR
|
||||
* interrupt control register
|
||||
*/
|
||||
#define I2S_INTCR_RFT_SHIFT 20
|
||||
#define I2S_INTCR_RFT(x) (((x) - 1) << I2S_INTCR_RFT_SHIFT)
|
||||
#define I2S_INTCR_RXOIC BIT(18)
|
||||
#define I2S_INTCR_RXOIE_SHIFT 17
|
||||
#define I2S_INTCR_RXOIE_DISABLE (0 << I2S_INTCR_RXOIE_SHIFT)
|
||||
#define I2S_INTCR_RXOIE_ENABLE (1 << I2S_INTCR_RXOIE_SHIFT)
|
||||
#define I2S_INTCR_RXFIE_SHIFT 16
|
||||
#define I2S_INTCR_RXFIE_DISABLE (0 << I2S_INTCR_RXFIE_SHIFT)
|
||||
#define I2S_INTCR_RXFIE_ENABLE (1 << I2S_INTCR_RXFIE_SHIFT)
|
||||
#define I2S_INTCR_TFT_SHIFT 4
|
||||
#define I2S_INTCR_TFT(x) (((x) - 1) << I2S_INTCR_TFT_SHIFT)
|
||||
#define I2S_INTCR_TFT_MASK (0x1f << I2S_INTCR_TFT_SHIFT)
|
||||
#define I2S_INTCR_TXUIC BIT(2)
|
||||
#define I2S_INTCR_TXUIE_SHIFT 1
|
||||
#define I2S_INTCR_TXUIE_DISABLE (0 << I2S_INTCR_TXUIE_SHIFT)
|
||||
#define I2S_INTCR_TXUIE_ENABLE (1 << I2S_INTCR_TXUIE_SHIFT)
|
||||
|
||||
/*
|
||||
* INTSR
|
||||
* interrupt status register
|
||||
*/
|
||||
#define I2S_INTSR_TXEIE_SHIFT 0
|
||||
#define I2S_INTSR_TXEIE_DISABLE (0 << I2S_INTSR_TXEIE_SHIFT)
|
||||
#define I2S_INTSR_TXEIE_ENABLE (1 << I2S_INTSR_TXEIE_SHIFT)
|
||||
#define I2S_INTSR_RXOI_SHIFT 17
|
||||
#define I2S_INTSR_RXOI_INA (0 << I2S_INTSR_RXOI_SHIFT)
|
||||
#define I2S_INTSR_RXOI_ACT (1 << I2S_INTSR_RXOI_SHIFT)
|
||||
#define I2S_INTSR_RXFI_SHIFT 16
|
||||
#define I2S_INTSR_RXFI_INA (0 << I2S_INTSR_RXFI_SHIFT)
|
||||
#define I2S_INTSR_RXFI_ACT (1 << I2S_INTSR_RXFI_SHIFT)
|
||||
#define I2S_INTSR_TXUI_SHIFT 1
|
||||
#define I2S_INTSR_TXUI_INA (0 << I2S_INTSR_TXUI_SHIFT)
|
||||
#define I2S_INTSR_TXUI_ACT (1 << I2S_INTSR_TXUI_SHIFT)
|
||||
#define I2S_INTSR_TXEI_SHIFT 0
|
||||
#define I2S_INTSR_TXEI_INA (0 << I2S_INTSR_TXEI_SHIFT)
|
||||
#define I2S_INTSR_TXEI_ACT (1 << I2S_INTSR_TXEI_SHIFT)
|
||||
|
||||
/*
|
||||
* XFER
|
||||
* Transfer start register
|
||||
*/
|
||||
#define I2S_XFER_RXS_SHIFT 1
|
||||
#define I2S_XFER_RXS_STOP (0 << I2S_XFER_RXS_SHIFT)
|
||||
#define I2S_XFER_RXS_START (1 << I2S_XFER_RXS_SHIFT)
|
||||
#define I2S_XFER_TXS_SHIFT 0
|
||||
#define I2S_XFER_TXS_STOP (0 << I2S_XFER_TXS_SHIFT)
|
||||
#define I2S_XFER_TXS_START (1 << I2S_XFER_TXS_SHIFT)
|
||||
|
||||
/*
|
||||
* CLR
|
||||
* clear SCLK domain logic register
|
||||
*/
|
||||
#define I2S_CLR_RXC BIT(1)
|
||||
#define I2S_CLR_TXC BIT(0)
|
||||
|
||||
/*
|
||||
* TXDR
|
||||
* Transimt FIFO data register, write only.
|
||||
*/
|
||||
#define I2S_TXDR_MASK (0xff)
|
||||
|
||||
/*
|
||||
* RXDR
|
||||
* Receive FIFO data register, write only.
|
||||
*/
|
||||
#define I2S_RXDR_MASK (0xff)
|
||||
|
||||
/*
|
||||
* TDM_CTRL
|
||||
* TDM ctrl register
|
||||
*/
|
||||
#define TDM_FSYNC_WIDTH_SEL1_MSK GENMASK(20, 18)
|
||||
#define TDM_FSYNC_WIDTH_SEL1(x) (((x) - 1) << 18)
|
||||
#define TDM_FSYNC_WIDTH_SEL0_MSK BIT(17)
|
||||
#define TDM_FSYNC_WIDTH_HALF_FRAME 0
|
||||
#define TDM_FSYNC_WIDTH_ONE_FRAME BIT(17)
|
||||
#define TDM_SHIFT_CTRL_MSK GENMASK(16, 14)
|
||||
#define TDM_SHIFT_CTRL(x) ((x) << 14)
|
||||
#define TDM_SLOT_BIT_WIDTH_MSK GENMASK(13, 9)
|
||||
#define TDM_SLOT_BIT_WIDTH(x) (((x) - 1) << 9)
|
||||
#define TDM_FRAME_WIDTH_MSK GENMASK(8, 0)
|
||||
#define TDM_FRAME_WIDTH(x) (((x) - 1) << 0)
|
||||
|
||||
/*
|
||||
* CLKDIV
|
||||
* Mclk div register
|
||||
*/
|
||||
#define I2S_CLKDIV_TXM_SHIFT 0
|
||||
#define I2S_CLKDIV_TXM(x) (((x) - 1) << I2S_CLKDIV_TXM_SHIFT)
|
||||
#define I2S_CLKDIV_TXM_MASK (0xff << I2S_CLKDIV_TXM_SHIFT)
|
||||
#define I2S_CLKDIV_RXM_SHIFT 8
|
||||
#define I2S_CLKDIV_RXM(x) (((x) - 1) << I2S_CLKDIV_RXM_SHIFT)
|
||||
#define I2S_CLKDIV_RXM_MASK (0xff << I2S_CLKDIV_RXM_SHIFT)
|
||||
|
||||
/* Clock divider id */
|
||||
enum {
|
||||
ROCKCHIP_DIV_MCLK = 0,
|
||||
ROCKCHIP_DIV_BCLK,
|
||||
};
|
||||
|
||||
/* channel select */
|
||||
#define I2S_CSR_SHIFT 15
|
||||
#define I2S_CHN_2 (0 << I2S_CSR_SHIFT)
|
||||
#define I2S_CHN_4 (1 << I2S_CSR_SHIFT)
|
||||
#define I2S_CHN_6 (2 << I2S_CSR_SHIFT)
|
||||
#define I2S_CHN_8 (3 << I2S_CSR_SHIFT)
|
||||
|
||||
/* io direction cfg register */
|
||||
#define I2S_IO_DIRECTION_MASK (7)
|
||||
#define I2S_IO_8CH_OUT_2CH_IN (7)
|
||||
#define I2S_IO_6CH_OUT_4CH_IN (3)
|
||||
#define I2S_IO_4CH_OUT_6CH_IN (1)
|
||||
#define I2S_IO_2CH_OUT_8CH_IN (0)
|
||||
|
||||
/* I2S REGS */
|
||||
#define I2S_TXCR (0x0000)
|
||||
#define I2S_RXCR (0x0004)
|
||||
#define I2S_CKR (0x0008)
|
||||
#define I2S_TXFIFOLR (0x000c)
|
||||
#define I2S_DMACR (0x0010)
|
||||
#define I2S_INTCR (0x0014)
|
||||
#define I2S_INTSR (0x0018)
|
||||
#define I2S_XFER (0x001c)
|
||||
#define I2S_CLR (0x0020)
|
||||
#define I2S_TXDR (0x0024)
|
||||
#define I2S_RXDR (0x0028)
|
||||
#define I2S_RXFIFOLR (0x002c)
|
||||
#define I2S_TDM_TXCR (0x0030)
|
||||
#define I2S_TDM_RXCR (0x0034)
|
||||
#define I2S_CLKDIV (0x0038)
|
||||
|
||||
#define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16))
|
||||
|
||||
/* PX30 GRF CONFIGS */
|
||||
#define PX30_I2S0_CLK_IN_SRC_FROM_TX HIWORD_UPDATE(1, 13, 12)
|
||||
#define PX30_I2S0_CLK_IN_SRC_FROM_RX HIWORD_UPDATE(2, 13, 12)
|
||||
#define PX30_I2S0_MCLK_OUT_SRC_FROM_TX HIWORD_UPDATE(1, 5, 5)
|
||||
#define PX30_I2S0_MCLK_OUT_SRC_FROM_RX HIWORD_UPDATE(0, 5, 5)
|
||||
|
||||
#define PX30_I2S0_CLK_TXONLY \
|
||||
(PX30_I2S0_MCLK_OUT_SRC_FROM_TX | PX30_I2S0_CLK_IN_SRC_FROM_TX)
|
||||
|
||||
#define PX30_I2S0_CLK_RXONLY \
|
||||
(PX30_I2S0_MCLK_OUT_SRC_FROM_RX | PX30_I2S0_CLK_IN_SRC_FROM_RX)
|
||||
|
||||
/* RK1808 GRF CONFIGS */
|
||||
#define RK1808_I2S0_MCLK_OUT_SRC_FROM_RX HIWORD_UPDATE(1, 2, 2)
|
||||
#define RK1808_I2S0_MCLK_OUT_SRC_FROM_TX HIWORD_UPDATE(0, 2, 2)
|
||||
#define RK1808_I2S0_CLK_IN_SRC_FROM_TX HIWORD_UPDATE(1, 1, 0)
|
||||
#define RK1808_I2S0_CLK_IN_SRC_FROM_RX HIWORD_UPDATE(2, 1, 0)
|
||||
|
||||
#define RK1808_I2S0_CLK_TXONLY \
|
||||
(RK1808_I2S0_MCLK_OUT_SRC_FROM_TX | RK1808_I2S0_CLK_IN_SRC_FROM_TX)
|
||||
|
||||
#define RK1808_I2S0_CLK_RXONLY \
|
||||
(RK1808_I2S0_MCLK_OUT_SRC_FROM_RX | RK1808_I2S0_CLK_IN_SRC_FROM_RX)
|
||||
|
||||
/* RK3308 GRF CONFIGS */
|
||||
#define RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_RX HIWORD_UPDATE(1, 10, 10)
|
||||
#define RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_TX HIWORD_UPDATE(0, 10, 10)
|
||||
#define RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_TX HIWORD_UPDATE(1, 9, 9)
|
||||
#define RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_RX HIWORD_UPDATE(0, 9, 9)
|
||||
#define RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_RX HIWORD_UPDATE(1, 8, 8)
|
||||
#define RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_TX HIWORD_UPDATE(0, 8, 8)
|
||||
#define RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_RX HIWORD_UPDATE(1, 2, 2)
|
||||
#define RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_TX HIWORD_UPDATE(0, 2, 2)
|
||||
#define RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_TX HIWORD_UPDATE(1, 1, 1)
|
||||
#define RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_RX HIWORD_UPDATE(0, 1, 1)
|
||||
#define RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_RX HIWORD_UPDATE(1, 0, 0)
|
||||
#define RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_TX HIWORD_UPDATE(0, 0, 0)
|
||||
|
||||
#define RK3308_I2S0_CLK_TXONLY \
|
||||
(RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_TX | \
|
||||
RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_TX | \
|
||||
RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_TX)
|
||||
|
||||
#define RK3308_I2S0_CLK_RXONLY \
|
||||
(RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_RX | \
|
||||
RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_RX | \
|
||||
RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_RX)
|
||||
|
||||
#define RK3308_I2S1_CLK_TXONLY \
|
||||
(RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_TX | \
|
||||
RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_TX | \
|
||||
RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_TX)
|
||||
|
||||
#define RK3308_I2S1_CLK_RXONLY \
|
||||
(RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_RX | \
|
||||
RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_RX | \
|
||||
RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_RX)
|
||||
|
||||
/* RK3568 GRF CONFIGS */
|
||||
#define RK3568_I2S1_MCLK_OUT_SRC_FROM_TX HIWORD_UPDATE(1, 5, 5)
|
||||
#define RK3568_I2S1_MCLK_OUT_SRC_FROM_RX HIWORD_UPDATE(0, 5, 5)
|
||||
|
||||
#define RK3568_I2S1_CLK_TXONLY \
|
||||
RK3568_I2S1_MCLK_OUT_SRC_FROM_TX
|
||||
|
||||
#define RK3568_I2S1_CLK_RXONLY \
|
||||
RK3568_I2S1_MCLK_OUT_SRC_FROM_RX
|
||||
|
||||
#define RK3568_I2S3_MCLK_OUT_SRC_FROM_TX HIWORD_UPDATE(1, 15, 15)
|
||||
#define RK3568_I2S3_MCLK_OUT_SRC_FROM_RX HIWORD_UPDATE(0, 15, 15)
|
||||
#define RK3568_I2S3_SCLK_SRC_FROM_TX HIWORD_UPDATE(1, 7, 7)
|
||||
#define RK3568_I2S3_SCLK_SRC_FROM_RX HIWORD_UPDATE(0, 7, 7)
|
||||
#define RK3568_I2S3_LRCK_SRC_FROM_TX HIWORD_UPDATE(1, 6, 6)
|
||||
#define RK3568_I2S3_LRCK_SRC_FROM_RX HIWORD_UPDATE(0, 6, 6)
|
||||
|
||||
#define RK3568_I2S3_MCLK_TXONLY \
|
||||
RK3568_I2S3_MCLK_OUT_SRC_FROM_TX
|
||||
|
||||
#define RK3568_I2S3_CLK_TXONLY \
|
||||
(RK3568_I2S3_SCLK_SRC_FROM_TX | \
|
||||
RK3568_I2S3_LRCK_SRC_FROM_TX)
|
||||
|
||||
#define RK3568_I2S3_MCLK_RXONLY \
|
||||
RK3568_I2S3_MCLK_OUT_SRC_FROM_RX
|
||||
|
||||
#define RK3568_I2S3_CLK_RXONLY \
|
||||
(RK3568_I2S3_SCLK_SRC_FROM_RX | \
|
||||
RK3568_I2S3_LRCK_SRC_FROM_RX)
|
||||
|
||||
#define RK3568_I2S3_MCLK_IE HIWORD_UPDATE(0, 3, 3)
|
||||
#define RK3568_I2S3_MCLK_OE HIWORD_UPDATE(1, 3, 3)
|
||||
#define RK3568_I2S2_MCLK_IE HIWORD_UPDATE(0, 2, 2)
|
||||
#define RK3568_I2S2_MCLK_OE HIWORD_UPDATE(1, 2, 2)
|
||||
#define RK3568_I2S1_MCLK_TX_IE HIWORD_UPDATE(0, 1, 1)
|
||||
#define RK3568_I2S1_MCLK_TX_OE HIWORD_UPDATE(1, 1, 1)
|
||||
#define RK3568_I2S1_MCLK_RX_IE HIWORD_UPDATE(0, 0, 0)
|
||||
#define RK3568_I2S1_MCLK_RX_OE HIWORD_UPDATE(1, 0, 0)
|
||||
|
||||
/* RV1126 GRF CONFIGS */
|
||||
#define RV1126_I2S0_MCLK_OUT_SRC_FROM_TX HIWORD_UPDATE(0, 9, 9)
|
||||
#define RV1126_I2S0_MCLK_OUT_SRC_FROM_RX HIWORD_UPDATE(1, 9, 9)
|
||||
|
||||
#define RV1126_I2S0_CLK_TXONLY \
|
||||
RV1126_I2S0_MCLK_OUT_SRC_FROM_TX
|
||||
|
||||
#define RV1126_I2S0_CLK_RXONLY \
|
||||
RV1126_I2S0_MCLK_OUT_SRC_FROM_RX
|
||||
|
||||
#endif /* _ROCKCHIP_I2S_TDM_H */
|
Loading…
x
Reference in New Issue
Block a user