Commit 5bf83bf8 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/topic/fsl' into asoc-next

parents aef60a50 f0377086
Freescale Sony/Philips Digital Interface Format (S/PDIF) Controller
The Freescale S/PDIF audio block is a stereo transceiver that allows the
processor to receive and transmit digital audio via an coaxial cable or
a fibre cable.
Required properties:
- compatible : Compatible list, must contain "fsl,imx35-spdif".
- reg : Offset and length of the register set for the device.
- interrupts : Contains the spdif interrupt.
- dmas : Generic dma devicetree binding as described in
Documentation/devicetree/bindings/dma/dma.txt.
- dma-names : Two dmas have to be defined, "tx" and "rx".
- clocks : Contains an entry for each entry in clock-names.
- clock-names : Includes the following entries:
"core" The core clock of spdif controller
"rxtx<0-7>" Clock source list for tx and rx clock.
This clock list should be identical to
the source list connecting to the spdif
clock mux in "SPDIF Transceiver Clock
Diagram" of SoC reference manual. It
can also be referred to TxClk_Source
bit of register SPDIF_STC.
Example:
spdif: spdif@02004000 {
compatible = "fsl,imx35-spdif";
reg = <0x02004000 0x4000>;
interrupts = <0 52 0x04>;
dmas = <&sdma 14 18 0>,
<&sdma 15 18 0>;
dma-names = "rx", "tx";
clocks = <&clks 197>, <&clks 3>,
<&clks 197>, <&clks 107>,
<&clks 0>, <&clks 118>,
<&clks 62>, <&clks 139>,
<&clks 0>;
clock-names = "core", "rxtx0",
"rxtx1", "rxtx2",
"rxtx3", "rxtx4",
"rxtx5", "rxtx6",
"rxtx7";
status = "okay";
};
......@@ -43,10 +43,22 @@ Required properties:
together. This would still allow different sample sizes,
but not different sample rates.
Required are also ac97 link bindings if ac97 is used. See
Documentation/devicetree/bindings/sound/soc-ac97link.txt for the necessary
bindings.
Optional properties:
- codec-handle: Phandle to a 'codec' node that defines an audio
codec connected to this SSI. This node is typically
a child of an I2C or other control node.
- fsl,fiq-stream-filter: Bool property. Disabled DMA and use FIQ instead to
filter the codec stream. This is necessary for some boards
where an incompatible codec is connected to this SSI, e.g.
on pca100 and pcm043.
- dmas: Generic dma devicetree binding as described in
Documentation/devicetree/bindings/dma/dma.txt.
- dma-names: Two dmas have to be defined, "tx" and "rx", if fsl,imx-fiq
is not defined.
Child 'codec' node required properties:
- compatible: Compatible list, contains the name of the codec
......
......@@ -5,6 +5,15 @@ Required properties:
or "fsl,imx31-audmux" for the version firstly used on i.MX31.
- reg : Should contain AUDMUX registers location and length
An initial configuration can be setup using child nodes.
Required properties of optional child nodes:
- fsl,audmux-port : Integer of the audmux port that is configured by this
child node.
- fsl,port-config : List of configuration options for the specific port. For
imx31-audmux and above, it is a list of tuples <ptcr pdcr>. For
imx21-audmux it is a list of pcr values.
Example:
audmux@021d8000 {
......
#ifndef __DT_FSL_IMX_AUDMUX_H
#define __DT_FSL_IMX_AUDMUX_H
#define MX27_AUDMUX_HPCR1_SSI0 0
#define MX27_AUDMUX_HPCR2_SSI1 1
#define MX27_AUDMUX_HPCR3_SSI_PINS_4 2
#define MX27_AUDMUX_PPCR1_SSI_PINS_1 3
#define MX27_AUDMUX_PPCR2_SSI_PINS_2 4
#define MX27_AUDMUX_PPCR3_SSI_PINS_3 5
#define MX31_AUDMUX_PORT1_SSI0 0
#define MX31_AUDMUX_PORT2_SSI1 1
#define MX31_AUDMUX_PORT3_SSI_PINS_3 2
#define MX31_AUDMUX_PORT4_SSI_PINS_4 3
#define MX31_AUDMUX_PORT5_SSI_PINS_5 4
#define MX31_AUDMUX_PORT6_SSI_PINS_6 5
#define MX31_AUDMUX_PORT7_SSI_PINS_7 6
#define MX51_AUDMUX_PORT1_SSI0 0
#define MX51_AUDMUX_PORT2_SSI1 1
#define MX51_AUDMUX_PORT3 2
#define MX51_AUDMUX_PORT4 3
#define MX51_AUDMUX_PORT5 4
#define MX51_AUDMUX_PORT6 5
#define MX51_AUDMUX_PORT7 6
/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
#define IMX_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff)
#define IMX_AUDMUX_V1_PCR_INMEN (1 << 8)
#define IMX_AUDMUX_V1_PCR_TXRXEN (1 << 10)
#define IMX_AUDMUX_V1_PCR_SYN (1 << 12)
#define IMX_AUDMUX_V1_PCR_RXDSEL(x) (((x) & 0x7) << 13)
#define IMX_AUDMUX_V1_PCR_RFCSEL(x) (((x) & 0xf) << 20)
#define IMX_AUDMUX_V1_PCR_RCLKDIR (1 << 24)
#define IMX_AUDMUX_V1_PCR_RFSDIR (1 << 25)
#define IMX_AUDMUX_V1_PCR_TFCSEL(x) (((x) & 0xf) << 26)
#define IMX_AUDMUX_V1_PCR_TCLKDIR (1 << 30)
#define IMX_AUDMUX_V1_PCR_TFSDIR (1 << 31)
/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
#define IMX_AUDMUX_V2_PTCR_TFSDIR (1 << 31)
#define IMX_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27)
#define IMX_AUDMUX_V2_PTCR_TCLKDIR (1 << 26)
#define IMX_AUDMUX_V2_PTCR_TCSEL(x) (((x) & 0xf) << 22)
#define IMX_AUDMUX_V2_PTCR_RFSDIR (1 << 21)
#define IMX_AUDMUX_V2_PTCR_RFSEL(x) (((x) & 0xf) << 17)
#define IMX_AUDMUX_V2_PTCR_RCLKDIR (1 << 16)
#define IMX_AUDMUX_V2_PTCR_RCSEL(x) (((x) & 0xf) << 12)
#define IMX_AUDMUX_V2_PTCR_SYN (1 << 11)
#define IMX_AUDMUX_V2_PDCR_RXDSEL(x) (((x) & 0x7) << 13)
#define IMX_AUDMUX_V2_PDCR_TXRXEN (1 << 12)
#define IMX_AUDMUX_V2_PDCR_MODE(x) (((x) & 0x3) << 8)
#define IMX_AUDMUX_V2_PDCR_INMMASK(x) ((x) & 0xff)
#endif /* __DT_FSL_IMX_AUDMUX_H */
config SND_SOC_FSL_SSI
tristate
config SND_SOC_FSL_SPDIF
tristate
config SND_SOC_FSL_UTILS
tristate
......@@ -98,7 +101,7 @@ endif # SND_POWERPC_SOC
menuconfig SND_IMX_SOC
tristate "SoC Audio for Freescale i.MX CPUs"
depends on ARCH_MXC
depends on ARCH_MXC || COMPILE_TEST
help
Say Y or M if you want to add support for codecs attached to
the i.MX CPUs.
......@@ -109,11 +112,11 @@ config SND_SOC_IMX_SSI
tristate
config SND_SOC_IMX_PCM_FIQ
bool
tristate
select FIQ
config SND_SOC_IMX_PCM_DMA
bool
tristate
select SND_SOC_GENERIC_DMAENGINE_PCM
config SND_SOC_IMX_AUDMUX
......@@ -175,7 +178,6 @@ config SND_SOC_IMX_WM8962
select SND_SOC_IMX_PCM_DMA
select SND_SOC_IMX_AUDMUX
select SND_SOC_FSL_SSI
select SND_SOC_FSL_UTILS
help
Say Y if you want to add support for SoC audio on an i.MX board with
a wm8962 codec.
......@@ -187,14 +189,13 @@ config SND_SOC_IMX_SGTL5000
select SND_SOC_IMX_PCM_DMA
select SND_SOC_IMX_AUDMUX
select SND_SOC_FSL_SSI
select SND_SOC_FSL_UTILS
help
Say Y if you want to add support for SoC audio on an i.MX board with
a sgtl5000 codec.
config SND_SOC_IMX_MC13783
tristate "SoC Audio support for I.MX boards with mc13783"
depends on MFD_MC13783
depends on MFD_MC13783 && ARM
select SND_SOC_IMX_SSI
select SND_SOC_IMX_AUDMUX
select SND_SOC_MC13783
......
......@@ -12,9 +12,11 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
# Freescale PowerPC SSI/DMA Platform Support
snd-soc-fsl-ssi-objs := fsl_ssi.o
snd-soc-fsl-spdif-objs := fsl_spdif.o
snd-soc-fsl-utils-objs := fsl_utils.o
snd-soc-fsl-dma-objs := fsl_dma.o
obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o
obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
......
This diff is collapsed.
/*
* fsl_spdif.h - ALSA S/PDIF interface for the Freescale i.MX SoC
*
* Copyright (C) 2013 Freescale Semiconductor, Inc.
*
* Author: Nicolin Chen <b42378@freescale.com>
*
* Based on fsl_ssi.h
* Author: Timur Tabi <timur@freescale.com>
* Copyright 2007-2008 Freescale Semiconductor, Inc.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef _FSL_SPDIF_DAI_H
#define _FSL_SPDIF_DAI_H
/* S/PDIF Register Map */
#define REG_SPDIF_SCR 0x0 /* SPDIF Configuration Register */
#define REG_SPDIF_SRCD 0x4 /* CDText Control Register */
#define REG_SPDIF_SRPC 0x8 /* PhaseConfig Register */
#define REG_SPDIF_SIE 0xc /* InterruptEn Register */
#define REG_SPDIF_SIS 0x10 /* InterruptStat Register */
#define REG_SPDIF_SIC 0x10 /* InterruptClear Register */
#define REG_SPDIF_SRL 0x14 /* SPDIFRxLeft Register */
#define REG_SPDIF_SRR 0x18 /* SPDIFRxRight Register */
#define REG_SPDIF_SRCSH 0x1c /* SPDIFRxCChannel_h Register */
#define REG_SPDIF_SRCSL 0x20 /* SPDIFRxCChannel_l Register */
#define REG_SPDIF_SRU 0x24 /* UchannelRx Register */
#define REG_SPDIF_SRQ 0x28 /* QchannelRx Register */
#define REG_SPDIF_STL 0x2C /* SPDIFTxLeft Register */
#define REG_SPDIF_STR 0x30 /* SPDIFTxRight Register */
#define REG_SPDIF_STCSCH 0x34 /* SPDIFTxCChannelCons_h Register */
#define REG_SPDIF_STCSCL 0x38 /* SPDIFTxCChannelCons_l Register */
#define REG_SPDIF_SRFM 0x44 /* FreqMeas Register */
#define REG_SPDIF_STC 0x50 /* SPDIFTxClk Register */
/* SPDIF Configuration register */
#define SCR_RXFIFO_CTL_OFFSET 23
#define SCR_RXFIFO_CTL_MASK (1 << SCR_RXFIFO_CTL_OFFSET)
#define SCR_RXFIFO_CTL_ZERO (1 << SCR_RXFIFO_CTL_OFFSET)
#define SCR_RXFIFO_OFF_OFFSET 22
#define SCR_RXFIFO_OFF_MASK (1 << SCR_RXFIFO_OFF_OFFSET)
#define SCR_RXFIFO_OFF (1 << SCR_RXFIFO_OFF_OFFSET)
#define SCR_RXFIFO_RST_OFFSET 21
#define SCR_RXFIFO_RST_MASK (1 << SCR_RXFIFO_RST_OFFSET)
#define SCR_RXFIFO_RST (1 << SCR_RXFIFO_RST_OFFSET)
#define SCR_RXFIFO_FSEL_OFFSET 19
#define SCR_RXFIFO_FSEL_MASK (0x3 << SCR_RXFIFO_FSEL_OFFSET)
#define SCR_RXFIFO_FSEL_IF0 (0x0 << SCR_RXFIFO_FSEL_OFFSET)
#define SCR_RXFIFO_FSEL_IF4 (0x1 << SCR_RXFIFO_FSEL_OFFSET)
#define SCR_RXFIFO_FSEL_IF8 (0x2 << SCR_RXFIFO_FSEL_OFFSET)
#define SCR_RXFIFO_FSEL_IF12 (0x3 << SCR_RXFIFO_FSEL_OFFSET)
#define SCR_RXFIFO_AUTOSYNC_OFFSET 18
#define SCR_RXFIFO_AUTOSYNC_MASK (1 << SCR_RXFIFO_AUTOSYNC_OFFSET)
#define SCR_RXFIFO_AUTOSYNC (1 << SCR_RXFIFO_AUTOSYNC_OFFSET)
#define SCR_TXFIFO_AUTOSYNC_OFFSET 17
#define SCR_TXFIFO_AUTOSYNC_MASK (1 << SCR_TXFIFO_AUTOSYNC_OFFSET)
#define SCR_TXFIFO_AUTOSYNC (1 << SCR_TXFIFO_AUTOSYNC_OFFSET)
#define SCR_TXFIFO_FSEL_OFFSET 15
#define SCR_TXFIFO_FSEL_MASK (0x3 << SCR_TXFIFO_FSEL_OFFSET)
#define SCR_TXFIFO_FSEL_IF0 (0x0 << SCR_TXFIFO_FSEL_OFFSET)
#define SCR_TXFIFO_FSEL_IF4 (0x1 << SCR_TXFIFO_FSEL_OFFSET)
#define SCR_TXFIFO_FSEL_IF8 (0x2 << SCR_TXFIFO_FSEL_OFFSET)
#define SCR_TXFIFO_FSEL_IF12 (0x3 << SCR_TXFIFO_FSEL_OFFSET)
#define SCR_LOW_POWER (1 << 13)
#define SCR_SOFT_RESET (1 << 12)
#define SCR_TXFIFO_CTRL_OFFSET 10
#define SCR_TXFIFO_CTRL_MASK (0x3 << SCR_TXFIFO_CTRL_OFFSET)
#define SCR_TXFIFO_CTRL_ZERO (0x0 << SCR_TXFIFO_CTRL_OFFSET)
#define SCR_TXFIFO_CTRL_NORMAL (0x1 << SCR_TXFIFO_CTRL_OFFSET)
#define SCR_TXFIFO_CTRL_ONESAMPLE (0x2 << SCR_TXFIFO_CTRL_OFFSET)
#define SCR_DMA_RX_EN_OFFSET 9
#define SCR_DMA_RX_EN_MASK (1 << SCR_DMA_RX_EN_OFFSET)
#define SCR_DMA_RX_EN (1 << SCR_DMA_RX_EN_OFFSET)
#define SCR_DMA_TX_EN_OFFSET 8
#define SCR_DMA_TX_EN_MASK (1 << SCR_DMA_TX_EN_OFFSET)
#define SCR_DMA_TX_EN (1 << SCR_DMA_TX_EN_OFFSET)
#define SCR_VAL_OFFSET 5
#define SCR_VAL_MASK (1 << SCR_VAL_OFFSET)
#define SCR_VAL_CLEAR (1 << SCR_VAL_OFFSET)
#define SCR_TXSEL_OFFSET 2
#define SCR_TXSEL_MASK (0x7 << SCR_TXSEL_OFFSET)
#define SCR_TXSEL_OFF (0 << SCR_TXSEL_OFFSET)
#define SCR_TXSEL_RX (1 << SCR_TXSEL_OFFSET)
#define SCR_TXSEL_NORMAL (0x5 << SCR_TXSEL_OFFSET)
#define SCR_USRC_SEL_OFFSET 0x0
#define SCR_USRC_SEL_MASK (0x3 << SCR_USRC_SEL_OFFSET)
#define SCR_USRC_SEL_NONE (0x0 << SCR_USRC_SEL_OFFSET)
#define SCR_USRC_SEL_RECV (0x1 << SCR_USRC_SEL_OFFSET)
#define SCR_USRC_SEL_CHIP (0x3 << SCR_USRC_SEL_OFFSET)
/* SPDIF CDText control */
#define SRCD_CD_USER_OFFSET 1
#define SRCD_CD_USER (1 << SRCD_CD_USER_OFFSET)
/* SPDIF Phase Configuration register */
#define SRPC_DPLL_LOCKED (1 << 6)
#define SRPC_CLKSRC_SEL_OFFSET 7
#define SRPC_CLKSRC_SEL_MASK (0xf << SRPC_CLKSRC_SEL_OFFSET)
#define SRPC_CLKSRC_SEL_SET(x) ((x << SRPC_CLKSRC_SEL_OFFSET) & SRPC_CLKSRC_SEL_MASK)
#define SRPC_CLKSRC_SEL_LOCKED_OFFSET1 5
#define SRPC_CLKSRC_SEL_LOCKED_OFFSET2 2
#define SRPC_GAINSEL_OFFSET 3
#define SRPC_GAINSEL_MASK (0x7 << SRPC_GAINSEL_OFFSET)
#define SRPC_GAINSEL_SET(x) ((x << SRPC_GAINSEL_OFFSET) & SRPC_GAINSEL_MASK)
#define SRPC_CLKSRC_MAX 16
enum spdif_gainsel {
GAINSEL_MULTI_24 = 0,
GAINSEL_MULTI_16,
GAINSEL_MULTI_12,
GAINSEL_MULTI_8,
GAINSEL_MULTI_6,
GAINSEL_MULTI_4,
GAINSEL_MULTI_3,
};
#define GAINSEL_MULTI_MAX (GAINSEL_MULTI_3 + 1)
#define SPDIF_DEFAULT_GAINSEL GAINSEL_MULTI_8
/* SPDIF interrupt mask define */
#define INT_DPLL_LOCKED (1 << 20)
#define INT_TXFIFO_UNOV (1 << 19)
#define INT_TXFIFO_RESYNC (1 << 18)
#define INT_CNEW (1 << 17)
#define INT_VAL_NOGOOD (1 << 16)
#define INT_SYM_ERR (1 << 15)
#define INT_BIT_ERR (1 << 14)
#define INT_URX_FUL (1 << 10)
#define INT_URX_OV (1 << 9)
#define INT_QRX_FUL (1 << 8)
#define INT_QRX_OV (1 << 7)
#define INT_UQ_SYNC (1 << 6)
#define INT_UQ_ERR (1 << 5)
#define INT_RXFIFO_UNOV (1 << 4)
#define INT_RXFIFO_RESYNC (1 << 3)
#define INT_LOSS_LOCK (1 << 2)
#define INT_TX_EM (1 << 1)
#define INT_RXFIFO_FUL (1 << 0)
/* SPDIF Clock register */
#define STC_SYSCLK_DIV_OFFSET 11
#define STC_SYSCLK_DIV_MASK (0x1ff << STC_TXCLK_SRC_OFFSET)
#define STC_SYSCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_SYSCLK_DIV_MASK)
#define STC_TXCLK_SRC_OFFSET 8
#define STC_TXCLK_SRC_MASK (0x7 << STC_TXCLK_SRC_OFFSET)
#define STC_TXCLK_SRC_SET(x) ((x << STC_TXCLK_SRC_OFFSET) & STC_TXCLK_SRC_MASK)
#define STC_TXCLK_ALL_EN_OFFSET 7
#define STC_TXCLK_ALL_EN_MASK (1 << STC_TXCLK_ALL_EN_OFFSET)
#define STC_TXCLK_ALL_EN (1 << STC_TXCLK_ALL_EN_OFFSET)
#define STC_TXCLK_DIV_OFFSET 0
#define STC_TXCLK_DIV_MASK (0x7ff << STC_TXCLK_DIV_OFFSET)
#define STC_TXCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_TXCLK_DIV_MASK)
#define STC_TXCLK_SRC_MAX 8
/* SPDIF tx rate */
enum spdif_txrate {
SPDIF_TXRATE_32000 = 0,
SPDIF_TXRATE_44100,
SPDIF_TXRATE_48000,
};
#define SPDIF_TXRATE_MAX (SPDIF_TXRATE_48000 + 1)
#define SPDIF_CSTATUS_BYTE 6
#define SPDIF_UBITS_SIZE 96
#define SPDIF_QSUB_SIZE (SPDIF_UBITS_SIZE / 8)
#define FSL_SPDIF_RATES_PLAYBACK (SNDRV_PCM_RATE_32000 | \
SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000)
#define FSL_SPDIF_RATES_CAPTURE (SNDRV_PCM_RATE_16000 | \
SNDRV_PCM_RATE_32000 | \
SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000 | \
SNDRV_PCM_RATE_64000 | \
SNDRV_PCM_RATE_96000)
#define FSL_SPDIF_FORMATS_PLAYBACK (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE)
#define FSL_SPDIF_FORMATS_CAPTURE (SNDRV_PCM_FMTBIT_S24_LE)
#endif /* _FSL_SPDIF_DAI_H */
This diff is collapsed.
......@@ -73,8 +73,11 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
if (!buf)
return -ENOMEM;
if (audmux_clk)
clk_prepare_enable(audmux_clk);
if (audmux_clk) {
ret = clk_prepare_enable(audmux_clk);
if (ret)
return ret;
}
ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port));
pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port));
......@@ -224,14 +227,19 @@ EXPORT_SYMBOL_GPL(imx_audmux_v1_configure_port);
int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
unsigned int pdcr)
{
int ret;
if (audmux_type != IMX31_AUDMUX)
return -EINVAL;
if (!audmux_base)
return -ENOSYS;
if (audmux_clk)
clk_prepare_enable(audmux_clk);
if (audmux_clk) {
ret = clk_prepare_enable(audmux_clk);
if (ret)
return ret;
}
writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port));
writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port));
......@@ -243,6 +251,66 @@ int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
}
EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
static int imx_audmux_parse_dt_defaults(struct platform_device *pdev,
struct device_node *of_node)
{
struct device_node *child;
for_each_available_child_of_node(of_node, child) {
unsigned int port;
unsigned int ptcr = 0;
unsigned int pdcr = 0;
unsigned int pcr = 0;
unsigned int val;
int ret;
int i = 0;
ret = of_property_read_u32(child, "fsl,audmux-port", &port);
if (ret) {
dev_warn(&pdev->dev, "Failed to get fsl,audmux-port of child node \"%s\"\n",
child->full_name);
continue;
}
if (!of_property_read_bool(child, "fsl,port-config")) {
dev_warn(&pdev->dev, "child node \"%s\" does not have property fsl,port-config\n",
child->full_name);
continue;
}
for (i = 0; (ret = of_property_read_u32_index(child,
"fsl,port-config", i, &val)) == 0;
++i) {
if (audmux_type == IMX31_AUDMUX) {
if (i % 2)
pdcr |= val;
else
ptcr |= val;
} else {
pcr |= val;
}
}
if (ret != -EOVERFLOW) {
dev_err(&pdev->dev, "Failed to read u32 at index %d of child %s\n",
i, child->full_name);
continue;
}
if (audmux_type == IMX31_AUDMUX) {
if (i % 2) {
dev_err(&pdev->dev, "One pdcr value is missing in child node %s\n",
child->full_name);
continue;
}
imx_audmux_v2_configure_port(port, ptcr, pdcr);
} else {
imx_audmux_v1_configure_port(port, pcr);
}
}
return 0;
}
static int imx_audmux_probe(struct platform_device *pdev)
{
struct resource *res;
......@@ -267,6 +335,8 @@ static int imx_audmux_probe(struct platform_device *pdev)
if (audmux_type == IMX31_AUDMUX)
audmux_debugfs_init();
imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node);
return 0;
}
......
#ifndef __IMX_AUDMUX_H
#define __IMX_AUDMUX_H
#define MX27_AUDMUX_HPCR1_SSI0 0
#define MX27_AUDMUX_HPCR2_SSI1 1
#define MX27_AUDMUX_HPCR3_SSI_PINS_4 2
#define MX27_AUDMUX_PPCR1_SSI_PINS_1 3
#define MX27_AUDMUX_PPCR2_SSI_PINS_2 4
#define MX27_AUDMUX_PPCR3_SSI_PINS_3 5
#define MX31_AUDMUX_PORT1_SSI0 0
#define MX31_AUDMUX_PORT2_SSI1 1
#define MX31_AUDMUX_PORT3_SSI_PINS_3 2
#define MX31_AUDMUX_PORT4_SSI_PINS_4 3
#define MX31_AUDMUX_PORT5_SSI_PINS_5 4
#define MX31_AUDMUX_PORT6_SSI_PINS_6 5
#define MX31_AUDMUX_PORT7_SSI_PINS_7 6
#define MX51_AUDMUX_PORT1_SSI0 0
#define MX51_AUDMUX_PORT2_SSI1 1
#define MX51_AUDMUX_PORT3 2
#define MX51_AUDMUX_PORT4 3
#define MX51_AUDMUX_PORT5 4
#define MX51_AUDMUX_PORT6 5
#define MX51_AUDMUX_PORT7 6
/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
#define IMX_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff)
#define IMX_AUDMUX_V1_PCR_INMEN (1 << 8)
#define IMX_AUDMUX_V1_PCR_TXRXEN (1 << 10)
#define IMX_AUDMUX_V1_PCR_SYN (1 << 12)
#define IMX_AUDMUX_V1_PCR_RXDSEL(x) (((x) & 0x7) << 13)
#define IMX_AUDMUX_V1_PCR_RFCSEL(x) (((x) & 0xf) << 20)
#define IMX_AUDMUX_V1_PCR_RCLKDIR (1 << 24)
#define IMX_AUDMUX_V1_PCR_RFSDIR (1 << 25)
#define IMX_AUDMUX_V1_PCR_TFCSEL(x) (((x) & 0xf) << 26)
#define IMX_AUDMUX_V1_PCR_TCLKDIR (1 << 30)
#define IMX_AUDMUX_V1_PCR_TFSDIR (1 << 31)
/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
#define IMX_AUDMUX_V2_PTCR_TFSDIR (1 << 31)
#define IMX_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27)
#define IMX_AUDMUX_V2_PTCR_TCLKDIR (1 << 26)
#define IMX_AUDMUX_V2_PTCR_TCSEL(x) (((x) & 0xf) << 22)
#define IMX_AUDMUX_V2_PTCR_RFSDIR (1 << 21)
#define IMX_AUDMUX_V2_PTCR_RFSEL(x) (((x) & 0xf) << 17)
#define IMX_AUDMUX_V2_PTCR_RCLKDIR (1 << 16)
#define IMX_AUDMUX_V2_PTCR_RCSEL(x) (((x) & 0xf) << 12)
#define IMX_AUDMUX_V2_PTCR_SYN (1 << 11)
#define IMX_AUDMUX_V2_PDCR_RXDSEL(x) (((x) & 0x7) << 13)
#define IMX_AUDMUX_V2_PDCR_TXRXEN (1 << 12)
#define IMX_AUDMUX_V2_PDCR_MODE(x) (((x) & 0x3) << 8)
#define IMX_AUDMUX_V2_PDCR_INMMASK(x) ((x) & 0xff)
#include <dt-bindings/sound/fsl-imx-audmux.h>
int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr);
......
......@@ -90,6 +90,7 @@ static const struct snd_soc_dapm_route imx_mc13783_routes[] = {
static struct snd_soc_card imx_mc13783 = {
.name = "imx_mc13783",
.owner = THIS_MODULE,
.dai_link = imx_mc13783_dai_mc13783,
.num_links = ARRAY_SIZE(imx_mc13783_dai_mc13783),
.dapm_widgets = imx_mc13783_widget,
......
......@@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/dmaengine.h>
#include <linux/types.h>
#include <linux/module.h>
#include <sound/core.h>
#include <sound/pcm.h>
......@@ -64,7 +65,6 @@ int imx_pcm_dma_init(struct platform_device *pdev)
{
return snd_dmaengine_pcm_register(&pdev->dev, &imx_dmaengine_pcm_config,
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
SND_DMAENGINE_PCM_FLAG_NO_DT |
SND_DMAENGINE_PCM_FLAG_COMPAT);
}
EXPORT_SYMBOL_GPL(imx_pcm_dma_init);
......@@ -74,3 +74,5 @@ void imx_pcm_dma_exit(struct platform_device *pdev)
snd_dmaengine_pcm_unregister(&pdev->dev);
}
EXPORT_SYMBOL_GPL(imx_pcm_dma_exit);
MODULE_LICENSE("GPL");
......@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/dmaengine_pcm.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
......@@ -32,6 +33,7 @@
#include <linux/platform_data/asoc-imx-ssi.h>
#include "imx-ssi.h"
#include "imx-pcm.h"
struct imx_pcm_runtime_data {
unsigned int period;
......@@ -366,9 +368,9 @@ static struct snd_soc_platform_driver imx_soc_platform_fiq = {
.pcm_free = imx_pcm_fiq_free,
};
int imx_pcm_fiq_init(struct platform_device *pdev)
int imx_pcm_fiq_init(struct platform_device *pdev,
struct imx_pcm_fiq_params *params)
{
struct imx_ssi *ssi = platform_get_drvdata(pdev);
int ret;
ret = claim_fiq(&fh);
......@@ -377,15 +379,15 @@ int imx_pcm_fiq_init(struct platform_device *pdev)
return ret;
}
mxc_set_irq_fiq(ssi->irq, 1);
ssi_irq = ssi->irq;
mxc_set_irq_fiq(params->irq, 1);
ssi_irq = params->irq;
imx_pcm_fiq = ssi->irq;
imx_pcm_fiq = params->irq;
imx_ssi_fiq_base = (unsigned long)ssi->base;
imx_ssi_fiq_base = (unsigned long)params->base;
ssi->dma_params_tx.maxburst = 4;
ssi->dma_params_rx.maxburst = 6;
params->dma_params_tx->maxburst = 4;
params->dma_params_rx->maxburst = 6;
ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
if (ret)
......@@ -406,3 +408,5 @@ void imx_pcm_fiq_exit(struct platform_device *pdev)
snd_soc_unregister_platform(&pdev->dev);
}
EXPORT_SYMBOL_GPL(imx_pcm_fiq_exit);
MODULE_LICENSE("GPL");
......@@ -22,17 +22,23 @@
static inline void
imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data,
int dma, bool shared)
int dma, enum sdma_peripheral_type peripheral_type)
{
dma_data->dma_request = dma;
dma_data->priority = DMA_PRIO_HIGH;
if (shared)
dma_data->peripheral_type = IMX_DMATYPE_SSI_SP;
else
dma_data->peripheral_type = IMX_DMATYPE_SSI;
dma_data->peripheral_type = peripheral_type;
}
#ifdef CONFIG_SND_SOC_IMX_PCM_DMA
struct imx_pcm_fiq_params {
int irq;
void __iomem *base;
/* Pointer to original ssi driver to setup tx rx sizes */
struct snd_dmaengine_dai_dma_data *dma_params_rx;
struct snd_dmaengine_dai_dma_data *dma_params_tx;
};
#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA)
int imx_pcm_dma_init(struct platform_device *pdev);
void imx_pcm_dma_exit(struct platform_device *pdev);
#else
......@@ -46,11 +52,13 @@ static inline void imx_pcm_dma_exit(struct platform_device *pdev)
}
#endif
#ifdef CONFIG_SND_SOC_IMX_PCM_FIQ
int imx_pcm_fiq_init(struct platform_device *pdev);
#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_FIQ)
int imx_pcm_fiq_init(struct platform_device *pdev,
struct imx_pcm_fiq_params *params);
void imx_pcm_fiq_exit(struct platform_device *pdev);
#else
static inline int imx_pcm_fiq_init(struct platform_device *pdev)
static inline int imx_pcm_fiq_init(struct platform_device *pdev,
struct imx_pcm_fiq_params *params)
{
return -ENODEV;
}
......
......@@ -129,8 +129,10 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
}
data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
if (IS_ERR(data->codec_clk))
if (IS_ERR(data->codec_clk)) {
ret = PTR_ERR(data->codec_clk);
goto fail;
}
data->clk_frequency = clk_get_rate(data->codec_clk);
......
......@@ -571,13 +571,13 @@ static int imx_ssi_probe(struct platform_device *pdev)
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
if (res) {
imx_pcm_dma_params_init_data(&ssi->filter_data_tx, res->start,
false);
IMX_DMATYPE_SSI);
}
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0");
if (res) {
imx_pcm_dma_params_init_data(&ssi->filter_data_rx, res->start,
false);
IMX_DMATYPE_SSI);
}
platform_set_drvdata(pdev, ssi);
......@@ -595,7 +595,12 @@ static int imx_ssi_probe(struct platform_device *pdev)
goto failed_register;
}
ret = imx_pcm_fiq_init(pdev);
ssi->fiq_params.irq = ssi->irq;
ssi->fiq_params.base = ssi->base;
ssi->fiq_params.dma_params_rx = &ssi->dma_params_rx;
ssi->fiq_params.dma_params_tx = &ssi->dma_params_tx;
ret = imx_pcm_fiq_init(pdev, &ssi->fiq_params);
if (ret)
goto failed_pcm_fiq;
......
......@@ -209,6 +209,7 @@ struct imx_ssi {
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct imx_dma_data filter_data_tx;
struct imx_dma_data filter_data_rx;
struct imx_pcm_fiq_params fiq_params;
int enabled;
};
......
......@@ -217,7 +217,8 @@ static int imx_wm8962_probe(struct platform_device *pdev)
codec_dev = of_find_i2c_device_by_node(codec_np);
if (!codec_dev || !codec_dev->driver) {
dev_err(&pdev->dev, "failed to find codec platform device\n");
return -EINVAL;
ret = -EINVAL;
goto fail;
}
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment