Commit 2cde51fb authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/ad1836', 'asoc/topic/ad193x',...

Merge remote-tracking branches 'asoc/topic/ad1836', 'asoc/topic/ad193x', 'asoc/topic/adav80x', 'asoc/topic/adsp', 'asoc/topic/ak4641', 'asoc/topic/ak4642', 'asoc/topic/arizona', 'asoc/topic/atmel', 'asoc/topic/au1x', 'asoc/topic/axi', 'asoc/topic/bcm2835', 'asoc/topic/blackfin', 'asoc/topic/cs4271', 'asoc/topic/cs42l52', 'asoc/topic/da7210', 'asoc/topic/davinci', 'asoc/topic/ep93xx', 'asoc/topic/fsl', 'asoc/topic/fsl-mxs', 'asoc/topic/generic', 'asoc/topic/hdmi', 'asoc/topic/jack', 'asoc/topic/jz4740', 'asoc/topic/max98090', 'asoc/topic/mxs', 'asoc/topic/omap', 'asoc/topic/pxa', 'asoc/topic/rcar', 'asoc/topic/s6000', 'asoc/topic/sai', 'asoc/topic/samsung', 'asoc/topic/sgtl5000', 'asoc/topic/spear', 'asoc/topic/ssm2518', 'asoc/topic/ssm2602', 'asoc/topic/tegra', 'asoc/topic/tlv320aic3x', 'asoc/topic/twl6040', 'asoc/topic/txx9', 'asoc/topic/uda1380', 'asoc/topic/width', 'asoc/topic/wm8510', 'asoc/topic/wm8523', 'asoc/topic/wm8580', 'asoc/topic/wm8711', 'asoc/topic/wm8728', 'asoc/topic/wm8731', 'asoc/topic/wm8741', 'asoc/topic/wm8750', 'asoc/topic/wm8753', 'asoc/topic/wm8776', 'asoc/topic/wm8804', 'asoc/topic/wm8900', 'asoc/topic/wm8901', 'asoc/topic/wm8940', 'asoc/topic/wm8962', 'asoc/topic/wm8974', 'asoc/topic/wm8985', 'asoc/topic/wm8988', 'asoc/topic/wm8990', 'asoc/topic/wm8991', 'asoc/topic/wm8994', 'asoc/topic/wm8995', 'asoc/topic/wm9081' and 'asoc/topic/x86' into asoc-next
ADI AXI-I2S controller
Required properties:
- compatible : Must be "adi,axi-i2s-1.00.a"
- reg : Must contain I2S core's registers location and length
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
The controller expects two clocks, the clock used for the AXI interface and
the clock used as the sampling rate reference clock sample.
- clock-names : "axi" for the clock to the AXI interface, "ref" for the sample
rate reference clock.
- dmas: Pairs of phandle and specifier for the DMA channels that are used by
the core. The core expects two dma channels, one for transmit and one for
receive.
- dma-names : "tx" for the transmit channel, "rx" for the receive channel.
For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
please check:
* resource-names.txt
* clock/clock-bindings.txt
* dma/dma.txt
Example:
i2s: i2s@0x77600000 {
compatible = "adi,axi-i2s-1.00.a";
reg = <0x77600000 0x1000>;
clocks = <&clk 15>, <&audio_clock>;
clock-names = "axi", "ref";
dmas = <&ps7_dma 0>, <&ps7_dma 1>;
dma-names = "tx", "rx";
};
ADI AXI-SPDIF controller
Required properties:
- compatible : Must be "adi,axi-spdif-1.00.a"
- reg : Must contain SPDIF core's registers location and length
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
The controller expects two clocks, the clock used for the AXI interface and
the clock used as the sampling rate reference clock sample.
- clock-names: "axi" for the clock to the AXI interface, "ref" for the sample
rate reference clock.
- dmas: Pairs of phandle and specifier for the DMA channel that is used by
the core. The core expects one dma channel for transmit.
- dma-names : Must be "tx"
For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
please check:
* resource-names.txt
* clock/clock-bindings.txt
* dma/dma.txt
Example:
spdif: spdif@0x77400000 {
compatible = "adi,axi-spdif-tx-1.00.a";
reg = <0x77600000 0x1000>;
clocks = <&clk 15>, <&audio_clock>;
clock-names = "axi", "ref";
dmas = <&ps7_dma 0>;
dma-names = "tx";
};
* Broadcom BCM2835 SoC I2S/PCM module
Required properties:
- compatible: "brcm,bcm2835-i2s"
- reg: A list of base address and size entries:
* The first entry should cover the PCM registers
* The second entry should cover the PCM clock registers
- dmas: List of DMA controller phandle and DMA request line ordered pairs.
- dma-names: Identifier string for each DMA request line in the dmas property.
These strings correspond 1:1 with the ordered pairs in dmas.
One of the DMA channels will be responsible for transmission (should be
named "tx") and one for reception (should be named "rx").
Example:
bcm2835_i2s: i2s@7e203000 {
compatible = "brcm,bcm2835-i2s";
reg = <0x7e203000 0x20>,
<0x7e101098 0x02>;
dmas = <&dma 2>,
<&dma 3>;
dma-names = "tx", "rx";
};
CS42L52 audio CODEC
Required properties:
- compatible : "cirrus,cs42l52"
- reg : the I2C address of the device for I2C
Optional properties:
- cirrus,reset-gpio : GPIO controller's phandle and the number
of the GPIO used to reset the codec.
- cirrus,chgfreq-divisor : Values used to set the Charge Pump Frequency.
Allowable values of 0x00 through 0x0F. These are raw values written to the
register, not the actual frequency. The frequency is determined by the following.
Frequency = (64xFs)/(N+2)
N = chgfreq_val
Fs = Sample Rate (variable)
- cirrus,mica-differential-cfg : boolean, If present, then the MICA input is configured
as a differential input. If not present then the MICA input is configured as
Single-ended input. Single-ended mode allows for MIC1 or MIC2 muxing for input.
- cirrus,micb-differential-cfg : boolean, If present, then the MICB input is configured
as a differential input. If not present then the MICB input is configured as
Single-ended input. Single-ended mode allows for MIC1 or MIC2 muxing for input.
- cirrus,micbias-lvl: Set the output voltage level on the MICBIAS Pin
0 = 0.5 x VA
1 = 0.6 x VA
2 = 0.7 x VA
3 = 0.8 x VA
4 = 0.83 x VA
5 = 0.91 x VA
Example:
codec: codec@4a {
compatible = "cirrus,cs42l52";
reg = <0x4a>;
reset-gpio = <&gpio 10 0>;
cirrus,chgfreq-divisor = <0x05>;
cirrus.mica-differential-cfg;
cirrus,micbias-lvl = <5>;
};
......@@ -4,7 +4,8 @@ Required properties:
- compatible :
"ti,dm646x-mcasp-audio" : for DM646x platforms
"ti,da830-mcasp-audio" : for both DA830 & DA850 platforms
"ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, TI81xx)
"ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx)
"ti,dra7-mcasp-audio" : for DRA7xx platforms
- reg : Should contain reg specifiers for the entries in the reg-names property.
- reg-names : Should contain:
......@@ -36,7 +37,8 @@ Optional properties:
- pinctrl-0: Should specify pin control group used for this controller.
- pinctrl-names: Should contain only one value - "default", for more details
please refer to pinctrl-bindings.txt
- fck_parent : Should contain a valid clock name which will be used as parent
for the McASP fck
Example:
......
Freescale Synchronous Audio Interface (SAI).
The SAI is based on I2S module that used communicating with audio codecs,
which provides a synchronous audio interface that supports fullduplex
serial interfaces with frame synchronization such as I2S, AC97, TDM, and
codec/DSP interfaces.
Required properties:
- compatible: Compatible list, contains "fsl,vf610-sai".
- reg: Offset and length of the register set for the device.
- clocks: Must contain an entry for each entry in clock-names.
- clock-names : Must include the "sai" entry.
- 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".
- pinctrl-names: Must contain a "default" entry.
- pinctrl-NNN: One property must exist for each entry in pinctrl-names.
See ../pinctrl/pinctrl-bindings.txt for details of the property values.
- big-endian-regs: If this property is absent, the little endian mode will
be in use as default, or the big endian mode will be in use for all the
device registers.
- big-endian-data: If this property is absent, the little endian mode will
be in use as default, or the big endian mode will be in use for all the
fifo data.
Example:
sai2: sai@40031000 {
compatible = "fsl,vf610-sai";
reg = <0x40031000 0x1000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai2_1>;
clocks = <&clks VF610_CLK_SAI2>;
clock-names = "sai";
dma-names = "tx", "rx";
dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>,
<&edma0 0 VF610_EDMA_MUXID0_SAI2_RX>;
big-endian-regs;
big-endian-data;
};
Device-Tree bindings for dummy HDMI codec
Required properties:
- compatible: should be "linux,hdmi-audio".
CODEC output pins:
* TX
CODEC input pins:
* RX
Example node:
hdmi_audio: hdmi_audio@0 {
compatible = "linux,hdmi-audio";
status = "okay";
};
MAX98090 audio CODEC
This device supports I2C only.
Required properties:
- compatible : "maxim,max98090".
- reg : The I2C address of the device.
- interrupts : The CODEC's interrupt output.
Pins on the device (for linking into audio routes):
* MIC1
* MIC2
* DMICL
* DMICR
* IN1
* IN2
* IN3
* IN4
* IN5
* IN6
* IN12
* IN34
* IN56
* HPL
* HPR
* SPKL
* SPKR
* RCVL
* RCVR
* MICBIAS
Example:
audio-codec@10 {
compatible = "maxim,max98090";
reg = <0x10>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
};
NVIDIA Tegra audio complex, with MAX98090 CODEC
Required properties:
- compatible : "nvidia,tegra-audio-max98090"
- clocks : Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names : Must include the following entries:
- pll_a
- pll_a_out0
- mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex.
- nvidia,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink,
the second being the connection's source. Valid names for sources and
sinks are the MAX98090's pins (as documented in its binding), and the jacks
on the board:
* Headphones
* Speakers
* Mic Jack
- nvidia,i2s-controller : The phandle of the Tegra I2S controller that's
connected to the CODEC.
- nvidia,audio-codec : The phandle of the MAX98090 audio codec.
Optional properties:
- nvidia,hp-det-gpios : The GPIO that detect headphones are plugged in
Example:
sound {
compatible = "nvidia,tegra-audio-max98090-venice2",
"nvidia,tegra-audio-max98090";
nvidia,model = "NVIDIA Tegra Venice2";
nvidia,audio-routing =
"Headphones", "HPR",
"Headphones", "HPL",
"Speakers", "SPKR",
"Speakers", "SPKL",
"Mic Jack", "MICBIAS",
"IN34", "Mic Jack";
nvidia,i2s-controller = <&tegra_i2s1>;
nvidia,audio-codec = <&acodec>;
clocks = <&tegra_car TEGRA124_CLK_PLL_A>,
<&tegra_car TEGRA124_CLK_PLL_A_OUT0>,
<&tegra_car TEGRA124_CLK_EXTERN1>;
clock-names = "pll_a", "pll_a_out0", "mclk";
};
......@@ -11,6 +11,11 @@ Optional properties:
- simple-audio-card,format : CPU/CODEC common audio format.
"i2s", "right_j", "left_j" , "dsp_a"
"dsp_b", "ac97", "pdm", "msb", "lsb"
- simple-audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the
connection's sink, the second being the connection's
source.
Required subnodes:
- simple-audio-card,cpu : CPU sub-node
......@@ -38,6 +43,10 @@ Example:
sound {
compatible = "simple-audio-card";
simple-audio-card,format = "left_j";
simple-audio-routing =
"MIC_IN", "Mic Jack",
"Headphone Jack", "HP_OUT",
"Ext Spk", "LINE_OUT";
simple-audio-card,cpu {
sound-dai = <&sh_fsi2 0>;
......
......@@ -723,6 +723,7 @@ config ARCH_S3C64XX
bool "Samsung S3C64XX"
select ARCH_HAS_CPUFREQ
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select ARM_VIC
select CLKDEV_LOOKUP
select CLKSRC_SAMSUNG_PWM
......
......@@ -17,9 +17,10 @@ config CPU_S3C6410
help
Enable S3C6410 CPU support
config S3C64XX_DMA
bool "S3C64XX DMA"
select S3C_DMA
config S3C64XX_PL080
bool "S3C64XX DMA using generic PL08x driver"
select AMBA_PL08X
select SAMSUNG_DMADEV
config S3C64XX_SETUP_SDHCI
bool
......
......@@ -26,7 +26,7 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle.o
# DMA support
obj-$(CONFIG_S3C64XX_DMA) += dma.o
obj-$(CONFIG_S3C64XX_PL080) += pl080.o
# Device support
......
......@@ -58,4 +58,9 @@ int __init s3c64xx_pm_late_initcall(void);
static inline int s3c64xx_pm_late_initcall(void) { return 0; }
#endif
#ifdef CONFIG_S3C64XX_PL080
extern struct pl08x_platform_data s3c64xx_dma0_plat_data;
extern struct pl08x_platform_data s3c64xx_dma1_plat_data;
#endif
#endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */
This diff is collapsed.
......@@ -11,51 +11,48 @@
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H __FILE__
#define S3C_DMA_CHANNELS (16)
#define S3C64XX_DMA_CHAN(name) ((unsigned long)(name))
/* DMA0/SDMA0 */
#define DMACH_UART0 S3C64XX_DMA_CHAN("uart0_tx")
#define DMACH_UART0_SRC2 S3C64XX_DMA_CHAN("uart0_rx")
#define DMACH_UART1 S3C64XX_DMA_CHAN("uart1_tx")
#define DMACH_UART1_SRC2 S3C64XX_DMA_CHAN("uart1_rx")
#define DMACH_UART2 S3C64XX_DMA_CHAN("uart2_tx")
#define DMACH_UART2_SRC2 S3C64XX_DMA_CHAN("uart2_rx")
#define DMACH_UART3 S3C64XX_DMA_CHAN("uart3_tx")
#define DMACH_UART3_SRC2 S3C64XX_DMA_CHAN("uart3_rx")
#define DMACH_PCM0_TX S3C64XX_DMA_CHAN("pcm0_tx")
#define DMACH_PCM0_RX S3C64XX_DMA_CHAN("pcm0_rx")
#define DMACH_I2S0_OUT S3C64XX_DMA_CHAN("i2s0_tx")
#define DMACH_I2S0_IN S3C64XX_DMA_CHAN("i2s0_rx")
#define DMACH_SPI0_TX S3C64XX_DMA_CHAN("spi0_tx")
#define DMACH_SPI0_RX S3C64XX_DMA_CHAN("spi0_rx")
#define DMACH_HSI_I2SV40_TX S3C64XX_DMA_CHAN("i2s2_tx")
#define DMACH_HSI_I2SV40_RX S3C64XX_DMA_CHAN("i2s2_rx")
/* DMA1/SDMA1 */
#define DMACH_PCM1_TX S3C64XX_DMA_CHAN("pcm1_tx")
#define DMACH_PCM1_RX S3C64XX_DMA_CHAN("pcm1_rx")
#define DMACH_I2S1_OUT S3C64XX_DMA_CHAN("i2s1_tx")
#define DMACH_I2S1_IN S3C64XX_DMA_CHAN("i2s1_rx")
#define DMACH_SPI1_TX S3C64XX_DMA_CHAN("spi1_tx")
#define DMACH_SPI1_RX S3C64XX_DMA_CHAN("spi1_rx")
#define DMACH_AC97_PCMOUT S3C64XX_DMA_CHAN("ac97_out")
#define DMACH_AC97_PCMIN S3C64XX_DMA_CHAN("ac97_in")
#define DMACH_AC97_MICIN S3C64XX_DMA_CHAN("ac97_mic")
#define DMACH_PWM S3C64XX_DMA_CHAN("pwm")
#define DMACH_IRDA S3C64XX_DMA_CHAN("irda")
#define DMACH_EXTERNAL S3C64XX_DMA_CHAN("external")
#define DMACH_SECURITY_RX S3C64XX_DMA_CHAN("sec_rx")
#define DMACH_SECURITY_TX S3C64XX_DMA_CHAN("sec_tx")
/* see mach-s3c2410/dma.h for notes on dma channel numbers */
/* Note, for the S3C64XX architecture we keep the DMACH_
* defines in the order they are allocated to [S]DMA0/[S]DMA1
* so that is easy to do DHACH_ -> DMA controller conversion
*/
enum dma_ch {
/* DMA0/SDMA0 */
DMACH_UART0 = 0,
DMACH_UART0_SRC2,
DMACH_UART1,
DMACH_UART1_SRC2,
DMACH_UART2,
DMACH_UART2_SRC2,
DMACH_UART3,
DMACH_UART3_SRC2,
DMACH_PCM0_TX,
DMACH_PCM0_RX,
DMACH_I2S0_OUT,
DMACH_I2S0_IN,
DMACH_SPI0_TX,
DMACH_SPI0_RX,
DMACH_HSI_I2SV40_TX,
DMACH_HSI_I2SV40_RX,
DMACH_MAX = 32
};
/* DMA1/SDMA1 */
DMACH_PCM1_TX = 16,
DMACH_PCM1_RX,
DMACH_I2S1_OUT,
DMACH_I2S1_IN,
DMACH_SPI1_TX,
DMACH_SPI1_RX,
DMACH_AC97_PCMOUT,
DMACH_AC97_PCMIN,
DMACH_AC97_MICIN,
DMACH_PWM,
DMACH_IRDA,
DMACH_EXTERNAL,
DMACH_RES1,
DMACH_RES2,
DMACH_SECURITY_RX, /* SDMA1 only */
DMACH_SECURITY_TX, /* SDMA1 only */
DMACH_MAX /* the end */
struct s3c2410_dma_client {
char *name;
};
static inline bool samsung_dma_has_circular(void)
......@@ -65,67 +62,10 @@ static inline bool samsung_dma_has_circular(void)
static inline bool samsung_dma_is_dmadev(void)
{
return false;
return true;
}
#define S3C2410_DMAF_CIRCULAR (1 << 0)
#include <plat/dma.h>
#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
struct s3c64xx_dma_buff;
/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor
* @next: Pointer to next buffer in queue or ring.
* @pw: Client provided identifier
* @lli: Pointer to hardware descriptor this buffer is associated with.
* @lli_dma: Hardare address of the descriptor.
*/
struct s3c64xx_dma_buff {
struct s3c64xx_dma_buff *next;
void *pw;
struct pl080s_lli *lli;
dma_addr_t lli_dma;
};
struct s3c64xx_dmac;
struct s3c2410_dma_chan {
unsigned char number; /* number of this dma channel */
unsigned char in_use; /* channel allocated */
unsigned char bit; /* bit for enable/disable/etc */
unsigned char hw_width;
unsigned char peripheral;
unsigned int flags;
enum dma_data_direction source;
dma_addr_t dev_addr;
struct s3c2410_dma_client *client;
struct s3c64xx_dmac *dmac; /* pointer to controller */
void __iomem *regs;
/* cdriver callbacks */
s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
s3c2410_dma_opfn_t op_fn; /* channel op callback */
/* buffer list and information */
struct s3c64xx_dma_buff *curr; /* current dma buffer */
struct s3c64xx_dma_buff *next; /* next buffer to load */
struct s3c64xx_dma_buff *end; /* end of queue */
/* note, when channel is running in circular mode, curr is the
* first buffer enqueued, end is the last and curr is where the
* last buffer-done event is set-at. The buffers are not freed
* and the last buffer hardware descriptor points back to the
* first.
*/
};
#include <plat/dma-core.h>
#include <linux/amba/pl08x.h>
#include <plat/dma-ops.h>
#endif /* __ASM_ARCH_IRQ_H */
/*
* Samsung's S3C64XX generic DMA support using amba-pl08x driver.
*
* Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl080.h>
#include <linux/amba/pl08x.h>
#include <linux/of.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include "regs-sys.h"
static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd)
{
return cd->min_signal;
}
static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch)
{
}
/*
* DMA0
*/
static struct pl08x_channel_data s3c64xx_dma0_info[] = {
{
.bus_id = "uart0_tx",
.min_signal = 0,
.max_signal = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart0_rx",
.min_signal = 1,
.max_signal = 1,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart1_tx",
.min_signal = 2,
.max_signal = 2,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart1_rx",
.min_signal = 3,
.max_signal = 3,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart2_tx",
.min_signal = 4,
.max_signal = 4,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart2_rx",
.min_signal = 5,
.max_signal = 5,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart3_tx",
.min_signal = 6,
.max_signal = 6,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart3_rx",
.min_signal = 7,
.max_signal = 7,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "pcm0_tx",
.min_signal = 8,
.max_signal = 8,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "pcm0_rx",
.min_signal = 9,
.max_signal = 9,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s0_tx",
.min_signal = 10,
.max_signal = 10,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s0_rx",
.min_signal = 11,
.max_signal = 11,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "spi0_tx",
.min_signal = 12,
.max_signal = 12,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "spi0_rx",
.min_signal = 13,
.max_signal = 13,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s2_tx",
.min_signal = 14,
.max_signal = 14,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s2_rx",
.min_signal = 15,
.max_signal = 15,
.periph_buses = PL08X_AHB2,
}
};
struct pl08x_platform_data s3c64xx_dma0_plat_data = {
.memcpy_channel = {
.bus_id = "memcpy",
.cctl_memcpy =
(PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT |
PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT |
PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT |
PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT |
PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
PL080_CONTROL_PROT_SYS),
},
.lli_buses = PL08X_AHB1,
.mem_buses = PL08X_AHB1,
.get_xfer_signal = pl08x_get_xfer_signal,
.put_xfer_signal = pl08x_put_xfer_signal,
.slave_channels = s3c64xx_dma0_info,
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info),
};
static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data);
/*
* DMA1
*/
static struct pl08x_channel_data s3c64xx_dma1_info[] = {
{
.bus_id = "pcm1_tx",
.min_signal = 0,
.max_signal = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "pcm1_rx",
.min_signal = 1,
.max_signal = 1,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s1_tx",
.min_signal = 2,
.max_signal = 2,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s1_rx",
.min_signal = 3,
.max_signal = 3,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "spi1_tx",
.min_signal = 4,
.max_signal = 4,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "spi1_rx",
.min_signal = 5,
.max_signal = 5,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ac97_out",
.min_signal = 6,
.max_signal = 6,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ac97_in",
.min_signal = 7,
.max_signal = 7,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ac97_mic",
.min_signal = 8,
.max_signal = 8,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "pwm",
.min_signal = 9,
.max_signal = 9,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "irda",
.min_signal = 10,
.max_signal = 10,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "external",
.min_signal = 11,
.max_signal = 11,
.periph_buses = PL08X_AHB2,
},
};
struct pl08x_platform_data s3c64xx_dma1_plat_data = {
.memcpy_channel = {
.bus_id = "memcpy",
.cctl_memcpy =
(PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT |
PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT |
PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT |
PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT |
PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
PL080_CONTROL_PROT_SYS),
},
.lli_buses = PL08X_AHB1,
.mem_buses = PL08X_AHB1,
.get_xfer_signal = pl08x_get_xfer_signal,
.put_xfer_signal = pl08x_put_xfer_signal,
.slave_channels = s3c64xx_dma1_info,
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info),
};
static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data);
static int __init s3c64xx_pl080_init(void)
{
/* Set all DMA configuration to be DMA, not SDMA */
writel(0xffffff, S3C64XX_SDMA_SEL);
if (of_have_populated_dt())
return 0;
amba_device_register(&s3c64xx_dma0_device, &iomem_resource);
amba_device_register(&s3c64xx_dma1_device, &iomem_resource);
return 0;
}
arch_initcall(s3c64xx_pl080_init);
......@@ -1468,6 +1468,8 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
#if defined(CONFIG_PL330_DMA)
pd.filter = pl330_filter;
#elif defined(CONFIG_S3C64XX_PL080)
pd.filter = pl08x_filter_id;
#elif defined(CONFIG_S3C24XX_DMAC)
pd.filter = s3c24xx_dma_filter;
#endif
......@@ -1509,8 +1511,10 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
#ifdef CONFIG_PL330_DMA
#if defined(CONFIG_PL330_DMA)
pd.filter = pl330_filter;
#elif defined(CONFIG_S3C64XX_PL080)
pd.filter = pl08x_filter_id;
#endif
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1);
......@@ -1550,8 +1554,10 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
#ifdef CONFIG_PL330_DMA
#if defined(CONFIG_PL330_DMA)
pd.filter = pl330_filter;
#elif defined(CONFIG_S3C64XX_PL080)
pd.filter = pl08x_filter_id;
#endif
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2);
......
......@@ -18,6 +18,12 @@
#include <mach/dma.h>
#if defined(CONFIG_PL330_DMA)
#define dma_filter pl330_filter
#elif defined(CONFIG_S3C64XX_PL080)
#define dma_filter pl08x_filter_id
#endif
static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
struct samsung_dma_req *param,
struct device *dev, char *ch_name)
......@@ -30,7 +36,7 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
if (dev->of_node)
return (unsigned)dma_request_slave_channel(dev, ch_name);
else
return (unsigned)dma_request_channel(mask, pl330_filter,
return (unsigned)dma_request_channel(mask, dma_filter,
(void *)dma_ch);
}
......
......@@ -331,8 +331,8 @@ static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
ALIAS(HCLK_DMA1, NULL, "dma1"),
ALIAS(HCLK_DMA0, NULL, "dma0"),
ALIAS(HCLK_DMA1, "dma-pl080s.1", "apb_pclk"),
ALIAS(HCLK_DMA0, "dma-pl080s.0", "apb_pclk"),
ALIAS(HCLK_CAMIF, "s3c-camif", "camif"),
ALIAS(HCLK_LCD, "s3c-fb", "lcd"),
ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"),
......
......@@ -44,6 +44,54 @@
#define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
#define TWL6040_NUM_SUPPLIES (2)
static struct reg_default twl6040_defaults[] = {
{ 0x01, 0x4B }, /* REG_ASICID (ro) */
{ 0x02, 0x00 }, /* REG_ASICREV (ro) */
{ 0x03, 0x00 }, /* REG_INTID */
{ 0x04, 0x00 }, /* REG_INTMR */
{ 0x05, 0x00 }, /* REG_NCPCTRL */
{ 0x06, 0x00 }, /* REG_LDOCTL */
{ 0x07, 0x60 }, /* REG_HPPLLCTL */
{ 0x08, 0x00 }, /* REG_LPPLLCTL */
{ 0x09, 0x4A }, /* REG_LPPLLDIV */
{ 0x0A, 0x00 }, /* REG_AMICBCTL */
{ 0x0B, 0x00 }, /* REG_DMICBCTL */
{ 0x0C, 0x00 }, /* REG_MICLCTL */
{ 0x0D, 0x00 }, /* REG_MICRCTL */
{ 0x0E, 0x00 }, /* REG_MICGAIN */
{ 0x0F, 0x1B }, /* REG_LINEGAIN */
{ 0x10, 0x00 }, /* REG_HSLCTL */
{ 0x11, 0x00 }, /* REG_HSRCTL */
{ 0x12, 0x00 }, /* REG_HSGAIN */
{ 0x13, 0x00 }, /* REG_EARCTL */
{ 0x14, 0x00 }, /* REG_HFLCTL */
{ 0x15, 0x00 }, /* REG_HFLGAIN */
{ 0x16, 0x00 }, /* REG_HFRCTL */
{ 0x17, 0x00 }, /* REG_HFRGAIN */
{ 0x18, 0x00 }, /* REG_VIBCTLL */
{ 0x19, 0x00 }, /* REG_VIBDATL */
{ 0x1A, 0x00 }, /* REG_VIBCTLR */
{ 0x1B, 0x00 }, /* REG_VIBDATR */
{ 0x1C, 0x00 }, /* REG_HKCTL1 */
{ 0x1D, 0x00 }, /* REG_HKCTL2 */
{ 0x1E, 0x00 }, /* REG_GPOCTL */
{ 0x1F, 0x00 }, /* REG_ALB */
{ 0x20, 0x00 }, /* REG_DLB */
/* 0x28, REG_TRIM1 */
/* 0x29, REG_TRIM2 */
/* 0x2A, REG_TRIM3 */
/* 0x2B, REG_HSOTRIM */
/* 0x2C, REG_HFOTRIM */
{ 0x2D, 0x08 }, /* REG_ACCCTL */
{ 0x2E, 0x00 }, /* REG_STATUS (ro) */
};
struct reg_default twl6040_patch[] = {
/* Select I2C bus access to dual access registers */
{ TWL6040_REG_ACCCTL, 0x09 },
};
static bool twl6040_has_vibra(struct device_node *node)
{
#ifdef CONFIG_OF
......@@ -238,6 +286,9 @@ int twl6040_power(struct twl6040 *twl6040, int on)
if (twl6040->power_count++)
goto out;
/* Allow writes to the chip */
regcache_cache_only(twl6040->regmap, false);
if (gpio_is_valid(twl6040->audpwron)) {
/* use automatic power-up sequence */
ret = twl6040_power_up_automatic(twl6040);
......@@ -253,6 +304,10 @@ int twl6040_power(struct twl6040 *twl6040, int on)
goto out;
}
}
/* Sync with the HW */
regcache_sync(twl6040->regmap);
/* Default PLL configuration after power up */
twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
twl6040->sysclk = 19200000;
......@@ -279,6 +334,11 @@ int twl6040_power(struct twl6040 *twl6040, int on)
/* use manual power-down sequence */
twl6040_power_down_manual(twl6040);
}
/* Set regmap to cache only and mark it as dirty */
regcache_cache_only(twl6040->regmap, true);
regcache_mark_dirty(twl6040->regmap);
twl6040->sysclk = 0;
twl6040->mclk = 0;
}
......@@ -490,9 +550,24 @@ static bool twl6040_readable_reg(struct device *dev, unsigned int reg)
static bool twl6040_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case TWL6040_REG_VIBCTLL:
case TWL6040_REG_VIBCTLR:
case TWL6040_REG_INTMR:
case TWL6040_REG_ASICID:
case TWL6040_REG_ASICREV:
case TWL6040_REG_INTID:
case TWL6040_REG_LPPLLCTL:
case TWL6040_REG_HPPLLCTL:
case TWL6040_REG_STATUS:
return true;
default:
return false;
}
}
static bool twl6040_writeable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case TWL6040_REG_ASICID:
case TWL6040_REG_ASICREV:
case TWL6040_REG_STATUS:
return false;
default:
return true;
......@@ -502,10 +577,15 @@ static bool twl6040_volatile_reg(struct device *dev, unsigned int reg)
static struct regmap_config twl6040_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.reg_defaults = twl6040_defaults,
.num_reg_defaults = ARRAY_SIZE(twl6040_defaults),
.max_register = TWL6040_REG_STATUS, /* 0x2e */
.readable_reg = twl6040_readable_reg,
.volatile_reg = twl6040_volatile_reg,
.writeable_reg = twl6040_writeable_reg,
.cache_type = REGCACHE_RBTREE,
};
......@@ -624,6 +704,8 @@ static int twl6040_probe(struct i2c_client *client,
/* dual-access registers controlled by I2C only */
twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL);
regmap_register_patch(twl6040->regmap, twl6040_patch,
ARRAY_SIZE(twl6040_patch));
/*
* The main functionality of twl6040 to provide audio on OMAP4+ systems.
......@@ -656,6 +738,10 @@ static int twl6040_probe(struct i2c_client *client,
cell->name = "twl6040-gpo";
children++;
/* The chip is powered down so mark regmap to cache only and dirty */
regcache_cache_only(twl6040->regmap, true);
regcache_mark_dirty(twl6040->regmap);
ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
NULL, 0, NULL);
if (ret)
......
This diff is collapsed.
......@@ -395,7 +395,7 @@ config SPI_S3C24XX_FIQ
config SPI_S3C64XX
tristate "Samsung S3C64XX series type SPI"
depends on PLAT_SAMSUNG
select S3C64XX_DMA if ARCH_S3C64XX
select S3C64XX_PL080 if ARCH_S3C64XX
help
SPI driver for Samsung S3C64XX and newer SoCs.
......
This diff is collapsed.
/*
* arch/arm/plat-omap/include/mach/mcbsp.h
*
* Defines for Multi-Channel Buffered Serial Port
*
* Copyright (C) 2002 RidgeRun, Inc.
......@@ -21,8 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __ASM_ARCH_OMAP_MCBSP_H
#define __ASM_ARCH_OMAP_MCBSP_H
#ifndef __ASOC_TI_MCBSP_H
#define __ASOC_TI_MCBSP_H
#include <linux/spinlock.h>
#include <linux/clk.h>
......
......@@ -92,6 +92,7 @@ enum {
MCASP_VERSION_1 = 0, /* DM646x */
MCASP_VERSION_2, /* DA8xx/OMAPL1x */
MCASP_VERSION_3, /* TI81xx/AM33xx */
MCASP_VERSION_4, /* DRA7xxx */
};
enum mcbsp_clk_input_pin {
......
......@@ -16,17 +16,11 @@ struct cs42l52_platform_data {
/* MICBIAS Level. Check datasheet Pg48 */
unsigned int micbias_lvl;
/* MICA mode selection 0=Single 1=Differential */
unsigned int mica_cfg;
/* MICA mode selection Differential or Single-ended */
bool mica_diff_cfg;
/* MICB mode selection 0=Single 1=Differential */
unsigned int micb_cfg;
/* MICA Select 0=MIC1A 1=MIC2A */
unsigned int mica_sel;
/* MICB Select 0=MIC2A 1=MIC2B */
unsigned int micb_sel;
/* MICB mode selection Differential or Single-ended */
bool micb_diff_cfg;
/* Charge Pump Freq. Check datasheet Pg73 */
unsigned int chgfreq;
......
......@@ -354,4 +354,16 @@ params_period_bytes(const struct snd_pcm_hw_params *p)
params_channels(p)) / 8;
}
static inline int
params_width(const struct snd_pcm_hw_params *p)
{
return snd_pcm_format_width(params_format(p));
}
static inline int
params_physical_width(const struct snd_pcm_hw_params *p)
{
return snd_pcm_format_physical_width(params_format(p));
}
#endif /* __SOUND_PCM_PARAMS_H */
......@@ -18,7 +18,7 @@
#define RSND_GEN1_ADG 1
#define RSND_GEN1_SSI 2
#define RSND_GEN2_SRU 0
#define RSND_GEN2_SCU 0
#define RSND_GEN2_ADG 1
#define RSND_GEN2_SSIU 2
#define RSND_GEN2_SSI 3
......@@ -58,6 +58,7 @@ struct rsnd_ssi_platform_info {
struct rsnd_scu_platform_info {
u32 flags;
u32 convert_rate; /* sampling rate convert */
};
/*
......
......@@ -334,9 +334,7 @@ struct snd_soc_jack_pin;
#include <sound/soc-dapm.h>
#include <sound/soc-dpcm.h>
#ifdef CONFIG_GPIOLIB
struct snd_soc_jack_gpio;
#endif
typedef int (*hw_write_t)(void *,const char* ,int);
......@@ -446,6 +444,17 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_gpio *gpios);
void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_gpio *gpios);
#else
static inline int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_gpio *gpios)
{
return 0;
}
static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_gpio *gpios)
{
}
#endif
/* codec register bit access */
......@@ -580,7 +589,6 @@ struct snd_soc_jack_zone {
* to provide more complex checks (eg, reading an
* ADC).
*/
#ifdef CONFIG_GPIOLIB
struct snd_soc_jack_gpio {
unsigned int gpio;
const char *name;
......@@ -594,7 +602,6 @@ struct snd_soc_jack_gpio {
int (*jack_status_check)(void);
};
#endif
struct snd_soc_jack {
struct mutex mutex;
......
......@@ -29,7 +29,6 @@ struct spear_dma_data {
dma_addr_t addr;
u32 max_burst;
enum dma_slave_buswidth addr_width;
bool (*filter)(struct dma_chan *chan, void *slave);
};
#endif /* SPEAR_DMA_H */
......@@ -31,8 +31,10 @@ config SND_SOC_GENERIC_DMAENGINE_PCM
select SND_DMAENGINE_PCM
# All the supported SoCs
source "sound/soc/adi/Kconfig"
source "sound/soc/atmel/Kconfig"
source "sound/soc/au1x/Kconfig"
source "sound/soc/bcm/Kconfig"
source "sound/soc/blackfin/Kconfig"
source "sound/soc/cirrus/Kconfig"
source "sound/soc/davinci/Kconfig"
......@@ -42,7 +44,7 @@ source "sound/soc/jz4740/Kconfig"
source "sound/soc/nuc900/Kconfig"
source "sound/soc/omap/Kconfig"
source "sound/soc/kirkwood/Kconfig"
source "sound/soc/mid-x86/Kconfig"
source "sound/soc/intel/Kconfig"
source "sound/soc/mxs/Kconfig"
source "sound/soc/pxa/Kconfig"
source "sound/soc/samsung/Kconfig"
......
......@@ -8,15 +8,17 @@ endif
obj-$(CONFIG_SND_SOC) += snd-soc-core.o
obj-$(CONFIG_SND_SOC) += codecs/
obj-$(CONFIG_SND_SOC) += generic/
obj-$(CONFIG_SND_SOC) += adi/
obj-$(CONFIG_SND_SOC) += atmel/
obj-$(CONFIG_SND_SOC) += au1x/
obj-$(CONFIG_SND_SOC) += bcm/
obj-$(CONFIG_SND_SOC) += blackfin/
obj-$(CONFIG_SND_SOC) += cirrus/
obj-$(CONFIG_SND_SOC) += davinci/
obj-$(CONFIG_SND_SOC) += dwc/
obj-$(CONFIG_SND_SOC) += fsl/
obj-$(CONFIG_SND_SOC) += jz4740/
obj-$(CONFIG_SND_SOC) += mid-x86/
obj-$(CONFIG_SND_SOC) += intel/
obj-$(CONFIG_SND_SOC) += mxs/
obj-$(CONFIG_SND_SOC) += nuc900/
obj-$(CONFIG_SND_SOC) += omap/
......
config SND_SOC_ADI
tristate "Audio support for Analog Devices reference designs"
depends on MICROBLAZE || ARCH_ZYNQ || COMPILE_TEST
help
Audio support for various reference designs by Analog Devices.
config SND_SOC_ADI_AXI_I2S
tristate "AXI-I2S support"
depends on SND_SOC_ADI
select SND_SOC_GENERIC_DMAENGINE_PCM
select REGMAP_MMIO
help
ASoC driver for the Analog Devices AXI-I2S softcore peripheral.
config SND_SOC_ADI_AXI_SPDIF
tristate "AXI-SPDIF support"
depends on SND_SOC_ADI
select SND_SOC_GENERIC_DMAENGINE_PCM
select REGMAP_MMIO
help
ASoC driver for the Analog Devices AXI-SPDIF softcore peripheral.
snd-soc-adi-axi-i2s-objs := axi-i2s.o
snd-soc-adi-axi-spdif-objs := axi-spdif.o
obj-$(CONFIG_SND_SOC_ADI_AXI_I2S) += snd-soc-adi-axi-i2s.o
obj-$(CONFIG_SND_SOC_ADI_AXI_SPDIF) += snd-soc-adi-axi-spdif.o
/*
* Copyright (C) 2012-2013, Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2.
*/
#include <linux/clk.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>
#define AXI_I2S_REG_RESET 0x00
#define AXI_I2S_REG_CTRL 0x04
#define AXI_I2S_REG_CLK_CTRL 0x08
#define AXI_I2S_REG_STATUS 0x10
#define AXI_I2S_REG_RX_FIFO 0x28
#define AXI_I2S_REG_TX_FIFO 0x2C
#define AXI_I2S_RESET_GLOBAL BIT(0)
#define AXI_I2S_RESET_TX_FIFO BIT(1)
#define AXI_I2S_RESET_RX_FIFO BIT(2)
#define AXI_I2S_CTRL_TX_EN BIT(0)
#define AXI_I2S_CTRL_RX_EN BIT(1)
/* The frame size is configurable, but for now we always set it 64 bit */
#define AXI_I2S_BITS_PER_FRAME 64
struct axi_i2s {
struct regmap *regmap;
struct clk *clk;
struct clk *clk_ref;
struct snd_soc_dai_driver dai_driver;
struct snd_dmaengine_dai_dma_data capture_dma_data;
struct snd_dmaengine_dai_dma_data playback_dma_data;
struct snd_ratnum ratnum;
struct snd_pcm_hw_constraint_ratnums rate_constraints;
};
static int axi_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai);
unsigned int mask, val;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
mask = AXI_I2S_CTRL_RX_EN;
else
mask = AXI_I2S_CTRL_TX_EN;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
val = mask;
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
val = 0;
break;
default:
return -EINVAL;
}
regmap_update_bits(i2s->regmap, AXI_I2S_REG_CTRL, mask, val);
return 0;
}
static int axi_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai);
unsigned int bclk_div, word_size;
unsigned int bclk_rate;
bclk_rate = params_rate(params) * AXI_I2S_BITS_PER_FRAME;
word_size = AXI_I2S_BITS_PER_FRAME / 2 - 1;
bclk_div = DIV_ROUND_UP(clk_get_rate(i2s->clk_ref), bclk_rate) / 2 - 1;
regmap_write(i2s->regmap, AXI_I2S_REG_CLK_CTRL, (word_size << 16) |
bclk_div);
return 0;
}
static int axi_i2s_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai);
uint32_t mask;
int ret;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
mask = AXI_I2S_RESET_RX_FIFO;
else
mask = AXI_I2S_RESET_TX_FIFO;
regmap_write(i2s->regmap, AXI_I2S_REG_RESET, mask);
ret = snd_pcm_hw_constraint_ratnums(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&i2s->rate_constraints);
if (ret)
return ret;
return clk_prepare_enable(i2s->clk_ref);
}
static void axi_i2s_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai);
clk_disable_unprepare(i2s->clk_ref);
}
static int axi_i2s_dai_probe(struct snd_soc_dai *dai)
{
struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai);
snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
&i2s->capture_dma_data);
return 0;
}
static const struct snd_soc_dai_ops axi_i2s_dai_ops = {
.startup = axi_i2s_startup,
.shutdown = axi_i2s_shutdown,
.trigger = axi_i2s_trigger,
.hw_params = axi_i2s_hw_params,
};
static struct snd_soc_dai_driver axi_i2s_dai = {
.probe = axi_i2s_dai_probe,
.playback = {
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE,
},
.capture = {
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE,
},
.ops = &axi_i2s_dai_ops,
.symmetric_rates = 1,
};
static const struct snd_soc_component_driver axi_i2s_component = {
.name = "axi-i2s",
};
static const struct regmap_config axi_i2s_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = AXI_I2S_REG_STATUS,
};
static int axi_i2s_probe(struct platform_device *pdev)
{
struct resource *res;
struct axi_i2s *i2s;
void __iomem *base;
int ret;
i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
if (!i2s)
return -ENOMEM;
platform_set_drvdata(pdev, i2s);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
i2s->regmap = devm_regmap_init_mmio(&pdev->dev, base,
&axi_i2s_regmap_config);
if (IS_ERR(i2s->regmap))
return PTR_ERR(i2s->regmap);
i2s->clk = devm_clk_get(&pdev->dev, "axi");
if (IS_ERR(i2s->clk))
return PTR_ERR(i2s->clk);
i2s->clk_ref = devm_clk_get(&pdev->dev, "ref");
if (IS_ERR(i2s->clk_ref))
return PTR_ERR(i2s->clk_ref);
ret = clk_prepare_enable(i2s->clk);
if (ret)
return ret;
i2s->playback_dma_data.addr = res->start + AXI_I2S_REG_TX_FIFO;
i2s->playback_dma_data.addr_width = 4;
i2s->playback_dma_data.maxburst = 1;
i2s->capture_dma_data.addr = res->start + AXI_I2S_REG_RX_FIFO;
i2s->capture_dma_data.addr_width = 4;
i2s->capture_dma_data.maxburst = 1;
i2s->ratnum.num = clk_get_rate(i2s->clk_ref) / 2 / AXI_I2S_BITS_PER_FRAME;
i2s->ratnum.den_step = 1;
i2s->ratnum.den_min = 1;
i2s->ratnum.den_max = 64;
i2s->rate_constraints.rats = &i2s->ratnum;
i2s->rate_constraints.nrats = 1;
regmap_write(i2s->regmap, AXI_I2S_REG_RESET, AXI_I2S_RESET_GLOBAL);
ret = devm_snd_soc_register_component(&pdev->dev, &axi_i2s_component,
&axi_i2s_dai, 1);
if (ret)
goto err_clk_disable;
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
if (ret)
goto err_clk_disable;
err_clk_disable:
clk_disable_unprepare(i2s->clk);
return ret;
}
static int axi_i2s_dev_remove(struct platform_device *pdev)
{
struct axi_i2s *i2s = platform_get_drvdata(pdev);
clk_disable_unprepare(i2s->clk);
return 0;
}
static const struct of_device_id axi_i2s_of_match[] = {
{ .compatible = "adi,axi-i2s-1.00.a", },
{},
};
MODULE_DEVICE_TABLE(of, axi_i2s_of_match);
static struct platform_driver axi_i2s_driver = {
.driver = {
.name = "axi-i2s",
.owner = THIS_MODULE,
.of_match_table = axi_i2s_of_match,
},
.probe = axi_i2s_probe,
.remove = axi_i2s_dev_remove,
};
module_platform_driver(axi_i2s_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("AXI I2S driver");
MODULE_LICENSE("GPL");
/*
* Copyright (C) 2012-2013, Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/dmaengine_pcm.h>
#define AXI_SPDIF_REG_CTRL 0x0
#define AXI_SPDIF_REG_STAT 0x4
#define AXI_SPDIF_REG_TX_FIFO 0xc
#define AXI_SPDIF_CTRL_TXDATA BIT(1)
#define AXI_SPDIF_CTRL_TXEN BIT(0)
#define AXI_SPDIF_CTRL_CLKDIV_OFFSET 8
#define AXI_SPDIF_CTRL_CLKDIV_MASK (0xff << 8)
#define AXI_SPDIF_FREQ_44100 (0x0 << 6)
#define AXI_SPDIF_FREQ_48000 (0x1 << 6)
#define AXI_SPDIF_FREQ_32000 (0x2 << 6)
#define AXI_SPDIF_FREQ_NA (0x3 << 6)
struct axi_spdif {
struct regmap *regmap;
struct clk *clk;
struct clk *clk_ref;
struct snd_dmaengine_dai_dma_data dma_data;
struct snd_ratnum ratnum;
struct snd_pcm_hw_constraint_ratnums rate_constraints;
};
static int axi_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai);
unsigned int val;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
val = AXI_SPDIF_CTRL_TXDATA;
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
val = 0;
break;
default:
return -EINVAL;
}
regmap_update_bits(spdif->regmap, AXI_SPDIF_REG_CTRL,
AXI_SPDIF_CTRL_TXDATA, val);
return 0;
}
static int axi_spdif_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai);
unsigned int rate = params_rate(params);
unsigned int clkdiv, stat;
switch (params_rate(params)) {
case 32000:
stat = AXI_SPDIF_FREQ_32000;
break;
case 44100:
stat = AXI_SPDIF_FREQ_44100;
break;
case 48000:
stat = AXI_SPDIF_FREQ_48000;
break;
default:
stat = AXI_SPDIF_FREQ_NA;
break;
}
clkdiv = DIV_ROUND_CLOSEST(clk_get_rate(spdif->clk_ref),
rate * 64 * 2) - 1;
clkdiv <<= AXI_SPDIF_CTRL_CLKDIV_OFFSET;
regmap_write(spdif->regmap, AXI_SPDIF_REG_STAT, stat);
regmap_update_bits(spdif->regmap, AXI_SPDIF_REG_CTRL,
AXI_SPDIF_CTRL_CLKDIV_MASK, clkdiv);
return 0;
}
static int axi_spdif_dai_probe(struct snd_soc_dai *dai)
{
struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai);
snd_soc_dai_init_dma_data(dai, &spdif->dma_data, NULL);
return 0;
}
static int axi_spdif_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai);
int ret;
ret = snd_pcm_hw_constraint_ratnums(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&spdif->rate_constraints);
if (ret)
return ret;
ret = clk_prepare_enable(spdif->clk_ref);
if (ret)
return ret;
regmap_update_bits(spdif->regmap, AXI_SPDIF_REG_CTRL,
AXI_SPDIF_CTRL_TXEN, AXI_SPDIF_CTRL_TXEN);
return 0;
}
static void axi_spdif_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai);
regmap_update_bits(spdif->regmap, AXI_SPDIF_REG_CTRL,
AXI_SPDIF_CTRL_TXEN, 0);
clk_disable_unprepare(spdif->clk_ref);
}
static const struct snd_soc_dai_ops axi_spdif_dai_ops = {
.startup = axi_spdif_startup,
.shutdown = axi_spdif_shutdown,
.trigger = axi_spdif_trigger,
.hw_params = axi_spdif_hw_params,
};
static struct snd_soc_dai_driver axi_spdif_dai = {
.probe = axi_spdif_dai_probe,
.playback = {
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
.ops = &axi_spdif_dai_ops,
};
static const struct snd_soc_component_driver axi_spdif_component = {
.name = "axi-spdif",
};
static const struct regmap_config axi_spdif_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = AXI_SPDIF_REG_STAT,
};
static int axi_spdif_probe(struct platform_device *pdev)
{
struct axi_spdif *spdif;
struct resource *res;
void __iomem *base;
int ret;
spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
if (!spdif)
return -ENOMEM;
platform_set_drvdata(pdev, spdif);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
spdif->regmap = devm_regmap_init_mmio(&pdev->dev, base,
&axi_spdif_regmap_config);
if (IS_ERR(spdif->regmap))
return PTR_ERR(spdif->regmap);
spdif->clk = devm_clk_get(&pdev->dev, "axi");
if (IS_ERR(spdif->clk))
return PTR_ERR(spdif->clk);
spdif->clk_ref = devm_clk_get(&pdev->dev, "ref");
if (IS_ERR(spdif->clk_ref))
return PTR_ERR(spdif->clk_ref);
ret = clk_prepare_enable(spdif->clk);
if (ret)
return ret;
spdif->dma_data.addr = res->start + AXI_SPDIF_REG_TX_FIFO;
spdif->dma_data.addr_width = 4;
spdif->dma_data.maxburst = 1;
spdif->ratnum.num = clk_get_rate(spdif->clk_ref) / 128;
spdif->ratnum.den_step = 1;
spdif->ratnum.den_min = 1;
spdif->ratnum.den_max = 64;
spdif->rate_constraints.rats = &spdif->ratnum;
spdif->rate_constraints.nrats = 1;
ret = devm_snd_soc_register_component(&pdev->dev, &axi_spdif_component,
&axi_spdif_dai, 1);
if (ret)
goto err_clk_disable;
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
if (ret)
goto err_clk_disable;
return 0;
err_clk_disable:
clk_disable_unprepare(spdif->clk);
return ret;
}
static int axi_spdif_dev_remove(struct platform_device *pdev)
{
struct axi_spdif *spdif = platform_get_drvdata(pdev);
clk_disable_unprepare(spdif->clk);
return 0;
}
static const struct of_device_id axi_spdif_of_match[] = {
{ .compatible = "adi,axi-spdif-tx-1.00.a", },
{},
};
MODULE_DEVICE_TABLE(of, axi_spdif_of_match);
static struct platform_driver axi_spdif_driver = {
.driver = {
.name = "axi-spdif",
.owner = THIS_MODULE,
.of_match_table = axi_spdif_of_match,
},
.probe = axi_spdif_probe,
.remove = axi_spdif_dev_remove,
};
module_platform_driver(axi_spdif_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("AXI SPDIF driver");
MODULE_LICENSE("GPL");
......@@ -155,8 +155,6 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
of_node_put(codec_np);
of_node_put(cpu_np);
platform_set_drvdata(pdev, card);
ret = snd_soc_register_card(card);
if (ret) {
dev_err(&pdev->dev,
......
......@@ -65,19 +65,10 @@ struct au1xpsc_audio_dmadata {
#define AU1XPSC_PERIOD_MIN_BYTES 1024
#define AU1XPSC_BUFFER_MIN_BYTES 65536
#define AU1XPSC_PCM_FMTS \
(SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \
SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \
0)
/* PCM hardware DMA capabilities - platform specific */
static const struct snd_pcm_hardware au1xpsc_pcm_hardware = {
.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH,
.formats = AU1XPSC_PCM_FMTS,
.period_bytes_min = AU1XPSC_PERIOD_MIN_BYTES,
.period_bytes_max = 4096 * 1024 - 1,
.periods_min = 2,
......
......@@ -21,14 +21,6 @@
#include "psc.h"
#define ALCHEMY_PCM_FMTS \
(SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \
SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \
0)
struct pcm_period {
u32 start;
u32 relative_end; /* relative to start of buffer */
......@@ -171,12 +163,6 @@ static irqreturn_t au1000_dma_interrupt(int irq, void *ptr)
static const struct snd_pcm_hardware alchemy_pcm_hardware = {
.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH,
.formats = ALCHEMY_PCM_FMTS,
.rates = SNDRV_PCM_RATE_8000_192000,
.rate_min = SNDRV_PCM_RATE_8000,
.rate_max = SNDRV_PCM_RATE_192000,
.channels_min = 2,
.channels_max = 2,
.period_bytes_min = 1024,
.period_bytes_max = 16 * 1024 - 1,
.periods_min = 4,
......
config SND_BCM2835_SOC_I2S
tristate "SoC Audio support for the Broadcom BCM2835 I2S module"
depends on ARCH_BCM2835 || COMPILE_TEST
select SND_SOC_DMAENGINE_PCM
select SND_SOC_GENERIC_DMAENGINE_PCM
select REGMAP_MMIO
help
Say Y or M if you want to add support for codecs attached to
the BCM2835 I2S interface. You will also need
to select the audio interfaces to support below.
# BCM2835 Platform Support
snd-soc-bcm2835-i2s-objs := bcm2835-i2s.o
obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o
This diff is collapsed.
......@@ -107,7 +107,6 @@ static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
#endif
SNDRV_PCM_INFO_BLOCK_TRANSFER,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.period_bytes_min = 32,
.period_bytes_max = 0x10000,
.periods_min = 1,
......
......@@ -52,9 +52,6 @@ static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_BLOCK_TRANSFER,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.period_bytes_min = 32,
.period_bytes_max = 0x10000,
.periods_min = 1,
......
......@@ -63,7 +63,7 @@ static struct snd_soc_ops edb93xx_ops = {
static struct snd_soc_dai_link edb93xx_dai = {
.name = "CS4271",
.stream_name = "CS4271 HiFi",
.platform_name = "ep93xx-pcm-audio",
.platform_name = "ep93xx-i2s",
.cpu_dai_name = "ep93xx-i2s",
.codec_name = "spi0.0",
.codec_dai_name = "cs4271-hifi",
......
......@@ -19,11 +19,14 @@
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/dmaengine_pcm.h>
#include <sound/ac97_codec.h>
#include <sound/soc.h>
#include <linux/platform_data/dma-ep93xx.h>
#include "ep93xx-pcm.h"
/*
* Per channel (1-4) registers.
*/
......@@ -95,6 +98,8 @@ struct ep93xx_ac97_info {
struct device *dev;
void __iomem *regs;
struct completion done;
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
};
/* currently ALSA only supports a single AC97 device */
......@@ -315,8 +320,13 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
static int ep93xx_ac97_dai_probe(struct snd_soc_dai *dai)
{
dai->playback_dma_data = &ep93xx_ac97_pcm_out;
dai->capture_dma_data = &ep93xx_ac97_pcm_in;
struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai);
info->dma_params_tx.filter_data = &ep93xx_ac97_pcm_out;
info->dma_params_rx.filter_data = &ep93xx_ac97_pcm_in;
dai->playback_dma_data = &info->dma_params_tx;
dai->capture_dma_data = &info->dma_params_rx;
return 0;
}
......@@ -394,8 +404,14 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
if (ret)
goto fail;
ret = devm_ep93xx_pcm_platform_register(&pdev->dev);
if (ret)
goto fail_unregister;
return 0;
fail_unregister:
snd_soc_unregister_component(&pdev->dev);
fail:
ep93xx_ac97_info = NULL;
snd_soc_set_ac97_ops(NULL);
......
......@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <sound/core.h>
#include <sound/dmaengine_pcm.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>
......@@ -30,6 +31,8 @@
#include <mach/ep93xx-regs.h>
#include <linux/platform_data/dma-ep93xx.h>
#include "ep93xx-pcm.h"
#define EP93XX_I2S_TXCLKCFG 0x00
#define EP93XX_I2S_RXCLKCFG 0x04
#define EP93XX_I2S_GLCTRL 0x0C
......@@ -61,6 +64,8 @@ struct ep93xx_i2s_info {
struct clk *sclk;
struct clk *lrclk;
void __iomem *regs;
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
};
static struct ep93xx_dma_data ep93xx_i2s_dma_data[] = {
......@@ -140,8 +145,15 @@ static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)
static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai)
{
dai->playback_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_PLAYBACK];
dai->capture_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_CAPTURE];
struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
info->dma_params_tx.filter_data =
&ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_PLAYBACK];
info->dma_params_rx.filter_data =
&ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_CAPTURE];
dai->playback_dma_data = &info->dma_params_tx;
dai->capture_dma_data = &info->dma_params_rx;
return 0;
}
......@@ -405,8 +417,14 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
if (err)
goto fail_put_lrclk;
err = devm_ep93xx_pcm_platform_register(&pdev->dev);
if (err)
goto fail_unregister;
return 0;
fail_unregister:
snd_soc_unregister_component(&pdev->dev);
fail_put_lrclk:
clk_put(info->lrclk);
fail_put_sclk:
......
......@@ -23,20 +23,13 @@
#include <linux/platform_data/dma-ep93xx.h>
#include "ep93xx-pcm.h"
static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER),
.rates = SNDRV_PCM_RATE_8000_192000,
.rate_min = SNDRV_PCM_RATE_8000,
.rate_max = SNDRV_PCM_RATE_192000,
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE),
.buffer_bytes_max = 131072,
.period_bytes_min = 32,
.period_bytes_max = 32768,
......@@ -57,53 +50,22 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
return false;
}
static struct dma_chan *ep93xx_compat_request_channel(
struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_substream *substream)
{
struct snd_dmaengine_dai_dma_data *dma_data;
dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
return snd_dmaengine_pcm_request_channel(ep93xx_pcm_dma_filter,
dma_data);
}
static const struct snd_dmaengine_pcm_config ep93xx_dmaengine_pcm_config = {
.pcm_hardware = &ep93xx_pcm_hardware,
.compat_filter_fn = ep93xx_pcm_dma_filter,
.compat_request_channel = ep93xx_compat_request_channel,
.prealloc_buffer_size = 131072,
};
static int ep93xx_soc_platform_probe(struct platform_device *pdev)
int devm_ep93xx_pcm_platform_register(struct device *dev)
{
return snd_dmaengine_pcm_register(&pdev->dev,
return devm_snd_dmaengine_pcm_register(dev,
&ep93xx_dmaengine_pcm_config,
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
SND_DMAENGINE_PCM_FLAG_NO_DT |
SND_DMAENGINE_PCM_FLAG_COMPAT);
}
static int ep93xx_soc_platform_remove(struct platform_device *pdev)
{
snd_dmaengine_pcm_unregister(&pdev->dev);
return 0;
}
static struct platform_driver ep93xx_pcm_driver = {
.driver = {
.name = "ep93xx-pcm-audio",
.owner = THIS_MODULE,
},
.probe = ep93xx_soc_platform_probe,
.remove = ep93xx_soc_platform_remove,
};
module_platform_driver(ep93xx_pcm_driver);
EXPORT_SYMBOL_GPL(devm_ep93xx_pcm_platform_register);
MODULE_AUTHOR("Ryan Mallon");
MODULE_DESCRIPTION("EP93xx ALSA PCM interface");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ep93xx-pcm-audio");
/*
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __EP93XX_PCM_H__
#define __EP93XX_PCM_H__
int devm_ep93xx_pcm_platform_register(struct device *dev);
#endif
......@@ -27,7 +27,7 @@ static struct snd_soc_dai_link simone_dai = {
.cpu_dai_name = "ep93xx-ac97",
.codec_dai_name = "ac97-hifi",
.codec_name = "ac97-codec",
.platform_name = "ep93xx-pcm-audio",
.platform_name = "ep93xx-ac97",
};
static struct snd_soc_card snd_soc_simone = {
......
......@@ -83,7 +83,7 @@ static struct snd_soc_dai_link snappercl15_dai = {
.cpu_dai_name = "ep93xx-i2s",
.codec_dai_name = "tlv320aic23-hifi",
.codec_name = "tlv320aic23-codec.0-001a",
.platform_name = "ep93xx-pcm-audio",
.platform_name = "ep93xx-i2s",
.init = snappercl15_tlv320aic23_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
SND_SOC_DAIFMT_CBS_CFS,
......
......@@ -163,8 +163,10 @@ config SND_SOC_WM_HUBS
config SND_SOC_WM_ADSP
tristate
default y if SND_SOC_WM5102=y
default y if SND_SOC_WM5110=y
default y if SND_SOC_WM2200=y
default m if SND_SOC_WM5102=m
default m if SND_SOC_WM5110=m
default m if SND_SOC_WM2200=m
config SND_SOC_AB8500_CODEC
......
......@@ -179,6 +179,8 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
case SNDRV_PCM_FORMAT_S32_LE:
word_len = AD1836_WORD_LEN_24;
break;
default:
return -EINVAL;
}
regmap_update_bits(ad1836->regmap, AD1836_DAC_CTRL1,
......
......@@ -413,7 +413,7 @@ static struct spi_driver ad193x_spi_driver = {
};
#endif
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
static const struct regmap_config ad193x_i2c_regmap_config = {
.val_bits = 8,
......@@ -470,7 +470,7 @@ static int __init ad193x_modinit(void)
{
int ret;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
ret = i2c_add_driver(&ad193x_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register AD193X I2C driver: %d\n",
......@@ -495,7 +495,7 @@ static void __exit ad193x_modexit(void)
spi_unregister_driver(&ad193x_spi_driver);
#endif
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
i2c_del_driver(&ad193x_i2c_driver);
#endif
}
......
......@@ -939,7 +939,7 @@ static struct spi_driver adav80x_spi_driver = {
};
#endif
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
static const struct regmap_config adav80x_i2c_regmap_config = {
.val_bits = 8,
.pad_bits = 1,
......@@ -985,7 +985,7 @@ static int __init adav80x_init(void)
{
int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
ret = i2c_add_driver(&adav80x_i2c_driver);
if (ret)
return ret;
......@@ -1001,7 +1001,7 @@ module_init(adav80x_init);
static void __exit adav80x_exit(void)
{
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
i2c_del_driver(&adav80x_i2c_driver);
#endif
#if defined(CONFIG_SPI_MASTER)
......
......@@ -17,6 +17,7 @@
#include <linux/gpio.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
......@@ -30,6 +31,7 @@
/* codec private data */
struct ak4641_priv {
struct regmap *regmap;
unsigned int sysclk;
int deemph;
int playback_fs;
......@@ -38,12 +40,12 @@ struct ak4641_priv {
/*
* ak4641 register cache
*/
static const u8 ak4641_reg[AK4641_CACHEREGNUM] = {
0x00, 0x80, 0x00, 0x80,
0x02, 0x00, 0x11, 0x05,
0x00, 0x00, 0x36, 0x10,
0x00, 0x00, 0x57, 0x00,
0x88, 0x88, 0x08, 0x08
static const struct reg_default ak4641_reg_defaults[] = {
{ 0, 0x00 }, { 1, 0x80 }, { 2, 0x00 }, { 3, 0x80 },
{ 4, 0x02 }, { 5, 0x00 }, { 6, 0x11 }, { 7, 0x05 },
{ 8, 0x00 }, { 9, 0x00 }, { 10, 0x36 }, { 11, 0x10 },
{ 12, 0x00 }, { 13, 0x00 }, { 14, 0x57 }, { 15, 0x00 },
{ 16, 0x88 }, { 17, 0x88 }, { 18, 0x08 }, { 19, 0x08 }
};
static const int deemph_settings[] = {44100, 0, 48000, 32000};
......@@ -396,6 +398,7 @@ static int ak4641_mute(struct snd_soc_dai *dai, int mute)
static int ak4641_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
struct ak4641_platform_data *pdata = codec->dev->platform_data;
int ret;
......@@ -417,7 +420,7 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec,
gpio_set_value(pdata->gpio_npdn, 1);
mdelay(1);
ret = snd_soc_cache_sync(codec);
ret = regcache_sync(ak4641->regmap);
if (ret) {
dev_err(codec->dev,
"Failed to sync cache: %d\n", ret);
......@@ -433,7 +436,7 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec,
gpio_set_value(pdata->gpio_npdn, 0);
if (pdata && gpio_is_valid(pdata->gpio_power))
gpio_set_value(pdata->gpio_power, 0);
codec->cache_sync = 1;
regcache_mark_dirty(ak4641->regmap);
break;
}
codec->dapm.bias_level = level;
......@@ -518,7 +521,7 @@ static int ak4641_probe(struct snd_soc_codec *codec)
{
int ret;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
......@@ -550,12 +553,17 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
.dapm_routes = ak4641_audio_map,
.num_dapm_routes = ARRAY_SIZE(ak4641_audio_map),
.set_bias_level = ak4641_set_bias_level,
.reg_cache_size = ARRAY_SIZE(ak4641_reg),
.reg_word_size = sizeof(u8),
.reg_cache_default = ak4641_reg,
.reg_cache_step = 1,
};
static const struct regmap_config ak4641_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = AK4641_BTIF,
.reg_defaults = ak4641_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(ak4641_reg_defaults),
.cache_type = REGCACHE_RBTREE,
};
static int ak4641_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
......@@ -569,6 +577,10 @@ static int ak4641_i2c_probe(struct i2c_client *i2c,
if (!ak4641)
return -ENOMEM;
ak4641->regmap = devm_regmap_init_i2c(i2c, &ak4641_regmap);
if (IS_ERR(ak4641->regmap))
return PTR_ERR(ak4641->regmap);
if (pdata) {
if (gpio_is_valid(pdata->gpio_power)) {
ret = gpio_request_one(pdata->gpio_power,
......
......@@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/of_device.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>
......@@ -198,30 +199,30 @@ static const struct snd_soc_dapm_route ak4642_intercon[] = {
/*
* ak4642 register cache
*/
static const u8 ak4642_reg[] = {
0x00, 0x00, 0x01, 0x00,
0x02, 0x00, 0x00, 0x00,
0xe1, 0xe1, 0x18, 0x00,
0xe1, 0x18, 0x11, 0x08,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00,
static const struct reg_default ak4642_reg[] = {
{ 0, 0x00 }, { 1, 0x00 }, { 2, 0x01 }, { 3, 0x00 },
{ 4, 0x02 }, { 5, 0x00 }, { 6, 0x00 }, { 7, 0x00 },
{ 8, 0xe1 }, { 9, 0xe1 }, { 10, 0x18 }, { 11, 0x00 },
{ 12, 0xe1 }, { 13, 0x18 }, { 14, 0x11 }, { 15, 0x08 },
{ 16, 0x00 }, { 17, 0x00 }, { 18, 0x00 }, { 19, 0x00 },
{ 20, 0x00 }, { 21, 0x00 }, { 22, 0x00 }, { 23, 0x00 },
{ 24, 0x00 }, { 25, 0x00 }, { 26, 0x00 }, { 27, 0x00 },
{ 28, 0x00 }, { 29, 0x00 }, { 30, 0x00 }, { 31, 0x00 },
{ 32, 0x00 }, { 33, 0x00 }, { 34, 0x00 }, { 35, 0x00 },
{ 36, 0x00 },
};
static const u8 ak4648_reg[] = {
0x00, 0x00, 0x01, 0x00,
0x02, 0x00, 0x00, 0x00,
0xe1, 0xe1, 0x18, 0x00,
0xe1, 0x18, 0x11, 0xb8,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x88, 0x88, 0x08,
static const struct reg_default ak4648_reg[] = {
{ 0, 0x00 }, { 1, 0x00 }, { 2, 0x01 }, { 3, 0x00 },
{ 4, 0x02 }, { 5, 0x00 }, { 6, 0x00 }, { 7, 0x00 },
{ 8, 0xe1 }, { 9, 0xe1 }, { 10, 0x18 }, { 11, 0x00 },
{ 12, 0xe1 }, { 13, 0x18 }, { 14, 0x11 }, { 15, 0xb8 },
{ 16, 0x00 }, { 17, 0x00 }, { 18, 0x00 }, { 19, 0x00 },
{ 20, 0x00 }, { 21, 0x00 }, { 22, 0x00 }, { 23, 0x00 },
{ 24, 0x00 }, { 25, 0x00 }, { 26, 0x00 }, { 27, 0x00 },
{ 28, 0x00 }, { 29, 0x00 }, { 30, 0x00 }, { 31, 0x00 },
{ 32, 0x00 }, { 33, 0x00 }, { 34, 0x00 }, { 35, 0x00 },
{ 36, 0x00 }, { 37, 0x88 }, { 38, 0x88 }, { 39, 0x08 },
};
static int ak4642_dai_startup(struct snd_pcm_substream *substream,
......@@ -454,7 +455,10 @@ static struct snd_soc_dai_driver ak4642_dai = {
static int ak4642_resume(struct snd_soc_codec *codec)
{
snd_soc_cache_sync(codec);
struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
regcache_mark_dirty(regmap);
regcache_sync(regmap);
return 0;
}
......@@ -463,15 +467,12 @@ static int ak4642_probe(struct snd_soc_codec *codec)
{
int ret;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
snd_soc_add_codec_controls(codec, ak4642_snd_controls,
ARRAY_SIZE(ak4642_snd_controls));
ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
......@@ -488,55 +489,59 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
.remove = ak4642_remove,
.resume = ak4642_resume,
.set_bias_level = ak4642_set_bias_level,
.reg_cache_default = ak4642_reg, /* ak4642 reg */
.reg_cache_size = ARRAY_SIZE(ak4642_reg), /* ak4642 reg */
.reg_word_size = sizeof(u8),
.controls = ak4642_snd_controls,
.num_controls = ARRAY_SIZE(ak4642_snd_controls),
.dapm_widgets = ak4642_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets),
.dapm_routes = ak4642_intercon,
.num_dapm_routes = ARRAY_SIZE(ak4642_intercon),
};
static struct snd_soc_codec_driver soc_codec_dev_ak4648 = {
.probe = ak4642_probe,
.remove = ak4642_remove,
.resume = ak4642_resume,
.set_bias_level = ak4642_set_bias_level,
.reg_cache_default = ak4648_reg, /* ak4648 reg */
.reg_cache_size = ARRAY_SIZE(ak4648_reg), /* ak4648 reg */
.reg_word_size = sizeof(u8),
.dapm_widgets = ak4642_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets),
.dapm_routes = ak4642_intercon,
.num_dapm_routes = ARRAY_SIZE(ak4642_intercon),
static const struct regmap_config ak4642_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = ARRAY_SIZE(ak4642_reg) + 1,
.reg_defaults = ak4642_reg,
.num_reg_defaults = ARRAY_SIZE(ak4642_reg),
};
static const struct regmap_config ak4648_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = ARRAY_SIZE(ak4648_reg) + 1,
.reg_defaults = ak4648_reg,
.num_reg_defaults = ARRAY_SIZE(ak4648_reg),
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static struct of_device_id ak4642_of_match[];
static int ak4642_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct device_node *np = i2c->dev.of_node;
const struct snd_soc_codec_driver *driver;
const struct regmap_config *regmap_config = NULL;
struct regmap *regmap;
driver = NULL;
if (np) {
const struct of_device_id *of_id;
of_id = of_match_device(ak4642_of_match, &i2c->dev);
if (of_id)
driver = of_id->data;
regmap_config = of_id->data;
} else {
driver = (struct snd_soc_codec_driver *)id->driver_data;
regmap_config = (const struct regmap_config *)id->driver_data;
}
if (!driver) {
dev_err(&i2c->dev, "no driver\n");
if (!regmap_config) {
dev_err(&i2c->dev, "Unknown device type\n");
return -EINVAL;
}
regmap = devm_regmap_init_i2c(i2c, regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
return snd_soc_register_codec(&i2c->dev,
driver, &ak4642_dai, 1);
&soc_codec_dev_ak4642, &ak4642_dai, 1);
}
static int ak4642_i2c_remove(struct i2c_client *client)
......@@ -546,17 +551,17 @@ static int ak4642_i2c_remove(struct i2c_client *client)
}
static struct of_device_id ak4642_of_match[] = {
{ .compatible = "asahi-kasei,ak4642", .data = &soc_codec_dev_ak4642},
{ .compatible = "asahi-kasei,ak4643", .data = &soc_codec_dev_ak4642},
{ .compatible = "asahi-kasei,ak4648", .data = &soc_codec_dev_ak4648},
{ .compatible = "asahi-kasei,ak4642", .data = &ak4642_regmap},
{ .compatible = "asahi-kasei,ak4643", .data = &ak4642_regmap},
{ .compatible = "asahi-kasei,ak4648", .data = &ak4648_regmap},
{},
};
MODULE_DEVICE_TABLE(of, ak4642_of_match);
static const struct i2c_device_id ak4642_i2c_id[] = {
{ "ak4642", (kernel_ulong_t)&soc_codec_dev_ak4642 },
{ "ak4643", (kernel_ulong_t)&soc_codec_dev_ak4642 },
{ "ak4648", (kernel_ulong_t)&soc_codec_dev_ak4648 },
{ "ak4642", (kernel_ulong_t)&ak4642_regmap },
{ "ak4643", (kernel_ulong_t)&ak4642_regmap },
{ "ak4648", (kernel_ulong_t)&ak4648_regmap },
{ }
};
MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
......@@ -571,27 +576,8 @@ static struct i2c_driver ak4642_i2c_driver = {
.remove = ak4642_i2c_remove,
.id_table = ak4642_i2c_id,
};
#endif
static int __init ak4642_modinit(void)
{
int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&ak4642_i2c_driver);
#endif
return ret;
}
module_init(ak4642_modinit);
static void __exit ak4642_exit(void)
{
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&ak4642_i2c_driver);
#endif
}
module_exit(ak4642_exit);
module_i2c_driver(ak4642_i2c_driver);
MODULE_DESCRIPTION("Soc AK4642 driver");
MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
......
This diff is collapsed.
......@@ -81,7 +81,7 @@ struct arizona_priv {
unsigned int spk_ena_pending:1;
};
#define ARIZONA_NUM_MIXER_INPUTS 99
#define ARIZONA_NUM_MIXER_INPUTS 103
extern const unsigned int arizona_mixer_tlv[];
extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
......@@ -186,6 +186,8 @@ extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];
extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE];
extern const struct soc_enum arizona_isrc_fsl[];
extern const struct soc_enum arizona_isrc_fsh[];
extern const struct soc_enum arizona_asrc_rate1;
extern const struct soc_enum arizona_in_vi_ramp;
extern const struct soc_enum arizona_in_vd_ramp;
......@@ -199,6 +201,7 @@ extern const struct soc_enum arizona_lhpf3_mode;
extern const struct soc_enum arizona_lhpf4_mode;
extern const struct soc_enum arizona_ng_hold;
extern const struct soc_enum arizona_in_hpf_cut_enum;
extern const struct soc_enum arizona_in_dmic_osr[];
extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
......
......@@ -675,7 +675,7 @@ static struct spi_driver cs4271_spi_driver = {
};
#endif /* defined(CONFIG_SPI_MASTER) */
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
static const struct i2c_device_id cs4271_i2c_id[] = {
{"cs4271", 0},
{}
......@@ -728,7 +728,7 @@ static struct i2c_driver cs4271_i2c_driver = {
.probe = cs4271_i2c_probe,
.remove = cs4271_i2c_remove,
};
#endif /* defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) */
#endif /* IS_ENABLED(CONFIG_I2C) */
/*
* We only register our serial bus driver here without
......@@ -741,7 +741,7 @@ static int __init cs4271_modinit(void)
{
int ret;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
ret = i2c_add_driver(&cs4271_i2c_driver);
if (ret) {
pr_err("Failed to register CS4271 I2C driver: %d\n", ret);
......@@ -767,7 +767,7 @@ static void __exit cs4271_modexit(void)
spi_unregister_driver(&cs4271_spi_driver);
#endif
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
i2c_del_driver(&cs4271_i2c_driver);
#endif
}
......
This diff is collapsed.
......@@ -1188,7 +1188,7 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
.num_dapm_routes = ARRAY_SIZE(da7210_audio_map),
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
static struct reg_default da7210_regmap_i2c_patch[] = {
......@@ -1362,7 +1362,7 @@ static struct spi_driver da7210_spi_driver = {
static int __init da7210_modinit(void)
{
int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
ret = i2c_add_driver(&da7210_i2c_driver);
#endif
#if defined(CONFIG_SPI_MASTER)
......@@ -1378,7 +1378,7 @@ module_init(da7210_modinit);
static void __exit da7210_exit(void)
{
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
i2c_del_driver(&da7210_i2c_driver);
#endif
#if defined(CONFIG_SPI_MASTER)
......
......@@ -20,6 +20,7 @@
*/
#include <linux/module.h>
#include <sound/soc.h>
#include <linux/of_device.h>
#define DRV_NAME "hdmi-audio-codec"
......@@ -44,7 +45,7 @@ static struct snd_soc_dai_driver hdmi_codec_dai = {
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE,
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
},
.capture = {
.stream_name = "Capture",
......@@ -60,6 +61,14 @@ static struct snd_soc_dai_driver hdmi_codec_dai = {
};
#ifdef CONFIG_OF
static const struct of_device_id hdmi_audio_codec_ids[] = {
{ .compatible = "linux,hdmi-audio", },
{ }
};
MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids);
#endif
static struct snd_soc_codec_driver hdmi_codec = {
.dapm_widgets = hdmi_widgets,
.num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
......@@ -83,6 +92,7 @@ static struct platform_driver hdmi_codec_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(hdmi_audio_codec_ids),
},
.probe = hdmi_codec_probe,
......
This diff is collapsed.
......@@ -549,13 +549,13 @@ static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
right_slot = 0;
} else {
/* We assume the left channel < right channel */
left_slot = ffs(tx_mask);
tx_mask &= ~(1 << tx_mask);
left_slot = __ffs(tx_mask);
tx_mask &= ~(1 << left_slot);
if (tx_mask == 0) {
right_slot = left_slot;
} else {
right_slot = ffs(tx_mask);
tx_mask &= ~(1 << tx_mask);
right_slot = __ffs(tx_mask);
tx_mask &= ~(1 << right_slot);
}
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -794,7 +794,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
.num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes),
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
static int uda1380_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
......@@ -840,7 +840,7 @@ static struct i2c_driver uda1380_i2c_driver = {
static int __init uda1380_modinit(void)
{
int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
ret = i2c_add_driver(&uda1380_i2c_driver);
if (ret != 0)
pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
......@@ -851,7 +851,7 @@ module_init(uda1380_modinit);
static void __exit uda1380_exit(void)
{
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
i2c_del_driver(&uda1380_i2c_driver);
#endif
}
......
......@@ -601,7 +601,7 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMU:
if (patch)
for (i = 0; i < patch_size; i++)
regmap_write(regmap, patch[i].reg,
regmap_write_async(regmap, patch[i].reg,
patch[i].def);
break;
......
This diff is collapsed.
......@@ -684,7 +684,7 @@ static struct spi_driver wm8510_spi_driver = {
};
#endif /* CONFIG_SPI_MASTER */
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
static int wm8510_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
......@@ -735,7 +735,7 @@ static struct i2c_driver wm8510_i2c_driver = {
static int __init wm8510_modinit(void)
{
int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
ret = i2c_add_driver(&wm8510_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register WM8510 I2C driver: %d\n",
......@@ -755,7 +755,7 @@ module_init(wm8510_modinit);
static void __exit wm8510_exit(void)
{
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#if IS_ENABLED(CONFIG_I2C)
i2c_del_driver(&wm8510_i2c_driver);
#endif
#if defined(CONFIG_SPI_MASTER)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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