提交 2aff4c9c 编写于 作者: T Takashi Iwai

Merge tag 'asoc-v3.14-2' of...

Merge tag 'asoc-v3.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next

ASoC: More updates for v3.14

A few more updates for v3.14 since the last set, highlights include:

 - Lots of DMA updates from Lars-Peter
 - Improvements to the constraints handling code from Lars-Peter
 - A very helpful conversion of the TWL4030 driver to regmap from Peter
 - A new driver for the Freescale ESAI controller from Nicolin Chen
 - Conversion of some of the drivers to use params_width()
Freescale Enhanced Serial Audio Interface (ESAI) Controller
The Enhanced Serial Audio Interface (ESAI) provides a full-duplex serial port
for serial communication with a variety of serial devices, including industry
standard codecs, Sony/Phillips Digital Interface (S/PDIF) transceivers, and
other DSPs. It has up to six transmitters and four receivers.
Required properties:
- compatible : Compatible list, must contain "fsl,imx35-esai".
- 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 used to access registers
"extal" The esai baud clock for esai controller used to derive
HCK, SCK and FS.
"fsys" The system clock derived from ahb clock used to derive
HCK, SCK and FS.
- fsl,fifo-depth: The number of elements in the transmit and receive FIFOs.
This number is the maximum allowed value for TFCR[TFWM] or RFCR[RFWM].
- fsl,esai-synchronous: This is a boolean property. If present, indicating
that ESAI would work in the synchronous mode, which means all the settings
for Receiving would be duplicated from Transmition related registers.
Example:
esai: esai@02024000 {
compatible = "fsl,imx35-esai";
reg = <0x02024000 0x4000>;
interrupts = <0 51 0x04>;
clocks = <&clks 208>, <&clks 118>, <&clks 208>;
clock-names = "core", "extal", "fsys";
dmas = <&sdma 23 21 0>, <&sdma 24 21 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <128>;
fsl,esai-synchronous;
status = "disabled";
};
...@@ -4,7 +4,12 @@ The SSI is a serial device that communicates with audio codecs. It can ...@@ -4,7 +4,12 @@ The SSI is a serial device that communicates with audio codecs. It can
be programmed in AC97, I2S, left-justified, or right-justified modes. be programmed in AC97, I2S, left-justified, or right-justified modes.
Required properties: Required properties:
- compatible: Compatible list, contains "fsl,ssi". - compatible: Compatible list, should contain one of the following
compatibles:
fsl,mpc8610-ssi
fsl,imx51-ssi
fsl,imx35-ssi
fsl,imx21-ssi
- cell-index: The SSI, <0> = SSI1, <1> = SSI2, and so on. - cell-index: The SSI, <0> = SSI1, <1> = SSI2, and so on.
- reg: Offset and length of the register set for the device. - reg: Offset and length of the register set for the device.
- interrupts: <a b> where a is the interrupt number and b is a - interrupts: <a b> where a is the interrupt number and b is a
......
...@@ -11,7 +11,7 @@ Optional properties: ...@@ -11,7 +11,7 @@ Optional properties:
- simple-audio-card,format : CPU/CODEC common audio format. - simple-audio-card,format : CPU/CODEC common audio format.
"i2s", "right_j", "left_j" , "dsp_a" "i2s", "right_j", "left_j" , "dsp_a"
"dsp_b", "ac97", "pdm", "msb", "lsb" "dsp_b", "ac97", "pdm", "msb", "lsb"
- simple-audio-routing : A list of the connections between audio components. - simple-audio-card,routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the Each entry is a pair of strings, the first being the
connection's sink, the second being the connection's connection's sink, the second being the connection's
source. source.
......
...@@ -6,6 +6,7 @@ Required properties: ...@@ -6,6 +6,7 @@ Required properties:
- compatible - "string" - One of: - compatible - "string" - One of:
"ti,tlv320aic3x" - Generic TLV320AIC3x device "ti,tlv320aic3x" - Generic TLV320AIC3x device
"ti,tlv320aic32x4" - TLV320AIC32x4
"ti,tlv320aic33" - TLV320AIC33 "ti,tlv320aic33" - TLV320AIC33
"ti,tlv320aic3007" - TLV320AIC3007 "ti,tlv320aic3007" - TLV320AIC3007
"ti,tlv320aic3106" - TLV320AIC3106 "ti,tlv320aic3106" - TLV320AIC3106
......
...@@ -49,18 +49,23 @@ features :- ...@@ -49,18 +49,23 @@ features :-
* Machine specific controls: Allow machines to add controls to the sound card * Machine specific controls: Allow machines to add controls to the sound card
(e.g. volume control for speaker amplifier). (e.g. volume control for speaker amplifier).
To achieve all this, ASoC basically splits an embedded audio system into 3 To achieve all this, ASoC basically splits an embedded audio system into
components :- multiple re-usable component drivers :-
* Codec driver: The codec driver is platform independent and contains audio * Codec class drivers: The codec class driver is platform independent and
controls, audio interface capabilities, codec DAPM definition and codec IO contains audio controls, audio interface capabilities, codec DAPM
functions. definition and codec IO functions. This class extends to BT, FM and MODEM
ICs if required. Codec class drivers should be generic code that can run
on any architecture and machine.
* Platform driver: The platform driver contains the audio DMA engine and audio * Platform class drivers: The platform class driver includes the audio DMA
interface drivers (e.g. I2S, AC97, PCM) for that platform. engine driver, digital audio interface (DAI) drivers (e.g. I2S, AC97, PCM)
and any audio DSP drivers for that platform.
* Machine driver: The machine driver handles any machine specific controls and * Machine class driver: The machine driver class acts as the glue that
audio events (e.g. turning on an amp at start of playback). decribes and binds the other component drivers together to form an ALSA
"sound card device". It handles any machine specific controls and
machine level audio events (e.g. turning on an amp at start of playback).
Documentation Documentation
...@@ -84,3 +89,7 @@ machine.txt: Machine driver internals. ...@@ -84,3 +89,7 @@ machine.txt: Machine driver internals.
pop_clicks.txt: How to minimise audio artifacts. pop_clicks.txt: How to minimise audio artifacts.
clocking.txt: ASoC clocking for best power performance. clocking.txt: ASoC clocking for best power performance.
jack.txt: ASoC jack detection.
DPCM.txt: Dynamic PCM - Describes DPCM with DSP examples.
...@@ -31,7 +31,7 @@ static struct stedma40_chan_cfg msp0_dma_tx = { ...@@ -31,7 +31,7 @@ static struct stedma40_chan_cfg msp0_dma_tx = {
}; };
struct msp_i2s_platform_data msp0_platform_data = { struct msp_i2s_platform_data msp0_platform_data = {
.id = MSP_I2S_0, .id = 0,
.msp_i2s_dma_rx = &msp0_dma_rx, .msp_i2s_dma_rx = &msp0_dma_rx,
.msp_i2s_dma_tx = &msp0_dma_tx, .msp_i2s_dma_tx = &msp0_dma_tx,
}; };
...@@ -49,7 +49,7 @@ static struct stedma40_chan_cfg msp1_dma_tx = { ...@@ -49,7 +49,7 @@ static struct stedma40_chan_cfg msp1_dma_tx = {
}; };
struct msp_i2s_platform_data msp1_platform_data = { struct msp_i2s_platform_data msp1_platform_data = {
.id = MSP_I2S_1, .id = 1,
.msp_i2s_dma_rx = NULL, .msp_i2s_dma_rx = NULL,
.msp_i2s_dma_tx = &msp1_dma_tx, .msp_i2s_dma_tx = &msp1_dma_tx,
}; };
...@@ -69,13 +69,13 @@ static struct stedma40_chan_cfg msp2_dma_tx = { ...@@ -69,13 +69,13 @@ static struct stedma40_chan_cfg msp2_dma_tx = {
}; };
struct msp_i2s_platform_data msp2_platform_data = { struct msp_i2s_platform_data msp2_platform_data = {
.id = MSP_I2S_2, .id = 2,
.msp_i2s_dma_rx = &msp2_dma_rx, .msp_i2s_dma_rx = &msp2_dma_rx,
.msp_i2s_dma_tx = &msp2_dma_tx, .msp_i2s_dma_tx = &msp2_dma_tx,
}; };
struct msp_i2s_platform_data msp3_platform_data = { struct msp_i2s_platform_data msp3_platform_data = {
.id = MSP_I2S_3, .id = 3,
.msp_i2s_dma_rx = &msp1_dma_rx, .msp_i2s_dma_rx = &msp1_dma_rx,
.msp_i2s_dma_tx = NULL, .msp_i2s_dma_tx = NULL,
}; };
...@@ -2884,6 +2884,7 @@ static int pl330_dma_device_slave_caps(struct dma_chan *dchan, ...@@ -2884,6 +2884,7 @@ static int pl330_dma_device_slave_caps(struct dma_chan *dchan,
caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
caps->cmd_pause = false; caps->cmd_pause = false;
caps->cmd_terminate = true; caps->cmd_terminate = true;
caps->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
return 0; return 0;
} }
......
...@@ -47,6 +47,9 @@ ...@@ -47,6 +47,9 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c/twl.h> #include <linux/i2c/twl.h>
/* Register descriptions for audio */
#include <linux/mfd/twl4030-audio.h>
#include "twl-core.h" #include "twl-core.h"
/* /*
...@@ -200,6 +203,105 @@ static struct twl_mapping twl4030_map[] = { ...@@ -200,6 +203,105 @@ static struct twl_mapping twl4030_map[] = {
{ 2, TWL5031_BASEADD_INTERRUPTS }, { 2, TWL5031_BASEADD_INTERRUPTS },
}; };
static struct reg_default twl4030_49_defaults[] = {
/* Audio Registers */
{ 0x01, 0x00}, /* CODEC_MODE */
{ 0x02, 0x00}, /* OPTION */
/* 0x03 Unused */
{ 0x04, 0x00}, /* MICBIAS_CTL */
{ 0x05, 0x00}, /* ANAMICL */
{ 0x06, 0x00}, /* ANAMICR */
{ 0x07, 0x00}, /* AVADC_CTL */
{ 0x08, 0x00}, /* ADCMICSEL */
{ 0x09, 0x00}, /* DIGMIXING */
{ 0x0a, 0x0f}, /* ATXL1PGA */
{ 0x0b, 0x0f}, /* ATXR1PGA */
{ 0x0c, 0x0f}, /* AVTXL2PGA */
{ 0x0d, 0x0f}, /* AVTXR2PGA */
{ 0x0e, 0x00}, /* AUDIO_IF */
{ 0x0f, 0x00}, /* VOICE_IF */
{ 0x10, 0x3f}, /* ARXR1PGA */
{ 0x11, 0x3f}, /* ARXL1PGA */
{ 0x12, 0x3f}, /* ARXR2PGA */
{ 0x13, 0x3f}, /* ARXL2PGA */
{ 0x14, 0x25}, /* VRXPGA */
{ 0x15, 0x00}, /* VSTPGA */
{ 0x16, 0x00}, /* VRX2ARXPGA */
{ 0x17, 0x00}, /* AVDAC_CTL */
{ 0x18, 0x00}, /* ARX2VTXPGA */
{ 0x19, 0x32}, /* ARXL1_APGA_CTL*/
{ 0x1a, 0x32}, /* ARXR1_APGA_CTL*/
{ 0x1b, 0x32}, /* ARXL2_APGA_CTL*/
{ 0x1c, 0x32}, /* ARXR2_APGA_CTL*/
{ 0x1d, 0x00}, /* ATX2ARXPGA */
{ 0x1e, 0x00}, /* BT_IF */
{ 0x1f, 0x55}, /* BTPGA */
{ 0x20, 0x00}, /* BTSTPGA */
{ 0x21, 0x00}, /* EAR_CTL */
{ 0x22, 0x00}, /* HS_SEL */
{ 0x23, 0x00}, /* HS_GAIN_SET */
{ 0x24, 0x00}, /* HS_POPN_SET */
{ 0x25, 0x00}, /* PREDL_CTL */
{ 0x26, 0x00}, /* PREDR_CTL */
{ 0x27, 0x00}, /* PRECKL_CTL */
{ 0x28, 0x00}, /* PRECKR_CTL */
{ 0x29, 0x00}, /* HFL_CTL */
{ 0x2a, 0x00}, /* HFR_CTL */
{ 0x2b, 0x05}, /* ALC_CTL */
{ 0x2c, 0x00}, /* ALC_SET1 */
{ 0x2d, 0x00}, /* ALC_SET2 */
{ 0x2e, 0x00}, /* BOOST_CTL */
{ 0x2f, 0x00}, /* SOFTVOL_CTL */
{ 0x30, 0x13}, /* DTMF_FREQSEL */
{ 0x31, 0x00}, /* DTMF_TONEXT1H */
{ 0x32, 0x00}, /* DTMF_TONEXT1L */
{ 0x33, 0x00}, /* DTMF_TONEXT2H */
{ 0x34, 0x00}, /* DTMF_TONEXT2L */
{ 0x35, 0x79}, /* DTMF_TONOFF */
{ 0x36, 0x11}, /* DTMF_WANONOFF */
{ 0x37, 0x00}, /* I2S_RX_SCRAMBLE_H */
{ 0x38, 0x00}, /* I2S_RX_SCRAMBLE_M */
{ 0x39, 0x00}, /* I2S_RX_SCRAMBLE_L */
{ 0x3a, 0x06}, /* APLL_CTL */
{ 0x3b, 0x00}, /* DTMF_CTL */
{ 0x3c, 0x44}, /* DTMF_PGA_CTL2 (0x3C) */
{ 0x3d, 0x69}, /* DTMF_PGA_CTL1 (0x3D) */
{ 0x3e, 0x00}, /* MISC_SET_1 */
{ 0x3f, 0x00}, /* PCMBTMUX */
/* 0x40 - 0x42 Unused */
{ 0x43, 0x00}, /* RX_PATH_SEL */
{ 0x44, 0x32}, /* VDL_APGA_CTL */
{ 0x45, 0x00}, /* VIBRA_CTL */
{ 0x46, 0x00}, /* VIBRA_SET */
{ 0x47, 0x00}, /* VIBRA_PWM_SET */
{ 0x48, 0x00}, /* ANAMIC_GAIN */
{ 0x49, 0x00}, /* MISC_SET_2 */
/* End of Audio Registers */
};
static bool twl4030_49_nop_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case 0:
case 3:
case 40:
case 41:
case 42:
return false;
default:
return true;
}
}
static const struct regmap_range twl4030_49_volatile_ranges[] = {
regmap_reg_range(TWL4030_BASEADD_TEST, 0xff),
};
static const struct regmap_access_table twl4030_49_volatile_table = {
.yes_ranges = twl4030_49_volatile_ranges,
.n_yes_ranges = ARRAY_SIZE(twl4030_49_volatile_ranges),
};
static struct regmap_config twl4030_regmap_config[4] = { static struct regmap_config twl4030_regmap_config[4] = {
{ {
/* Address 0x48 */ /* Address 0x48 */
...@@ -212,6 +314,15 @@ static struct regmap_config twl4030_regmap_config[4] = { ...@@ -212,6 +314,15 @@ static struct regmap_config twl4030_regmap_config[4] = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
.max_register = 0xff, .max_register = 0xff,
.readable_reg = twl4030_49_nop_reg,
.writeable_reg = twl4030_49_nop_reg,
.volatile_table = &twl4030_49_volatile_table,
.reg_defaults = twl4030_49_defaults,
.num_reg_defaults = ARRAY_SIZE(twl4030_49_defaults),
.cache_type = REGCACHE_RBTREE,
}, },
{ {
/* Address 0x4a */ /* Address 0x4a */
...@@ -302,35 +413,50 @@ unsigned int twl_rev(void) ...@@ -302,35 +413,50 @@ unsigned int twl_rev(void)
EXPORT_SYMBOL(twl_rev); EXPORT_SYMBOL(twl_rev);
/** /**
* twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0 * twl_get_regmap - Get the regmap associated with the given module
* @mod_no: module number * @mod_no: module number
* @value: an array of num_bytes+1 containing data to write
* @reg: register address (just offset will do)
* @num_bytes: number of bytes to transfer
* *
* Returns the result of operation - 0 is success * Returns the regmap pointer or NULL in case of failure.
*/ */
int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) static struct regmap *twl_get_regmap(u8 mod_no)
{ {
int ret;
int sid; int sid;
struct twl_client *twl; struct twl_client *twl;
if (unlikely(!twl_priv || !twl_priv->ready)) { if (unlikely(!twl_priv || !twl_priv->ready)) {
pr_err("%s: not initialized\n", DRIVER_NAME); pr_err("%s: not initialized\n", DRIVER_NAME);
return -EPERM; return NULL;
} }
if (unlikely(mod_no >= twl_get_last_module())) { if (unlikely(mod_no >= twl_get_last_module())) {
pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
return -EPERM; return NULL;
} }
sid = twl_priv->twl_map[mod_no].sid; sid = twl_priv->twl_map[mod_no].sid;
twl = &twl_priv->twl_modules[sid]; twl = &twl_priv->twl_modules[sid];
ret = regmap_bulk_write(twl->regmap, return twl->regmap;
twl_priv->twl_map[mod_no].base + reg, value, }
num_bytes);
/**
* twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0
* @mod_no: module number
* @value: an array of num_bytes+1 containing data to write
* @reg: register address (just offset will do)
* @num_bytes: number of bytes to transfer
*
* Returns the result of operation - 0 is success
*/
int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
{
struct regmap *regmap = twl_get_regmap(mod_no);
int ret;
if (!regmap)
return -EPERM;
ret = regmap_bulk_write(regmap, twl_priv->twl_map[mod_no].base + reg,
value, num_bytes);
if (ret) if (ret)
pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n", pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n",
...@@ -351,25 +477,14 @@ EXPORT_SYMBOL(twl_i2c_write); ...@@ -351,25 +477,14 @@ EXPORT_SYMBOL(twl_i2c_write);
*/ */
int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
{ {
struct regmap *regmap = twl_get_regmap(mod_no);
int ret; int ret;
int sid;
struct twl_client *twl;
if (unlikely(!twl_priv || !twl_priv->ready)) { if (!regmap)
pr_err("%s: not initialized\n", DRIVER_NAME);
return -EPERM;
}
if (unlikely(mod_no >= twl_get_last_module())) {
pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
return -EPERM; return -EPERM;
}
sid = twl_priv->twl_map[mod_no].sid;
twl = &twl_priv->twl_modules[sid];
ret = regmap_bulk_read(twl->regmap, ret = regmap_bulk_read(regmap, twl_priv->twl_map[mod_no].base + reg,
twl_priv->twl_map[mod_no].base + reg, value, value, num_bytes);
num_bytes);
if (ret) if (ret)
pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n", pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n",
...@@ -379,6 +494,27 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) ...@@ -379,6 +494,27 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
} }
EXPORT_SYMBOL(twl_i2c_read); EXPORT_SYMBOL(twl_i2c_read);
/**
* twl_regcache_bypass - Configure the regcache bypass for the regmap associated
* with the module
* @mod_no: module number
* @enable: Regcache bypass state
*
* Returns 0 else failure.
*/
int twl_set_regcache_bypass(u8 mod_no, bool enable)
{
struct regmap *regmap = twl_get_regmap(mod_no);
if (!regmap)
return -EPERM;
regcache_cache_bypass(regmap, enable);
return 0;
}
EXPORT_SYMBOL(twl_set_regcache_bypass);
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
/** /**
......
...@@ -610,6 +610,9 @@ static const struct reg_default wm5110_reg_default[] = { ...@@ -610,6 +610,9 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000491, 0x0000 }, /* R1169 - PDM SPK1 CTRL 2 */ { 0x00000491, 0x0000 }, /* R1169 - PDM SPK1 CTRL 2 */
{ 0x00000492, 0x0069 }, /* R1170 - PDM SPK2 CTRL 1 */ { 0x00000492, 0x0069 }, /* R1170 - PDM SPK2 CTRL 1 */
{ 0x00000493, 0x0000 }, /* R1171 - PDM SPK2 CTRL 2 */ { 0x00000493, 0x0000 }, /* R1171 - PDM SPK2 CTRL 2 */
{ 0x000004A0, 0x3480 }, /* R1184 - HP1 Short Circuit Ctrl */
{ 0x000004A1, 0x3480 }, /* R1185 - HP2 Short Circuit Ctrl */
{ 0x000004A2, 0x3480 }, /* R1186 - HP3 Short Circuit Ctrl */
{ 0x00000500, 0x000C }, /* R1280 - AIF1 BCLK Ctrl */ { 0x00000500, 0x000C }, /* R1280 - AIF1 BCLK Ctrl */
{ 0x00000501, 0x0008 }, /* R1281 - AIF1 Tx Pin Ctrl */ { 0x00000501, 0x0008 }, /* R1281 - AIF1 Tx Pin Ctrl */
{ 0x00000502, 0x0000 }, /* R1282 - AIF1 Rx Pin Ctrl */ { 0x00000502, 0x0000 }, /* R1282 - AIF1 Rx Pin Ctrl */
...@@ -1639,6 +1642,9 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) ...@@ -1639,6 +1642,9 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_PDM_SPK1_CTRL_2: case ARIZONA_PDM_SPK1_CTRL_2:
case ARIZONA_PDM_SPK2_CTRL_1: case ARIZONA_PDM_SPK2_CTRL_1:
case ARIZONA_PDM_SPK2_CTRL_2: case ARIZONA_PDM_SPK2_CTRL_2:
case ARIZONA_HP1_SHORT_CIRCUIT_CTRL:
case ARIZONA_HP2_SHORT_CIRCUIT_CTRL:
case ARIZONA_HP3_SHORT_CIRCUIT_CTRL:
case ARIZONA_AIF1_BCLK_CTRL: case ARIZONA_AIF1_BCLK_CTRL:
case ARIZONA_AIF1_TX_PIN_CTRL: case ARIZONA_AIF1_TX_PIN_CTRL:
case ARIZONA_AIF1_RX_PIN_CTRL: case ARIZONA_AIF1_RX_PIN_CTRL:
......
...@@ -364,6 +364,32 @@ struct dma_slave_config { ...@@ -364,6 +364,32 @@ struct dma_slave_config {
unsigned int slave_id; unsigned int slave_id;
}; };
/**
* enum dma_residue_granularity - Granularity of the reported transfer residue
* @DMA_RESIDUE_GRANULARITY_DESCRIPTOR: Residue reporting is not support. The
* DMA channel is only able to tell whether a descriptor has been completed or
* not, which means residue reporting is not supported by this channel. The
* residue field of the dma_tx_state field will always be 0.
* @DMA_RESIDUE_GRANULARITY_SEGMENT: Residue is updated after each successfully
* completed segment of the transfer (For cyclic transfers this is after each
* period). This is typically implemented by having the hardware generate an
* interrupt after each transferred segment and then the drivers updates the
* outstanding residue by the size of the segment. Another possibility is if
* the hardware supports scatter-gather and the segment descriptor has a field
* which gets set after the segment has been completed. The driver then counts
* the number of segments without the flag set to compute the residue.
* @DMA_RESIDUE_GRANULARITY_BURST: Residue is updated after each transferred
* burst. This is typically only supported if the hardware has a progress
* register of some sort (E.g. a register with the current read/write address
* or a register with the amount of bursts/beats/bytes that have been
* transferred or still need to be transferred).
*/
enum dma_residue_granularity {
DMA_RESIDUE_GRANULARITY_DESCRIPTOR = 0,
DMA_RESIDUE_GRANULARITY_SEGMENT = 1,
DMA_RESIDUE_GRANULARITY_BURST = 2,
};
/* struct dma_slave_caps - expose capabilities of a slave channel only /* struct dma_slave_caps - expose capabilities of a slave channel only
* *
* @src_addr_widths: bit mask of src addr widths the channel supports * @src_addr_widths: bit mask of src addr widths the channel supports
...@@ -374,6 +400,7 @@ struct dma_slave_config { ...@@ -374,6 +400,7 @@ struct dma_slave_config {
* should be checked by controller as well * should be checked by controller as well
* @cmd_pause: true, if pause and thereby resume is supported * @cmd_pause: true, if pause and thereby resume is supported
* @cmd_terminate: true, if terminate cmd is supported * @cmd_terminate: true, if terminate cmd is supported
* @residue_granularity: granularity of the reported transfer residue
*/ */
struct dma_slave_caps { struct dma_slave_caps {
u32 src_addr_widths; u32 src_addr_widths;
...@@ -381,6 +408,7 @@ struct dma_slave_caps { ...@@ -381,6 +408,7 @@ struct dma_slave_caps {
u32 directions; u32 directions;
bool cmd_pause; bool cmd_pause;
bool cmd_terminate; bool cmd_terminate;
enum dma_residue_granularity residue_granularity;
}; };
static inline const char *dma_chan_name(struct dma_chan *chan) static inline const char *dma_chan_name(struct dma_chan *chan)
......
...@@ -175,6 +175,9 @@ static inline int twl_class_is_ ##class(void) \ ...@@ -175,6 +175,9 @@ static inline int twl_class_is_ ##class(void) \
TWL_CLASS_IS(4030, TWL4030_CLASS_ID) TWL_CLASS_IS(4030, TWL4030_CLASS_ID)
TWL_CLASS_IS(6030, TWL6030_CLASS_ID) TWL_CLASS_IS(6030, TWL6030_CLASS_ID)
/* Set the regcache bypass for the regmap associated with the nodule */
int twl_set_regcache_bypass(u8 mod_no, bool enable);
/* /*
* Read and write several 8-bit registers at once. * Read and write several 8-bit registers at once.
*/ */
...@@ -667,8 +670,6 @@ struct twl4030_codec_data { ...@@ -667,8 +670,6 @@ struct twl4030_codec_data {
unsigned int digimic_delay; /* in ms */ unsigned int digimic_delay; /* in ms */
unsigned int ramp_delay_value; unsigned int ramp_delay_value;
unsigned int offset_cncl_path; unsigned int offset_cncl_path;
unsigned int check_defaults:1;
unsigned int reset_registers:1;
unsigned int hs_extmute:1; unsigned int hs_extmute:1;
int hs_extmute_gpio; int hs_extmute_gpio;
}; };
......
...@@ -226,6 +226,9 @@ ...@@ -226,6 +226,9 @@
#define ARIZONA_PDM_SPK1_CTRL_2 0x491 #define ARIZONA_PDM_SPK1_CTRL_2 0x491
#define ARIZONA_PDM_SPK2_CTRL_1 0x492 #define ARIZONA_PDM_SPK2_CTRL_1 0x492
#define ARIZONA_PDM_SPK2_CTRL_2 0x493 #define ARIZONA_PDM_SPK2_CTRL_2 0x493
#define ARIZONA_HP1_SHORT_CIRCUIT_CTRL 0x4A0
#define ARIZONA_HP2_SHORT_CIRCUIT_CTRL 0x4A1
#define ARIZONA_HP3_SHORT_CIRCUIT_CTRL 0x4A2
#define ARIZONA_SPK_CTRL_2 0x4B5 #define ARIZONA_SPK_CTRL_2 0x4B5
#define ARIZONA_SPK_CTRL_3 0x4B6 #define ARIZONA_SPK_CTRL_3 0x4B6
#define ARIZONA_DAC_COMP_1 0x4DC #define ARIZONA_DAC_COMP_1 0x4DC
...@@ -3332,6 +3335,30 @@ ...@@ -3332,6 +3335,30 @@
#define ARIZONA_SPK2_FMT_SHIFT 0 /* SPK2_FMT */ #define ARIZONA_SPK2_FMT_SHIFT 0 /* SPK2_FMT */
#define ARIZONA_SPK2_FMT_WIDTH 1 /* SPK2_FMT */ #define ARIZONA_SPK2_FMT_WIDTH 1 /* SPK2_FMT */
/*
* R1184 (0x4A0) - HP1 Short Circuit Ctrl
*/
#define ARIZONA_HP1_SC_ENA 0x1000 /* HP1_SC_ENA */
#define ARIZONA_HP1_SC_ENA_MASK 0x1000 /* HP1_SC_ENA */
#define ARIZONA_HP1_SC_ENA_SHIFT 12 /* HP1_SC_ENA */
#define ARIZONA_HP1_SC_ENA_WIDTH 1 /* HP1_SC_ENA */
/*
* R1185 (0x4A1) - HP2 Short Circuit Ctrl
*/
#define ARIZONA_HP2_SC_ENA 0x1000 /* HP2_SC_ENA */
#define ARIZONA_HP2_SC_ENA_MASK 0x1000 /* HP2_SC_ENA */
#define ARIZONA_HP2_SC_ENA_SHIFT 12 /* HP2_SC_ENA */
#define ARIZONA_HP2_SC_ENA_WIDTH 1 /* HP2_SC_ENA */
/*
* R1186 (0x4A2) - HP3 Short Circuit Ctrl
*/
#define ARIZONA_HP3_SC_ENA 0x1000 /* HP3_SC_ENA */
#define ARIZONA_HP3_SC_ENA_MASK 0x1000 /* HP3_SC_ENA */
#define ARIZONA_HP3_SC_ENA_SHIFT 12 /* HP3_SC_ENA */
#define ARIZONA_HP3_SC_ENA_WIDTH 1 /* HP3_SC_ENA */
/* /*
* R1244 (0x4DC) - DAC comp 1 * R1244 (0x4DC) - DAC comp 1
*/ */
......
...@@ -10,16 +10,9 @@ ...@@ -10,16 +10,9 @@
#include <linux/platform_data/dma-ste-dma40.h> #include <linux/platform_data/dma-ste-dma40.h>
enum msp_i2s_id {
MSP_I2S_0 = 0,
MSP_I2S_1,
MSP_I2S_2,
MSP_I2S_3,
};
/* Platform data structure for a MSP I2S-device */ /* Platform data structure for a MSP I2S-device */
struct msp_i2s_platform_data { struct msp_i2s_platform_data {
enum msp_i2s_id id; int id;
struct stedma40_chan_cfg *msp_i2s_dma_rx; struct stedma40_chan_cfg *msp_i2s_dma_rx;
struct stedma40_chan_cfg *msp_i2s_dma_tx; struct stedma40_chan_cfg *msp_i2s_dma_tx;
}; };
......
...@@ -900,6 +900,8 @@ extern const struct snd_pcm_hw_constraint_list snd_pcm_known_rates; ...@@ -900,6 +900,8 @@ extern const struct snd_pcm_hw_constraint_list snd_pcm_known_rates;
int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime); int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime);
unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate); unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate);
unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit); unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit);
unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a,
unsigned int rates_b);
static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream, static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream,
struct snd_dma_buffer *bufp) struct snd_dma_buffer *bufp)
......
...@@ -123,6 +123,8 @@ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate); ...@@ -123,6 +123,8 @@ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute, int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
int direction); int direction);
int snd_soc_dai_is_dummy(struct snd_soc_dai *dai);
struct snd_soc_dai_ops { struct snd_soc_dai_ops {
/* /*
* DAI clocking configuration, all optional. * DAI clocking configuration, all optional.
......
...@@ -412,6 +412,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, ...@@ -412,6 +412,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
struct snd_soc_dai *dai); struct snd_soc_dai *dai);
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card); int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);
int snd_soc_dapm_new_pcm(struct snd_soc_card *card, int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
const struct snd_soc_pcm_stream *params, const struct snd_soc_pcm_stream *params,
struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *source,
......
...@@ -895,6 +895,10 @@ struct snd_soc_dai_link { ...@@ -895,6 +895,10 @@ struct snd_soc_dai_link {
/* This DAI link can route to other DAI links at runtime (Frontend)*/ /* This DAI link can route to other DAI links at runtime (Frontend)*/
unsigned int dynamic:1; unsigned int dynamic:1;
/* DPCM capture and Playback support */
unsigned int dpcm_capture:1;
unsigned int dpcm_playback:1;
/* pmdown_time is ignored at stop */ /* pmdown_time is ignored at stop */
unsigned int ignore_pmdown_time:1; unsigned int ignore_pmdown_time:1;
......
...@@ -514,3 +514,42 @@ unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit) ...@@ -514,3 +514,42 @@ unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit)
return 0; return 0;
} }
EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate); EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate);
static unsigned int snd_pcm_rate_mask_sanitize(unsigned int rates)
{
if (rates & SNDRV_PCM_RATE_CONTINUOUS)
return SNDRV_PCM_RATE_CONTINUOUS;
else if (rates & SNDRV_PCM_RATE_KNOT)
return SNDRV_PCM_RATE_KNOT;
return rates;
}
/**
* snd_pcm_rate_mask_intersect - computes the intersection between two rate masks
* @rates_a: The first rate mask
* @rates_b: The second rate mask
*
* This function computes the rates that are supported by both rate masks passed
* to the function. It will take care of the special handling of
* SNDRV_PCM_RATE_CONTINUOUS and SNDRV_PCM_RATE_KNOT.
*
* Return: A rate mask containing the rates that are supported by both rates_a
* and rates_b.
*/
unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a,
unsigned int rates_b)
{
rates_a = snd_pcm_rate_mask_sanitize(rates_a);
rates_b = snd_pcm_rate_mask_sanitize(rates_b);
if (rates_a & SNDRV_PCM_RATE_CONTINUOUS)
return rates_b;
else if (rates_b & SNDRV_PCM_RATE_CONTINUOUS)
return rates_a;
else if (rates_a & SNDRV_PCM_RATE_KNOT)
return rates_b;
else if (rates_b & SNDRV_PCM_RATE_KNOT)
return rates_a;
return rates_a & rates_b;
}
EXPORT_SYMBOL_GPL(snd_pcm_rate_mask_intersect);
...@@ -236,8 +236,7 @@ static int axi_i2s_probe(struct platform_device *pdev) ...@@ -236,8 +236,7 @@ static int axi_i2s_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_clk_disable; goto err_clk_disable;
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
if (ret) if (ret)
goto err_clk_disable; goto err_clk_disable;
......
...@@ -229,8 +229,7 @@ static int axi_spdif_probe(struct platform_device *pdev) ...@@ -229,8 +229,7 @@ static int axi_spdif_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_clk_disable; goto err_clk_disable;
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
if (ret) if (ret)
goto err_clk_disable; goto err_clk_disable;
......
...@@ -50,7 +50,6 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = { ...@@ -50,7 +50,6 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = {
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_PAUSE, SNDRV_PCM_INFO_PAUSE,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.period_bytes_min = 256, /* lighting DMA overhead */ .period_bytes_min = 256, /* lighting DMA overhead */
.period_bytes_max = 2 * 0xffff, /* if 2 bytes format */ .period_bytes_max = 2 * 0xffff, /* if 2 bytes format */
.periods_min = 8, .periods_min = 8,
......
...@@ -58,7 +58,6 @@ static const struct snd_pcm_hardware atmel_pcm_hardware = { ...@@ -58,7 +58,6 @@ static const struct snd_pcm_hardware atmel_pcm_hardware = {
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE, SNDRV_PCM_INFO_PAUSE,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.period_bytes_min = 32, .period_bytes_min = 32,
.period_bytes_max = 8192, .period_bytes_max = 8192,
.periods_min = 2, .periods_min = 2,
......
config SND_BCM2835_SOC_I2S config SND_BCM2835_SOC_I2S
tristate "SoC Audio support for the Broadcom BCM2835 I2S module" tristate "SoC Audio support for the Broadcom BCM2835 I2S module"
depends on ARCH_BCM2835 || COMPILE_TEST depends on ARCH_BCM2835 || COMPILE_TEST
select SND_SOC_DMAENGINE_PCM
select SND_SOC_GENERIC_DMAENGINE_PCM select SND_SOC_GENERIC_DMAENGINE_PCM
select REGMAP_MMIO select REGMAP_MMIO
help help
......
...@@ -168,15 +168,15 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream, ...@@ -168,15 +168,15 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
int word_len = 0; int word_len = 0;
/* bit size */ /* bit size */
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
word_len = AD1836_WORD_LEN_16; word_len = AD1836_WORD_LEN_16;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
word_len = AD1836_WORD_LEN_20; word_len = AD1836_WORD_LEN_20;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
case SNDRV_PCM_FORMAT_S32_LE: case 32:
word_len = AD1836_WORD_LEN_24; word_len = AD1836_WORD_LEN_24;
break; break;
default: default:
......
...@@ -249,15 +249,15 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream, ...@@ -249,15 +249,15 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
/* bit size */ /* bit size */
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
word_len = 3; word_len = 3;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
word_len = 1; word_len = 1;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
case SNDRV_PCM_FORMAT_S32_LE: case 32:
word_len = 0; word_len = 0;
break; break;
} }
......
...@@ -1078,17 +1078,17 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream, ...@@ -1078,17 +1078,17 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream,
ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK, ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK,
(div << 2) | ADAU1373_BCLKDIV_64); (div << 2) | ADAU1373_BCLKDIV_64);
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
ctrl = ADAU1373_DAI_WLEN_16; ctrl = ADAU1373_DAI_WLEN_16;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
ctrl = ADAU1373_DAI_WLEN_20; ctrl = ADAU1373_DAI_WLEN_20;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
ctrl = ADAU1373_DAI_WLEN_24; ctrl = ADAU1373_DAI_WLEN_24;
break; break;
case SNDRV_PCM_FORMAT_S32_LE: case 32:
ctrl = ADAU1373_DAI_WLEN_32; ctrl = ADAU1373_DAI_WLEN_32;
break; break;
default: default:
......
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
#define ADAU1701_SEROCTL_WORD_LEN_24 0x0000 #define ADAU1701_SEROCTL_WORD_LEN_24 0x0000
#define ADAU1701_SEROCTL_WORD_LEN_20 0x0001 #define ADAU1701_SEROCTL_WORD_LEN_20 0x0001
#define ADAU1701_SEROCTL_WORD_LEN_16 0x0010 #define ADAU1701_SEROCTL_WORD_LEN_16 0x0002
#define ADAU1701_SEROCTL_WORD_LEN_MASK 0x0003 #define ADAU1701_SEROCTL_WORD_LEN_MASK 0x0003
#define ADAU1701_AUXNPOW_VBPD 0x40 #define ADAU1701_AUXNPOW_VBPD 0x40
...@@ -299,20 +299,20 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv) ...@@ -299,20 +299,20 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
} }
static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
snd_pcm_format_t format) struct snd_pcm_hw_params *params)
{ {
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK; unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK;
unsigned int val; unsigned int val;
switch (format) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
val = ADAU1701_SEROCTL_WORD_LEN_16; val = ADAU1701_SEROCTL_WORD_LEN_16;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
val = ADAU1701_SEROCTL_WORD_LEN_20; val = ADAU1701_SEROCTL_WORD_LEN_20;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
val = ADAU1701_SEROCTL_WORD_LEN_24; val = ADAU1701_SEROCTL_WORD_LEN_24;
break; break;
default: default:
...@@ -320,14 +320,14 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, ...@@ -320,14 +320,14 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
} }
if (adau1701->dai_fmt == SND_SOC_DAIFMT_RIGHT_J) { if (adau1701->dai_fmt == SND_SOC_DAIFMT_RIGHT_J) {
switch (format) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
val |= ADAU1701_SEROCTL_MSB_DEALY16; val |= ADAU1701_SEROCTL_MSB_DEALY16;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
val |= ADAU1701_SEROCTL_MSB_DEALY12; val |= ADAU1701_SEROCTL_MSB_DEALY12;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
val |= ADAU1701_SEROCTL_MSB_DEALY8; val |= ADAU1701_SEROCTL_MSB_DEALY8;
break; break;
} }
...@@ -340,7 +340,7 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, ...@@ -340,7 +340,7 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
} }
static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec, static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
snd_pcm_format_t format) struct snd_pcm_hw_params *params)
{ {
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
unsigned int val; unsigned int val;
...@@ -348,14 +348,14 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec, ...@@ -348,14 +348,14 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
if (adau1701->dai_fmt != SND_SOC_DAIFMT_RIGHT_J) if (adau1701->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
return 0; return 0;
switch (format) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
val = ADAU1701_SERICTL_RIGHTJ_16; val = ADAU1701_SERICTL_RIGHTJ_16;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
val = ADAU1701_SERICTL_RIGHTJ_20; val = ADAU1701_SERICTL_RIGHTJ_20;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
val = ADAU1701_SERICTL_RIGHTJ_24; val = ADAU1701_SERICTL_RIGHTJ_24;
break; break;
default: default:
...@@ -374,7 +374,6 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream, ...@@ -374,7 +374,6 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
unsigned int clkdiv = adau1701->sysclk / params_rate(params); unsigned int clkdiv = adau1701->sysclk / params_rate(params);
snd_pcm_format_t format;
unsigned int val; unsigned int val;
int ret; int ret;
...@@ -406,11 +405,10 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream, ...@@ -406,11 +405,10 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL, regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL,
ADAU1701_DSPCTRL_SR_MASK, val); ADAU1701_DSPCTRL_SR_MASK, val);
format = params_format(params);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return adau1701_set_playback_pcm_format(codec, format); return adau1701_set_playback_pcm_format(codec, params);
else else
return adau1701_set_capture_pcm_format(codec, format); return adau1701_set_capture_pcm_format(codec, params);
} }
static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai, static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
......
...@@ -453,22 +453,22 @@ static int adav80x_set_dac_clock(struct snd_soc_codec *codec, ...@@ -453,22 +453,22 @@ static int adav80x_set_dac_clock(struct snd_soc_codec *codec,
} }
static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec, static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec,
struct snd_soc_dai *dai, snd_pcm_format_t format) struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
{ {
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
unsigned int val; unsigned int val;
switch (format) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
val = ADAV80X_CAPTURE_WORD_LEN16; val = ADAV80X_CAPTURE_WORD_LEN16;
break; break;
case SNDRV_PCM_FORMAT_S18_3LE: case 18:
val = ADAV80X_CAPTRUE_WORD_LEN18; val = ADAV80X_CAPTRUE_WORD_LEN18;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
val = ADAV80X_CAPTURE_WORD_LEN20; val = ADAV80X_CAPTURE_WORD_LEN20;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
val = ADAV80X_CAPTURE_WORD_LEN24; val = ADAV80X_CAPTURE_WORD_LEN24;
break; break;
default: default:
...@@ -482,7 +482,7 @@ static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec, ...@@ -482,7 +482,7 @@ static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec,
} }
static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec, static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec,
struct snd_soc_dai *dai, snd_pcm_format_t format) struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
{ {
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
unsigned int val; unsigned int val;
...@@ -490,17 +490,17 @@ static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec, ...@@ -490,17 +490,17 @@ static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec,
if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J) if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J)
return 0; return 0;
switch (format) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_16; val = ADAV80X_PLAYBACK_MODE_RIGHT_J_16;
break; break;
case SNDRV_PCM_FORMAT_S18_3LE: case 18:
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_18; val = ADAV80X_PLAYBACK_MODE_RIGHT_J_18;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_20; val = ADAV80X_PLAYBACK_MODE_RIGHT_J_20;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_24; val = ADAV80X_PLAYBACK_MODE_RIGHT_J_24;
break; break;
default: default:
...@@ -524,12 +524,10 @@ static int adav80x_hw_params(struct snd_pcm_substream *substream, ...@@ -524,12 +524,10 @@ static int adav80x_hw_params(struct snd_pcm_substream *substream,
return -EINVAL; return -EINVAL;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
adav80x_set_playback_pcm_format(codec, dai, adav80x_set_playback_pcm_format(codec, dai, params);
params_format(params));
adav80x_set_dac_clock(codec, rate); adav80x_set_dac_clock(codec, rate);
} else { } else {
adav80x_set_capture_pcm_format(codec, dai, adav80x_set_capture_pcm_format(codec, dai, params);
params_format(params));
adav80x_set_adc_clock(codec, rate); adav80x_set_adc_clock(codec, rate);
} }
adav80x->rate = rate; adav80x->rate = rate;
......
...@@ -714,17 +714,17 @@ static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -714,17 +714,17 @@ static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
iface &= ~ALC5623_DAI_I2S_DL_MASK; iface &= ~ALC5623_DAI_I2S_DL_MASK;
/* bit size */ /* bit size */
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
iface |= ALC5623_DAI_I2S_DL_16; iface |= ALC5623_DAI_I2S_DL_16;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
iface |= ALC5623_DAI_I2S_DL_20; iface |= ALC5623_DAI_I2S_DL_20;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
iface |= ALC5623_DAI_I2S_DL_24; iface |= ALC5623_DAI_I2S_DL_24;
break; break;
case SNDRV_PCM_FORMAT_S32_LE: case 32:
iface |= ALC5623_DAI_I2S_DL_32; iface |= ALC5623_DAI_I2S_DL_32;
break; break;
default: default:
......
...@@ -869,14 +869,14 @@ static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -869,14 +869,14 @@ static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
iface &= ~ALC5632_DAI_I2S_DL_MASK; iface &= ~ALC5632_DAI_I2S_DL_MASK;
/* bit size */ /* bit size */
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
iface |= ALC5632_DAI_I2S_DL_16; iface |= ALC5632_DAI_I2S_DL_16;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
iface |= ALC5632_DAI_I2S_DL_20; iface |= ALC5632_DAI_I2S_DL_20;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
iface |= ALC5632_DAI_I2S_DL_24; iface |= ALC5632_DAI_I2S_DL_24;
break; break;
default: default:
......
...@@ -166,20 +166,21 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ...@@ -166,20 +166,21 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") ARIZONA_MIXER_INPUT_ROUTES(name " Input 4")
#define ARIZONA_DSP_ROUTES(name) \ #define ARIZONA_DSP_ROUTES(name) \
{ name, NULL, name " Aux 1" }, \ { name, NULL, name " Preloader"}, \
{ name, NULL, name " Aux 2" }, \ { name " Preloader", NULL, name " Aux 1" }, \
{ name, NULL, name " Aux 3" }, \ { name " Preloader", NULL, name " Aux 2" }, \
{ name, NULL, name " Aux 4" }, \ { name " Preloader", NULL, name " Aux 3" }, \
{ name, NULL, name " Aux 5" }, \ { name " Preloader", NULL, name " Aux 4" }, \
{ name, NULL, name " Aux 6" }, \ { name " Preloader", NULL, name " Aux 5" }, \
{ name " Preloader", NULL, name " Aux 6" }, \
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \
ARIZONA_MIXER_ROUTES(name, name "L"), \ ARIZONA_MIXER_ROUTES(name " Preloader", name "L"), \
ARIZONA_MIXER_ROUTES(name, name "R") ARIZONA_MIXER_ROUTES(name " Preloader", name "R")
#define ARIZONA_RATE_ENUM_SIZE 4 #define ARIZONA_RATE_ENUM_SIZE 4
extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];
......
...@@ -423,21 +423,17 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream, ...@@ -423,21 +423,17 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24); intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24);
break; break;
case SND_SOC_DAIFMT_RIGHT_J: case SND_SOC_DAIFMT_RIGHT_J:
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
case SNDRV_PCM_FORMAT_S16_BE:
fmt = CS42L51_DAC_DIF_RJ16; fmt = CS42L51_DAC_DIF_RJ16;
break; break;
case SNDRV_PCM_FORMAT_S18_3LE: case 18:
case SNDRV_PCM_FORMAT_S18_3BE:
fmt = CS42L51_DAC_DIF_RJ18; fmt = CS42L51_DAC_DIF_RJ18;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
case SNDRV_PCM_FORMAT_S20_3BE:
fmt = CS42L51_DAC_DIF_RJ20; fmt = CS42L51_DAC_DIF_RJ20;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
case SNDRV_PCM_FORMAT_S24_BE:
fmt = CS42L51_DAC_DIF_RJ24; fmt = CS42L51_DAC_DIF_RJ24;
break; break;
default: default:
......
...@@ -778,17 +778,17 @@ static int da7210_hw_params(struct snd_pcm_substream *substream, ...@@ -778,17 +778,17 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1); dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1);
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
dai_cfg1 |= DA7210_DAI_WORD_S16_LE; dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
dai_cfg1 |= DA7210_DAI_WORD_S20_3LE; dai_cfg1 |= DA7210_DAI_WORD_S20_3LE;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
dai_cfg1 |= DA7210_DAI_WORD_S24_LE; dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
break; break;
case SNDRV_PCM_FORMAT_S32_LE: case 32:
dai_cfg1 |= DA7210_DAI_WORD_S32_LE; dai_cfg1 |= DA7210_DAI_WORD_S32_LE;
break; break;
default: default:
......
...@@ -1067,17 +1067,17 @@ static int da7213_hw_params(struct snd_pcm_substream *substream, ...@@ -1067,17 +1067,17 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
u8 fs; u8 fs;
/* Set DAI format */ /* Set DAI format */
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S16_LE; dai_ctrl |= DA7213_DAI_WORD_LENGTH_S16_LE;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S20_LE; dai_ctrl |= DA7213_DAI_WORD_LENGTH_S20_LE;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S24_LE; dai_ctrl |= DA7213_DAI_WORD_LENGTH_S24_LE;
break; break;
case SNDRV_PCM_FORMAT_S32_LE: case 32:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S32_LE; dai_ctrl |= DA7213_DAI_WORD_LENGTH_S32_LE;
break; break;
default: default:
......
...@@ -973,17 +973,17 @@ static int da732x_hw_params(struct snd_pcm_substream *substream, ...@@ -973,17 +973,17 @@ static int da732x_hw_params(struct snd_pcm_substream *substream,
reg_aif = dai->driver->base; reg_aif = dai->driver->base;
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
aif |= DA732X_AIF_WORD_16; aif |= DA732X_AIF_WORD_16;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
aif |= DA732X_AIF_WORD_20; aif |= DA732X_AIF_WORD_20;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
aif |= DA732X_AIF_WORD_24; aif |= DA732X_AIF_WORD_24;
break; break;
case SNDRV_PCM_FORMAT_S32_LE: case 32:
aif |= DA732X_AIF_WORD_32; aif |= DA732X_AIF_WORD_32;
break; break;
default: default:
......
...@@ -1058,17 +1058,17 @@ static int da9055_hw_params(struct snd_pcm_substream *substream, ...@@ -1058,17 +1058,17 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
u8 aif_ctrl, fs; u8 aif_ctrl, fs;
u32 sysclk; u32 sysclk;
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
aif_ctrl = DA9055_AIF_WORD_S16_LE; aif_ctrl = DA9055_AIF_WORD_S16_LE;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
aif_ctrl = DA9055_AIF_WORD_S20_3LE; aif_ctrl = DA9055_AIF_WORD_S20_3LE;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
aif_ctrl = DA9055_AIF_WORD_S24_LE; aif_ctrl = DA9055_AIF_WORD_S24_LE;
break; break;
case SNDRV_PCM_FORMAT_S32_LE: case 32:
aif_ctrl = DA9055_AIF_WORD_S32_LE; aif_ctrl = DA9055_AIF_WORD_S32_LE;
break; break;
default: default:
......
...@@ -951,11 +951,11 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream, ...@@ -951,11 +951,11 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
ISABELLE_FS_RATE_MASK, fs_val); ISABELLE_FS_RATE_MASK, fs_val);
/* bit size */ /* bit size */
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
aif |= ISABELLE_AIF_LENGTH_20; aif |= ISABELLE_AIF_LENGTH_20;
break; break;
case SNDRV_PCM_FORMAT_S32_LE: case 32:
aif |= ISABELLE_AIF_LENGTH_32; aif |= ISABELLE_AIF_LENGTH_32;
break; break;
default: default:
......
...@@ -1233,12 +1233,12 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream, ...@@ -1233,12 +1233,12 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,
rate = params_rate(params); rate = params_rate(params);
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT, snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
M98088_DAI_WS, 0); M98088_DAI_WS, 0);
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT, snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
M98088_DAI_WS, M98088_DAI_WS); M98088_DAI_WS, M98088_DAI_WS);
break; break;
......
...@@ -1840,8 +1840,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream, ...@@ -1840,8 +1840,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
max98090->lrclk = params_rate(params); max98090->lrclk = params_rate(params);
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
snd_soc_update_bits(codec, M98090_REG_INTERFACE_FORMAT, snd_soc_update_bits(codec, M98090_REG_INTERFACE_FORMAT,
M98090_WS_MASK, 0); M98090_WS_MASK, 0);
break; break;
......
...@@ -1213,12 +1213,12 @@ static int max98095_dai1_hw_params(struct snd_pcm_substream *substream, ...@@ -1213,12 +1213,12 @@ static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
rate = params_rate(params); rate = params_rate(params);
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT, snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
M98095_DAI_WS, 0); M98095_DAI_WS, 0);
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT, snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
M98095_DAI_WS, M98095_DAI_WS); M98095_DAI_WS, M98095_DAI_WS);
break; break;
......
...@@ -149,14 +149,14 @@ static int max9850_hw_params(struct snd_pcm_substream *substream, ...@@ -149,14 +149,14 @@ static int max9850_hw_params(struct snd_pcm_substream *substream,
snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f); snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f);
snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff); snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff);
switch (params_format(params)) { switch (params_width(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case 16:
da = 0; da = 0;
break; break;
case SNDRV_PCM_FORMAT_S20_3LE: case 20:
da = 0x2; da = 0x2;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case 24:
da = 0x3; da = 0x3;
break; break;
default: default:
......
...@@ -750,30 +750,26 @@ static struct snd_soc_codec_driver soc_codec_dev_mc13783 = { ...@@ -750,30 +750,26 @@ static struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
.num_dapm_routes = ARRAY_SIZE(mc13783_routes), .num_dapm_routes = ARRAY_SIZE(mc13783_routes),
}; };
static int mc13783_codec_probe(struct platform_device *pdev) static int __init mc13783_codec_probe(struct platform_device *pdev)
{ {
struct mc13xxx *mc13xxx;
struct mc13783_priv *priv; struct mc13783_priv *priv;
struct mc13xxx_codec_platform_data *pdata = pdev->dev.platform_data; struct mc13xxx_codec_platform_data *pdata = pdev->dev.platform_data;
int ret; int ret;
mc13xxx = dev_get_drvdata(pdev->dev.parent);
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (priv == NULL) if (!priv)
return -ENOMEM; return -ENOMEM;
dev_set_drvdata(&pdev->dev, priv);
priv->mc13xxx = mc13xxx;
if (pdata) { if (pdata) {
priv->adc_ssi_port = pdata->adc_ssi_port; priv->adc_ssi_port = pdata->adc_ssi_port;
priv->dac_ssi_port = pdata->dac_ssi_port; priv->dac_ssi_port = pdata->dac_ssi_port;
} else { } else {
priv->adc_ssi_port = MC13783_SSI1_PORT; return -ENOSYS;
priv->dac_ssi_port = MC13783_SSI2_PORT;
} }
dev_set_drvdata(&pdev->dev, priv);
priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
if (priv->adc_ssi_port == priv->dac_ssi_port) if (priv->adc_ssi_port == priv->dac_ssi_port)
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783, ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
mc13783_dai_sync, ARRAY_SIZE(mc13783_dai_sync)); mc13783_dai_sync, ARRAY_SIZE(mc13783_dai_sync));
...@@ -781,14 +777,6 @@ static int mc13783_codec_probe(struct platform_device *pdev) ...@@ -781,14 +777,6 @@ static int mc13783_codec_probe(struct platform_device *pdev)
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783, ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
mc13783_dai_async, ARRAY_SIZE(mc13783_dai_async)); mc13783_dai_async, ARRAY_SIZE(mc13783_dai_async));
if (ret)
goto err_register_codec;
return 0;
err_register_codec:
dev_err(&pdev->dev, "register codec failed with %d\n", ret);
return ret; return ret;
} }
...@@ -801,14 +789,12 @@ static int mc13783_codec_remove(struct platform_device *pdev) ...@@ -801,14 +789,12 @@ static int mc13783_codec_remove(struct platform_device *pdev)
static struct platform_driver mc13783_codec_driver = { static struct platform_driver mc13783_codec_driver = {
.driver = { .driver = {
.name = "mc13783-codec", .name = "mc13783-codec",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = mc13783_codec_probe,
.remove = mc13783_codec_remove, .remove = mc13783_codec_remove,
}; };
module_platform_driver_probe(mc13783_codec_driver, mc13783_codec_probe);
module_platform_driver(mc13783_codec_driver);
MODULE_DESCRIPTION("ASoC MC13783 driver"); MODULE_DESCRIPTION("ASoC MC13783 driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>"); MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>");
......
...@@ -194,7 +194,7 @@ static const struct snd_soc_dapm_route ssm2604_routes[] = { ...@@ -194,7 +194,7 @@ static const struct snd_soc_dapm_route ssm2604_routes[] = {
}; };
static const unsigned int ssm2602_rates_12288000[] = { static const unsigned int ssm2602_rates_12288000[] = {
8000, 32000, 48000, 96000, 8000, 16000, 32000, 48000, 96000,
}; };
static struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = { static struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = {
...@@ -231,6 +231,11 @@ static const struct ssm2602_coeff ssm2602_coeff_table[] = { ...@@ -231,6 +231,11 @@ static const struct ssm2602_coeff ssm2602_coeff_table[] = {
{18432000, 32000, SSM2602_COEFF_SRATE(0x6, 0x1, 0x0)}, {18432000, 32000, SSM2602_COEFF_SRATE(0x6, 0x1, 0x0)},
{12000000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x1)}, {12000000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x1)},
/* 16k */
{12288000, 16000, SSM2602_COEFF_SRATE(0x5, 0x0, 0x0)},
{18432000, 16000, SSM2602_COEFF_SRATE(0x5, 0x1, 0x0)},
{12000000, 16000, SSM2602_COEFF_SRATE(0xa, 0x0, 0x1)},
/* 8k */ /* 8k */
{12288000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x0)}, {12288000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x0)},
{18432000, 8000, SSM2602_COEFF_SRATE(0x3, 0x1, 0x0)}, {18432000, 8000, SSM2602_COEFF_SRATE(0x3, 0x1, 0x0)},
...@@ -473,9 +478,10 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec, ...@@ -473,9 +478,10 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
return 0; return 0;
} }
#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 |\ #define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
SNDRV_PCM_RATE_96000)
#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ #define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
......
...@@ -267,8 +267,8 @@ static const struct regmap_range_cfg aic32x4_regmap_pages[] = { ...@@ -267,8 +267,8 @@ static const struct regmap_range_cfg aic32x4_regmap_pages[] = {
.selector_mask = 0xff, .selector_mask = 0xff,
.window_start = 0, .window_start = 0,
.window_len = 128, .window_len = 128,
.range_min = AIC32X4_PAGE1, .range_min = 0,
.range_max = AIC32X4_PAGE1 + 127, .range_max = AIC32X4_RMICPGAVOL,
}, },
}; };
......
此差异已折叠。
...@@ -313,6 +313,13 @@ ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), ...@@ -313,6 +313,13 @@ ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("SPKDAT2L", ARIZONA_OUT6LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT2L", ARIZONA_OUT6LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("SPKDAT2R", ARIZONA_OUT6RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT2R", ARIZONA_OUT6RMIX_INPUT_1_SOURCE),
SOC_SINGLE("HPOUT1 SC Protect Switch", ARIZONA_HP1_SHORT_CIRCUIT_CTRL,
ARIZONA_HP1_SC_ENA_SHIFT, 1, 0),
SOC_SINGLE("HPOUT2 SC Protect Switch", ARIZONA_HP2_SHORT_CIRCUIT_CTRL,
ARIZONA_HP2_SC_ENA_SHIFT, 1, 0),
SOC_SINGLE("HPOUT3 SC Protect Switch", ARIZONA_HP3_SHORT_CIRCUIT_CTRL,
ARIZONA_HP3_SC_ENA_SHIFT, 1, 0),
SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L, SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1), ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L, SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
......
...@@ -1497,107 +1497,149 @@ static int wm_adsp2_ena(struct wm_adsp *dsp) ...@@ -1497,107 +1497,149 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
return 0; return 0;
} }
int wm_adsp2_event(struct snd_soc_dapm_widget *w, static void wm_adsp2_boot_work(struct work_struct *work)
struct snd_kcontrol *kcontrol, int event)
{ {
struct snd_soc_codec *codec = w->codec; struct wm_adsp *dsp = container_of(work,
struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); struct wm_adsp,
struct wm_adsp *dsp = &dsps[w->shift]; boot_work);
struct wm_adsp_alg_region *alg_region;
struct wm_coeff_ctl *ctl;
unsigned int val;
int ret; int ret;
unsigned int val;
dsp->card = codec->card; /*
* For simplicity set the DSP clock rate to be the
* SYSCLK rate rather than making it configurable.
*/
ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
if (ret != 0) {
adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret);
return;
}
val = (val & ARIZONA_SYSCLK_FREQ_MASK)
>> ARIZONA_SYSCLK_FREQ_SHIFT;
switch (event) { ret = regmap_update_bits_async(dsp->regmap,
case SND_SOC_DAPM_POST_PMU: dsp->base + ADSP2_CLOCKING,
/* ADSP2_CLK_SEL_MASK, val);
* For simplicity set the DSP clock rate to be the if (ret != 0) {
* SYSCLK rate rather than making it configurable. adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
*/ return;
ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val); }
if (ret != 0) {
adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
ret);
return ret;
}
val = (val & ARIZONA_SYSCLK_FREQ_MASK)
>> ARIZONA_SYSCLK_FREQ_SHIFT;
ret = regmap_update_bits_async(dsp->regmap, if (dsp->dvfs) {
dsp->base + ADSP2_CLOCKING, ret = regmap_read(dsp->regmap,
ADSP2_CLK_SEL_MASK, val); dsp->base + ADSP2_CLOCKING, &val);
if (ret != 0) { if (ret != 0) {
adsp_err(dsp, "Failed to set clock rate: %d\n", dev_err(dsp->dev, "Failed to read clocking: %d\n", ret);
ret); return;
return ret;
} }
if (dsp->dvfs) { if ((val & ADSP2_CLK_SEL_MASK) >= 3) {
ret = regmap_read(dsp->regmap, ret = regulator_enable(dsp->dvfs);
dsp->base + ADSP2_CLOCKING, &val);
if (ret != 0) { if (ret != 0) {
dev_err(dsp->dev, dev_err(dsp->dev,
"Failed to read clocking: %d\n", ret); "Failed to enable supply: %d\n",
return ret; ret);
return;
} }
if ((val & ADSP2_CLK_SEL_MASK) >= 3) { ret = regulator_set_voltage(dsp->dvfs,
ret = regulator_enable(dsp->dvfs); 1800000,
if (ret != 0) { 1800000);
dev_err(dsp->dev, if (ret != 0) {
"Failed to enable supply: %d\n", dev_err(dsp->dev,
ret); "Failed to raise supply: %d\n",
return ret; ret);
} return;
ret = regulator_set_voltage(dsp->dvfs,
1800000,
1800000);
if (ret != 0) {
dev_err(dsp->dev,
"Failed to raise supply: %d\n",
ret);
return ret;
}
} }
} }
}
ret = wm_adsp2_ena(dsp); ret = wm_adsp2_ena(dsp);
if (ret != 0) if (ret != 0)
return ret; return;
ret = wm_adsp_load(dsp); ret = wm_adsp_load(dsp);
if (ret != 0) if (ret != 0)
goto err; goto err;
ret = wm_adsp_setup_algs(dsp); ret = wm_adsp_setup_algs(dsp);
if (ret != 0) if (ret != 0)
goto err; goto err;
ret = wm_adsp_load_coeff(dsp); ret = wm_adsp_load_coeff(dsp);
if (ret != 0) if (ret != 0)
goto err; goto err;
/* Initialize caches for enabled and unset controls */ /* Initialize caches for enabled and unset controls */
ret = wm_coeff_init_control_caches(dsp); ret = wm_coeff_init_control_caches(dsp);
if (ret != 0) if (ret != 0)
goto err; goto err;
/* Sync set controls */ /* Sync set controls */
ret = wm_coeff_sync_controls(dsp); ret = wm_coeff_sync_controls(dsp);
if (ret != 0) if (ret != 0)
goto err; goto err;
ret = regmap_update_bits_async(dsp->regmap,
dsp->base + ADSP2_CONTROL,
ADSP2_CORE_ENA,
ADSP2_CORE_ENA);
if (ret != 0)
goto err;
dsp->running = true;
return;
err:
regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
}
int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
struct wm_adsp *dsp = &dsps[w->shift];
dsp->card = codec->card;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
queue_work(system_unbound_wq, &dsp->boot_work);
break;
default:
break;
};
return 0;
}
EXPORT_SYMBOL_GPL(wm_adsp2_early_event);
int wm_adsp2_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
struct wm_adsp *dsp = &dsps[w->shift];
struct wm_adsp_alg_region *alg_region;
struct wm_coeff_ctl *ctl;
int ret;
switch (event) {
case SND_SOC_DAPM_POST_PMU:
flush_work(&dsp->boot_work);
if (!dsp->running)
return -EIO;
ret = regmap_update_bits_async(dsp->regmap, ret = regmap_update_bits(dsp->regmap,
dsp->base + ADSP2_CONTROL, dsp->base + ADSP2_CONTROL,
ADSP2_CORE_ENA | ADSP2_START, ADSP2_START,
ADSP2_CORE_ENA | ADSP2_START); ADSP2_START);
if (ret != 0) if (ret != 0)
goto err; goto err;
dsp->running = true;
break; break;
case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_PRE_PMD:
...@@ -1668,6 +1710,7 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) ...@@ -1668,6 +1710,7 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
INIT_LIST_HEAD(&adsp->alg_regions); INIT_LIST_HEAD(&adsp->alg_regions);
INIT_LIST_HEAD(&adsp->ctl_list); INIT_LIST_HEAD(&adsp->ctl_list);
INIT_WORK(&adsp->boot_work, wm_adsp2_boot_work);
if (dvfs) { if (dvfs) {
adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
......
...@@ -59,6 +59,8 @@ struct wm_adsp { ...@@ -59,6 +59,8 @@ struct wm_adsp {
struct regulator *dvfs; struct regulator *dvfs;
struct list_head ctl_list; struct list_head ctl_list;
struct work_struct boot_work;
}; };
#define WM_ADSP1(wname, num) \ #define WM_ADSP1(wname, num) \
...@@ -66,8 +68,12 @@ struct wm_adsp { ...@@ -66,8 +68,12 @@ struct wm_adsp {
wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
#define WM_ADSP2(wname, num) \ #define WM_ADSP2(wname, num) \
SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ { .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \
wm_adsp2_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_early_event, \
.event_flags = SND_SOC_DAPM_PRE_PMU }, \
{ .id = snd_soc_dapm_out_drv, .name = wname, \
.reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \
.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];
extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];
...@@ -76,6 +82,8 @@ int wm_adsp1_init(struct wm_adsp *adsp); ...@@ -76,6 +82,8 @@ int wm_adsp1_init(struct wm_adsp *adsp);
int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs);
int wm_adsp1_event(struct snd_soc_dapm_widget *w, int wm_adsp1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event); struct snd_kcontrol *kcontrol, int event);
int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
int wm_adsp2_event(struct snd_soc_dapm_widget *w, int wm_adsp2_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event); struct snd_kcontrol *kcontrol, int event);
......
...@@ -8,6 +8,9 @@ config SND_SOC_FSL_SSI ...@@ -8,6 +8,9 @@ config SND_SOC_FSL_SSI
config SND_SOC_FSL_SPDIF config SND_SOC_FSL_SPDIF
tristate tristate
config SND_SOC_FSL_ESAI
tristate
config SND_SOC_FSL_UTILS config SND_SOC_FSL_UTILS
tristate tristate
......
...@@ -14,11 +14,13 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o ...@@ -14,11 +14,13 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
snd-soc-fsl-sai-objs := fsl_sai.o snd-soc-fsl-sai-objs := fsl_sai.o
snd-soc-fsl-ssi-objs := fsl_ssi.o snd-soc-fsl-ssi-objs := fsl_ssi.o
snd-soc-fsl-spdif-objs := fsl_spdif.o snd-soc-fsl-spdif-objs := fsl_spdif.o
snd-soc-fsl-esai-objs := fsl_esai.o
snd-soc-fsl-utils-objs := fsl_utils.o snd-soc-fsl-utils-objs := fsl_utils.o
snd-soc-fsl-dma-objs := fsl_dma.o snd-soc-fsl-dma-objs := fsl_dma.o
obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.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_SPDIF) += snd-soc-fsl-spdif.o
obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o
obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
......
...@@ -55,10 +55,6 @@ ...@@ -55,10 +55,6 @@
SNDRV_PCM_FMTBIT_S32_BE | \ SNDRV_PCM_FMTBIT_S32_BE | \
SNDRV_PCM_FMTBIT_U32_LE | \ SNDRV_PCM_FMTBIT_U32_LE | \
SNDRV_PCM_FMTBIT_U32_BE) SNDRV_PCM_FMTBIT_U32_BE)
#define FSLDMA_PCM_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
SNDRV_PCM_RATE_CONTINUOUS)
struct dma_object { struct dma_object {
struct snd_soc_platform_driver dai; struct snd_soc_platform_driver dai;
dma_addr_t ssi_stx_phys; dma_addr_t ssi_stx_phys;
...@@ -140,9 +136,6 @@ static const struct snd_pcm_hardware fsl_dma_hardware = { ...@@ -140,9 +136,6 @@ static const struct snd_pcm_hardware fsl_dma_hardware = {
SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_JOINT_DUPLEX |
SNDRV_PCM_INFO_PAUSE, SNDRV_PCM_INFO_PAUSE,
.formats = FSLDMA_PCM_FORMATS, .formats = FSLDMA_PCM_FORMATS,
.rates = FSLDMA_PCM_RATES,
.rate_min = 5512,
.rate_max = 192000,
.period_bytes_min = 512, /* A reasonable limit */ .period_bytes_min = 512, /* A reasonable limit */
.period_bytes_max = (u32) -1, .period_bytes_max = (u32) -1,
.periods_min = NUM_DMA_LINKS, .periods_min = NUM_DMA_LINKS,
......
此差异已折叠。
/*
* fsl_esai.h - ALSA ESAI interface for the Freescale i.MX SoC
*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
*
* Author: Nicolin Chen <Guangyu.Chen@freescale.com>
*
* 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_ESAI_DAI_H
#define _FSL_ESAI_DAI_H
/* ESAI Register Map */
#define REG_ESAI_ETDR 0x00
#define REG_ESAI_ERDR 0x04
#define REG_ESAI_ECR 0x08
#define REG_ESAI_ESR 0x0C
#define REG_ESAI_TFCR 0x10
#define REG_ESAI_TFSR 0x14
#define REG_ESAI_RFCR 0x18
#define REG_ESAI_RFSR 0x1C
#define REG_ESAI_xFCR(tx) (tx ? REG_ESAI_TFCR : REG_ESAI_RFCR)
#define REG_ESAI_xFSR(tx) (tx ? REG_ESAI_TFSR : REG_ESAI_RFSR)
#define REG_ESAI_TX0 0x80
#define REG_ESAI_TX1 0x84
#define REG_ESAI_TX2 0x88
#define REG_ESAI_TX3 0x8C
#define REG_ESAI_TX4 0x90
#define REG_ESAI_TX5 0x94
#define REG_ESAI_TSR 0x98
#define REG_ESAI_RX0 0xA0
#define REG_ESAI_RX1 0xA4
#define REG_ESAI_RX2 0xA8
#define REG_ESAI_RX3 0xAC
#define REG_ESAI_SAISR 0xCC
#define REG_ESAI_SAICR 0xD0
#define REG_ESAI_TCR 0xD4
#define REG_ESAI_TCCR 0xD8
#define REG_ESAI_RCR 0xDC
#define REG_ESAI_RCCR 0xE0
#define REG_ESAI_xCR(tx) (tx ? REG_ESAI_TCR : REG_ESAI_RCR)
#define REG_ESAI_xCCR(tx) (tx ? REG_ESAI_TCCR : REG_ESAI_RCCR)
#define REG_ESAI_TSMA 0xE4
#define REG_ESAI_TSMB 0xE8
#define REG_ESAI_RSMA 0xEC
#define REG_ESAI_RSMB 0xF0
#define REG_ESAI_xSMA(tx) (tx ? REG_ESAI_TSMA : REG_ESAI_RSMA)
#define REG_ESAI_xSMB(tx) (tx ? REG_ESAI_TSMB : REG_ESAI_RSMB)
#define REG_ESAI_PRRC 0xF8
#define REG_ESAI_PCRC 0xFC
/* ESAI Control Register -- REG_ESAI_ECR 0x8 */
#define ESAI_ECR_ETI_SHIFT 19
#define ESAI_ECR_ETI_MASK (1 << ESAI_ECR_ETI_SHIFT)
#define ESAI_ECR_ETI (1 << ESAI_ECR_ETI_SHIFT)
#define ESAI_ECR_ETO_SHIFT 18
#define ESAI_ECR_ETO_MASK (1 << ESAI_ECR_ETO_SHIFT)
#define ESAI_ECR_ETO (1 << ESAI_ECR_ETO_SHIFT)
#define ESAI_ECR_ERI_SHIFT 17
#define ESAI_ECR_ERI_MASK (1 << ESAI_ECR_ERI_SHIFT)
#define ESAI_ECR_ERI (1 << ESAI_ECR_ERI_SHIFT)
#define ESAI_ECR_ERO_SHIFT 16
#define ESAI_ECR_ERO_MASK (1 << ESAI_ECR_ERO_SHIFT)
#define ESAI_ECR_ERO (1 << ESAI_ECR_ERO_SHIFT)
#define ESAI_ECR_ERST_SHIFT 1
#define ESAI_ECR_ERST_MASK (1 << ESAI_ECR_ERST_SHIFT)
#define ESAI_ECR_ERST (1 << ESAI_ECR_ERST_SHIFT)
#define ESAI_ECR_ESAIEN_SHIFT 0
#define ESAI_ECR_ESAIEN_MASK (1 << ESAI_ECR_ESAIEN_SHIFT)
#define ESAI_ECR_ESAIEN (1 << ESAI_ECR_ESAIEN_SHIFT)
/* ESAI Status Register -- REG_ESAI_ESR 0xC */
#define ESAI_ESR_TINIT_SHIFT 10
#define ESAI_ESR_TINIT_MASK (1 << ESAI_ESR_TINIT_SHIFT)
#define ESAI_ESR_TINIT (1 << ESAI_ESR_TINIT_SHIFT)
#define ESAI_ESR_RFF_SHIFT 9
#define ESAI_ESR_RFF_MASK (1 << ESAI_ESR_RFF_SHIFT)
#define ESAI_ESR_RFF (1 << ESAI_ESR_RFF_SHIFT)
#define ESAI_ESR_TFE_SHIFT 8
#define ESAI_ESR_TFE_MASK (1 << ESAI_ESR_TFE_SHIFT)
#define ESAI_ESR_TFE (1 << ESAI_ESR_TFE_SHIFT)
#define ESAI_ESR_TLS_SHIFT 7
#define ESAI_ESR_TLS_MASK (1 << ESAI_ESR_TLS_SHIFT)
#define ESAI_ESR_TLS (1 << ESAI_ESR_TLS_SHIFT)
#define ESAI_ESR_TDE_SHIFT 6
#define ESAI_ESR_TDE_MASK (1 << ESAI_ESR_TDE_SHIFT)
#define ESAI_ESR_TDE (1 << ESAI_ESR_TDE_SHIFT)
#define ESAI_ESR_TED_SHIFT 5
#define ESAI_ESR_TED_MASK (1 << ESAI_ESR_TED_SHIFT)
#define ESAI_ESR_TED (1 << ESAI_ESR_TED_SHIFT)
#define ESAI_ESR_TD_SHIFT 4
#define ESAI_ESR_TD_MASK (1 << ESAI_ESR_TD_SHIFT)
#define ESAI_ESR_TD (1 << ESAI_ESR_TD_SHIFT)
#define ESAI_ESR_RLS_SHIFT 3
#define ESAI_ESR_RLS_MASK (1 << ESAI_ESR_RLS_SHIFT)
#define ESAI_ESR_RLS (1 << ESAI_ESR_RLS_SHIFT)
#define ESAI_ESR_RDE_SHIFT 2
#define ESAI_ESR_RDE_MASK (1 << ESAI_ESR_RDE_SHIFT)
#define ESAI_ESR_RDE (1 << ESAI_ESR_RDE_SHIFT)
#define ESAI_ESR_RED_SHIFT 1
#define ESAI_ESR_RED_MASK (1 << ESAI_ESR_RED_SHIFT)
#define ESAI_ESR_RED (1 << ESAI_ESR_RED_SHIFT)
#define ESAI_ESR_RD_SHIFT 0
#define ESAI_ESR_RD_MASK (1 << ESAI_ESR_RD_SHIFT)
#define ESAI_ESR_RD (1 << ESAI_ESR_RD_SHIFT)
/*
* Transmit FIFO Configuration Register -- REG_ESAI_TFCR 0x10
* Receive FIFO Configuration Register -- REG_ESAI_RFCR 0x18
*/
#define ESAI_xFCR_TIEN_SHIFT 19
#define ESAI_xFCR_TIEN_MASK (1 << ESAI_xFCR_TIEN_SHIFT)
#define ESAI_xFCR_TIEN (1 << ESAI_xFCR_TIEN_SHIFT)
#define ESAI_xFCR_REXT_SHIFT 19
#define ESAI_xFCR_REXT_MASK (1 << ESAI_xFCR_REXT_SHIFT)
#define ESAI_xFCR_REXT (1 << ESAI_xFCR_REXT_SHIFT)
#define ESAI_xFCR_xWA_SHIFT 16
#define ESAI_xFCR_xWA_WIDTH 3
#define ESAI_xFCR_xWA_MASK (((1 << ESAI_xFCR_xWA_WIDTH) - 1) << ESAI_xFCR_xWA_SHIFT)
#define ESAI_xFCR_xWA(v) (((8 - ((v) >> 2)) << ESAI_xFCR_xWA_SHIFT) & ESAI_xFCR_xWA_MASK)
#define ESAI_xFCR_xFWM_SHIFT 8
#define ESAI_xFCR_xFWM_WIDTH 8
#define ESAI_xFCR_xFWM_MASK (((1 << ESAI_xFCR_xFWM_WIDTH) - 1) << ESAI_xFCR_xFWM_SHIFT)
#define ESAI_xFCR_xFWM(v) ((((v) - 1) << ESAI_xFCR_xFWM_SHIFT) & ESAI_xFCR_xFWM_MASK)
#define ESAI_xFCR_xE_SHIFT 2
#define ESAI_xFCR_TE_WIDTH 6
#define ESAI_xFCR_RE_WIDTH 4
#define ESAI_xFCR_TE_MASK (((1 << ESAI_xFCR_TE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT)
#define ESAI_xFCR_RE_MASK (((1 << ESAI_xFCR_RE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT)
#define ESAI_xFCR_TE(x) ((ESAI_xFCR_TE_MASK >> (ESAI_xFCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_TE_MASK)
#define ESAI_xFCR_RE(x) ((ESAI_xFCR_RE_MASK >> (ESAI_xFCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_RE_MASK)
#define ESAI_xFCR_xFR_SHIFT 1
#define ESAI_xFCR_xFR_MASK (1 << ESAI_xFCR_xFR_SHIFT)
#define ESAI_xFCR_xFR (1 << ESAI_xFCR_xFR_SHIFT)
#define ESAI_xFCR_xFEN_SHIFT 0
#define ESAI_xFCR_xFEN_MASK (1 << ESAI_xFCR_xFEN_SHIFT)
#define ESAI_xFCR_xFEN (1 << ESAI_xFCR_xFEN_SHIFT)
/*
* Transmit FIFO Status Register -- REG_ESAI_TFSR 0x14
* Receive FIFO Status Register --REG_ESAI_RFSR 0x1C
*/
#define ESAI_xFSR_NTFO_SHIFT 12
#define ESAI_xFSR_NRFI_SHIFT 12
#define ESAI_xFSR_NTFI_SHIFT 8
#define ESAI_xFSR_NRFO_SHIFT 8
#define ESAI_xFSR_NTFx_WIDTH 3
#define ESAI_xFSR_NRFx_WIDTH 2
#define ESAI_xFSR_NTFO_MASK (((1 << ESAI_xFSR_NTFx_WIDTH) - 1) << ESAI_xFSR_NTFO_SHIFT)
#define ESAI_xFSR_NTFI_MASK (((1 << ESAI_xFSR_NTFx_WIDTH) - 1) << ESAI_xFSR_NTFI_SHIFT)
#define ESAI_xFSR_NRFO_MASK (((1 << ESAI_xFSR_NRFx_WIDTH) - 1) << ESAI_xFSR_NRFO_SHIFT)
#define ESAI_xFSR_NRFI_MASK (((1 << ESAI_xFSR_NRFx_WIDTH) - 1) << ESAI_xFSR_NRFI_SHIFT)
#define ESAI_xFSR_xFCNT_SHIFT 0
#define ESAI_xFSR_xFCNT_WIDTH 8
#define ESAI_xFSR_xFCNT_MASK (((1 << ESAI_xFSR_xFCNT_WIDTH) - 1) << ESAI_xFSR_xFCNT_SHIFT)
/* ESAI Transmit Slot Register -- REG_ESAI_TSR 0x98 */
#define ESAI_TSR_SHIFT 0
#define ESAI_TSR_WIDTH 24
#define ESAI_TSR_MASK (((1 << ESAI_TSR_WIDTH) - 1) << ESAI_TSR_SHIFT)
/* Serial Audio Interface Status Register -- REG_ESAI_SAISR 0xCC */
#define ESAI_SAISR_TODFE_SHIFT 17
#define ESAI_SAISR_TODFE_MASK (1 << ESAI_SAISR_TODFE_SHIFT)
#define ESAI_SAISR_TODFE (1 << ESAI_SAISR_TODFE_SHIFT)
#define ESAI_SAISR_TEDE_SHIFT 16
#define ESAI_SAISR_TEDE_MASK (1 << ESAI_SAISR_TEDE_SHIFT)
#define ESAI_SAISR_TEDE (1 << ESAI_SAISR_TEDE_SHIFT)
#define ESAI_SAISR_TDE_SHIFT 15
#define ESAI_SAISR_TDE_MASK (1 << ESAI_SAISR_TDE_SHIFT)
#define ESAI_SAISR_TDE (1 << ESAI_SAISR_TDE_SHIFT)
#define ESAI_SAISR_TUE_SHIFT 14
#define ESAI_SAISR_TUE_MASK (1 << ESAI_SAISR_TUE_SHIFT)
#define ESAI_SAISR_TUE (1 << ESAI_SAISR_TUE_SHIFT)
#define ESAI_SAISR_TFS_SHIFT 13
#define ESAI_SAISR_TFS_MASK (1 << ESAI_SAISR_TFS_SHIFT)
#define ESAI_SAISR_TFS (1 << ESAI_SAISR_TFS_SHIFT)
#define ESAI_SAISR_RODF_SHIFT 10
#define ESAI_SAISR_RODF_MASK (1 << ESAI_SAISR_RODF_SHIFT)
#define ESAI_SAISR_RODF (1 << ESAI_SAISR_RODF_SHIFT)
#define ESAI_SAISR_REDF_SHIFT 9
#define ESAI_SAISR_REDF_MASK (1 << ESAI_SAISR_REDF_SHIFT)
#define ESAI_SAISR_REDF (1 << ESAI_SAISR_REDF_SHIFT)
#define ESAI_SAISR_RDF_SHIFT 8
#define ESAI_SAISR_RDF_MASK (1 << ESAI_SAISR_RDF_SHIFT)
#define ESAI_SAISR_RDF (1 << ESAI_SAISR_RDF_SHIFT)
#define ESAI_SAISR_ROE_SHIFT 7
#define ESAI_SAISR_ROE_MASK (1 << ESAI_SAISR_ROE_SHIFT)
#define ESAI_SAISR_ROE (1 << ESAI_SAISR_ROE_SHIFT)
#define ESAI_SAISR_RFS_SHIFT 6
#define ESAI_SAISR_RFS_MASK (1 << ESAI_SAISR_RFS_SHIFT)
#define ESAI_SAISR_RFS (1 << ESAI_SAISR_RFS_SHIFT)
#define ESAI_SAISR_IF2_SHIFT 2
#define ESAI_SAISR_IF2_MASK (1 << ESAI_SAISR_IF2_SHIFT)
#define ESAI_SAISR_IF2 (1 << ESAI_SAISR_IF2_SHIFT)
#define ESAI_SAISR_IF1_SHIFT 1
#define ESAI_SAISR_IF1_MASK (1 << ESAI_SAISR_IF1_SHIFT)
#define ESAI_SAISR_IF1 (1 << ESAI_SAISR_IF1_SHIFT)
#define ESAI_SAISR_IF0_SHIFT 0
#define ESAI_SAISR_IF0_MASK (1 << ESAI_SAISR_IF0_SHIFT)
#define ESAI_SAISR_IF0 (1 << ESAI_SAISR_IF0_SHIFT)
/* Serial Audio Interface Control Register -- REG_ESAI_SAICR 0xD0 */
#define ESAI_SAICR_ALC_SHIFT 8
#define ESAI_SAICR_ALC_MASK (1 << ESAI_SAICR_ALC_SHIFT)
#define ESAI_SAICR_ALC (1 << ESAI_SAICR_ALC_SHIFT)
#define ESAI_SAICR_TEBE_SHIFT 7
#define ESAI_SAICR_TEBE_MASK (1 << ESAI_SAICR_TEBE_SHIFT)
#define ESAI_SAICR_TEBE (1 << ESAI_SAICR_TEBE_SHIFT)
#define ESAI_SAICR_SYNC_SHIFT 6
#define ESAI_SAICR_SYNC_MASK (1 << ESAI_SAICR_SYNC_SHIFT)
#define ESAI_SAICR_SYNC (1 << ESAI_SAICR_SYNC_SHIFT)
#define ESAI_SAICR_OF2_SHIFT 2
#define ESAI_SAICR_OF2_MASK (1 << ESAI_SAICR_OF2_SHIFT)
#define ESAI_SAICR_OF2 (1 << ESAI_SAICR_OF2_SHIFT)
#define ESAI_SAICR_OF1_SHIFT 1
#define ESAI_SAICR_OF1_MASK (1 << ESAI_SAICR_OF1_SHIFT)
#define ESAI_SAICR_OF1 (1 << ESAI_SAICR_OF1_SHIFT)
#define ESAI_SAICR_OF0_SHIFT 0
#define ESAI_SAICR_OF0_MASK (1 << ESAI_SAICR_OF0_SHIFT)
#define ESAI_SAICR_OF0 (1 << ESAI_SAICR_OF0_SHIFT)
/*
* Transmit Control Register -- REG_ESAI_TCR 0xD4
* Receive Control Register -- REG_ESAI_RCR 0xDC
*/
#define ESAI_xCR_xLIE_SHIFT 23
#define ESAI_xCR_xLIE_MASK (1 << ESAI_xCR_xLIE_SHIFT)
#define ESAI_xCR_xLIE (1 << ESAI_xCR_xLIE_SHIFT)
#define ESAI_xCR_xIE_SHIFT 22
#define ESAI_xCR_xIE_MASK (1 << ESAI_xCR_xIE_SHIFT)
#define ESAI_xCR_xIE (1 << ESAI_xCR_xIE_SHIFT)
#define ESAI_xCR_xEDIE_SHIFT 21
#define ESAI_xCR_xEDIE_MASK (1 << ESAI_xCR_xEDIE_SHIFT)
#define ESAI_xCR_xEDIE (1 << ESAI_xCR_xEDIE_SHIFT)
#define ESAI_xCR_xEIE_SHIFT 20
#define ESAI_xCR_xEIE_MASK (1 << ESAI_xCR_xEIE_SHIFT)
#define ESAI_xCR_xEIE (1 << ESAI_xCR_xEIE_SHIFT)
#define ESAI_xCR_xPR_SHIFT 19
#define ESAI_xCR_xPR_MASK (1 << ESAI_xCR_xPR_SHIFT)
#define ESAI_xCR_xPR (1 << ESAI_xCR_xPR_SHIFT)
#define ESAI_xCR_PADC_SHIFT 17
#define ESAI_xCR_PADC_MASK (1 << ESAI_xCR_PADC_SHIFT)
#define ESAI_xCR_PADC (1 << ESAI_xCR_PADC_SHIFT)
#define ESAI_xCR_xFSR_SHIFT 16
#define ESAI_xCR_xFSR_MASK (1 << ESAI_xCR_xFSR_SHIFT)
#define ESAI_xCR_xFSR (1 << ESAI_xCR_xFSR_SHIFT)
#define ESAI_xCR_xFSL_SHIFT 15
#define ESAI_xCR_xFSL_MASK (1 << ESAI_xCR_xFSL_SHIFT)
#define ESAI_xCR_xFSL (1 << ESAI_xCR_xFSL_SHIFT)
#define ESAI_xCR_xSWS_SHIFT 10
#define ESAI_xCR_xSWS_WIDTH 5
#define ESAI_xCR_xSWS_MASK (((1 << ESAI_xCR_xSWS_WIDTH) - 1) << ESAI_xCR_xSWS_SHIFT)
#define ESAI_xCR_xSWS(s, w) ((w < 24 ? (s - w + ((w - 8) >> 2)) : (s < 32 ? 0x1e : 0x1f)) << ESAI_xCR_xSWS_SHIFT)
#define ESAI_xCR_xMOD_SHIFT 8
#define ESAI_xCR_xMOD_WIDTH 2
#define ESAI_xCR_xMOD_MASK (((1 << ESAI_xCR_xMOD_WIDTH) - 1) << ESAI_xCR_xMOD_SHIFT)
#define ESAI_xCR_xMOD_ONDEMAND (0x1 << ESAI_xCR_xMOD_SHIFT)
#define ESAI_xCR_xMOD_NETWORK (0x1 << ESAI_xCR_xMOD_SHIFT)
#define ESAI_xCR_xMOD_AC97 (0x3 << ESAI_xCR_xMOD_SHIFT)
#define ESAI_xCR_xWA_SHIFT 7
#define ESAI_xCR_xWA_MASK (1 << ESAI_xCR_xWA_SHIFT)
#define ESAI_xCR_xWA (1 << ESAI_xCR_xWA_SHIFT)
#define ESAI_xCR_xSHFD_SHIFT 6
#define ESAI_xCR_xSHFD_MASK (1 << ESAI_xCR_xSHFD_SHIFT)
#define ESAI_xCR_xSHFD (1 << ESAI_xCR_xSHFD_SHIFT)
#define ESAI_xCR_xE_SHIFT 0
#define ESAI_xCR_TE_WIDTH 6
#define ESAI_xCR_RE_WIDTH 4
#define ESAI_xCR_TE_MASK (((1 << ESAI_xCR_TE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT)
#define ESAI_xCR_RE_MASK (((1 << ESAI_xCR_RE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT)
#define ESAI_xCR_TE(x) ((ESAI_xCR_TE_MASK >> (ESAI_xCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_TE_MASK)
#define ESAI_xCR_RE(x) ((ESAI_xCR_RE_MASK >> (ESAI_xCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_RE_MASK)
/*
* Transmit Clock Control Register -- REG_ESAI_TCCR 0xD8
* Receive Clock Control Register -- REG_ESAI_RCCR 0xE0
*/
#define ESAI_xCCR_xHCKD_SHIFT 23
#define ESAI_xCCR_xHCKD_MASK (1 << ESAI_xCCR_xHCKD_SHIFT)
#define ESAI_xCCR_xHCKD (1 << ESAI_xCCR_xHCKD_SHIFT)
#define ESAI_xCCR_xFSD_SHIFT 22
#define ESAI_xCCR_xFSD_MASK (1 << ESAI_xCCR_xFSD_SHIFT)
#define ESAI_xCCR_xFSD (1 << ESAI_xCCR_xFSD_SHIFT)
#define ESAI_xCCR_xCKD_SHIFT 21
#define ESAI_xCCR_xCKD_MASK (1 << ESAI_xCCR_xCKD_SHIFT)
#define ESAI_xCCR_xCKD (1 << ESAI_xCCR_xCKD_SHIFT)
#define ESAI_xCCR_xHCKP_SHIFT 20
#define ESAI_xCCR_xHCKP_MASK (1 << ESAI_xCCR_xHCKP_SHIFT)
#define ESAI_xCCR_xHCKP (1 << ESAI_xCCR_xHCKP_SHIFT)
#define ESAI_xCCR_xFSP_SHIFT 19
#define ESAI_xCCR_xFSP_MASK (1 << ESAI_xCCR_xFSP_SHIFT)
#define ESAI_xCCR_xFSP (1 << ESAI_xCCR_xFSP_SHIFT)
#define ESAI_xCCR_xCKP_SHIFT 18
#define ESAI_xCCR_xCKP_MASK (1 << ESAI_xCCR_xCKP_SHIFT)
#define ESAI_xCCR_xCKP (1 << ESAI_xCCR_xCKP_SHIFT)
#define ESAI_xCCR_xFP_SHIFT 14
#define ESAI_xCCR_xFP_WIDTH 4
#define ESAI_xCCR_xFP_MASK (((1 << ESAI_xCCR_xFP_WIDTH) - 1) << ESAI_xCCR_xFP_SHIFT)
#define ESAI_xCCR_xFP(v) ((((v) - 1) << ESAI_xCCR_xFP_SHIFT) & ESAI_xCCR_xFP_MASK)
#define ESAI_xCCR_xDC_SHIFT 9
#define ESAI_xCCR_xDC_WIDTH 4
#define ESAI_xCCR_xDC_MASK (((1 << ESAI_xCCR_xDC_WIDTH) - 1) << ESAI_xCCR_xDC_SHIFT)
#define ESAI_xCCR_xDC(v) ((((v) - 1) << ESAI_xCCR_xDC_SHIFT) & ESAI_xCCR_xDC_MASK)
#define ESAI_xCCR_xPSR_SHIFT 8
#define ESAI_xCCR_xPSR_MASK (1 << ESAI_xCCR_xPSR_SHIFT)
#define ESAI_xCCR_xPSR_BYPASS (1 << ESAI_xCCR_xPSR_SHIFT)
#define ESAI_xCCR_xPSR_DIV8 (0 << ESAI_xCCR_xPSR_SHIFT)
#define ESAI_xCCR_xPM_SHIFT 0
#define ESAI_xCCR_xPM_WIDTH 8
#define ESAI_xCCR_xPM_MASK (((1 << ESAI_xCCR_xPM_WIDTH) - 1) << ESAI_xCCR_xPM_SHIFT)
#define ESAI_xCCR_xPM(v) ((((v) - 1) << ESAI_xCCR_xPM_SHIFT) & ESAI_xCCR_xPM_MASK)
/* Transmit Slot Mask Register A/B -- REG_ESAI_TSMA/B 0xE4 ~ 0xF0 */
#define ESAI_xSMA_xS_SHIFT 0
#define ESAI_xSMA_xS_WIDTH 16
#define ESAI_xSMA_xS_MASK (((1 << ESAI_xSMA_xS_WIDTH) - 1) << ESAI_xSMA_xS_SHIFT)
#define ESAI_xSMA_xS(v) ((v) & ESAI_xSMA_xS_MASK)
#define ESAI_xSMB_xS_SHIFT 0
#define ESAI_xSMB_xS_WIDTH 16
#define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT)
#define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMA_xS_MASK)
/* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */
#define ESAI_PRRC_PDC_SHIFT 0
#define ESAI_PRRC_PDC_WIDTH 12
#define ESAI_PRRC_PDC_MASK (((1 << ESAI_PRRC_PDC_WIDTH) - 1) << ESAI_PRRC_PDC_SHIFT)
#define ESAI_PRRC_PDC(v) ((v) & ESAI_PRRC_PDC_MASK)
/* Port C Control Register -- REG_ESAI_PCRC 0xFC */
#define ESAI_PCRC_PC_SHIFT 0
#define ESAI_PCRC_PC_WIDTH 12
#define ESAI_PCRC_PC_MASK (((1 << ESAI_PCRC_PC_WIDTH) - 1) << ESAI_PCRC_PC_SHIFT)
#define ESAI_PCRC_PC(v) ((v) & ESAI_PCRC_PC_MASK)
#define ESAI_GPIO 0xfff
/* ESAI clock source */
#define ESAI_HCKT_FSYS 0
#define ESAI_HCKT_EXTAL 1
#define ESAI_HCKR_FSYS 2
#define ESAI_HCKR_EXTAL 3
/* ESAI clock divider */
#define ESAI_TX_DIV_PSR 0
#define ESAI_TX_DIV_PM 1
#define ESAI_TX_DIV_FP 2
#define ESAI_RX_DIV_PSR 3
#define ESAI_RX_DIV_PM 4
#define ESAI_RX_DIV_FP 5
#endif /* _FSL_ESAI_DAI_H */
...@@ -62,26 +62,25 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, ...@@ -62,26 +62,25 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
reg_cr2 = FSL_SAI_RCR2; reg_cr2 = FSL_SAI_RCR2;
val_cr2 = sai_readl(sai, sai->base + reg_cr2); val_cr2 = sai_readl(sai, sai->base + reg_cr2);
val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
switch (clk_id) { switch (clk_id) {
case FSL_SAI_CLK_BUS: case FSL_SAI_CLK_BUS:
val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
val_cr2 |= FSL_SAI_CR2_MSEL_BUS; val_cr2 |= FSL_SAI_CR2_MSEL_BUS;
break; break;
case FSL_SAI_CLK_MAST1: case FSL_SAI_CLK_MAST1:
val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1; val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1;
break; break;
case FSL_SAI_CLK_MAST2: case FSL_SAI_CLK_MAST2:
val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2; val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2;
break; break;
case FSL_SAI_CLK_MAST3: case FSL_SAI_CLK_MAST3:
val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3; val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3;
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
sai_writel(sai, val_cr2, sai->base + reg_cr2); sai_writel(sai, val_cr2, sai->base + reg_cr2);
return 0; return 0;
......
此差异已折叠。
...@@ -41,9 +41,6 @@ static const struct snd_pcm_hardware imx_pcm_hardware = { ...@@ -41,9 +41,6 @@ static const struct snd_pcm_hardware imx_pcm_hardware = {
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_RESUME, SNDRV_PCM_INFO_RESUME,
.formats = SNDRV_PCM_FMTBIT_S16_LE, .formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_min = 8000,
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = IMX_SSI_DMABUF_SIZE, .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
.period_bytes_min = 128, .period_bytes_min = 128,
.period_bytes_max = 65535, /* Limited by SDMA engine */ .period_bytes_max = 65535, /* Limited by SDMA engine */
......
...@@ -162,9 +162,6 @@ static struct snd_pcm_hardware snd_imx_hardware = { ...@@ -162,9 +162,6 @@ static struct snd_pcm_hardware snd_imx_hardware = {
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_RESUME, SNDRV_PCM_INFO_RESUME,
.formats = SNDRV_PCM_FMTBIT_S16_LE, .formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_min = 8000,
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = IMX_SSI_DMABUF_SIZE, .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
.period_bytes_min = 128, .period_bytes_min = 128,
.period_bytes_max = 16 * 1024, .period_bytes_max = 16 * 1024,
......
...@@ -200,10 +200,6 @@ static const struct snd_pcm_hardware psc_dma_hardware = { ...@@ -200,10 +200,6 @@ static const struct snd_pcm_hardware psc_dma_hardware = {
SNDRV_PCM_INFO_BATCH, SNDRV_PCM_INFO_BATCH,
.formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |
SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE, SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE,
.rate_min = 8000,
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
.period_bytes_max = 1024 * 1024, .period_bytes_max = 1024 * 1024,
.period_bytes_min = 32, .period_bytes_min = 32,
.periods_min = 2, .periods_min = 2,
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
* ALSA that we support all rates and let the codec driver decide what rates * ALSA that we support all rates and let the codec driver decide what rates
* are really supported. * are really supported.
*/ */
#define PSC_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \ #define PSC_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS
SNDRV_PCM_RATE_CONTINUOUS)
/** /**
* PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode * PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode
......
...@@ -9,14 +9,12 @@ ...@@ -9,14 +9,12 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/module.h> #include <linux/string.h>
#include <sound/simple_card.h> #include <sound/simple_card.h>
#define asoc_simple_get_card_info(p) \
container_of(p->dai_link, struct asoc_simple_card_info, snd_link)
static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
struct asoc_simple_dai *set, struct asoc_simple_dai *set,
unsigned int daifmt) unsigned int daifmt)
...@@ -41,7 +39,8 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, ...@@ -41,7 +39,8 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
{ {
struct asoc_simple_card_info *info = asoc_simple_get_card_info(rtd); struct asoc_simple_card_info *info =
snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *codec = rtd->codec_dai; struct snd_soc_dai *codec = rtd->codec_dai;
struct snd_soc_dai *cpu = rtd->cpu_dai; struct snd_soc_dai *cpu = rtd->cpu_dai;
unsigned int daifmt = info->daifmt; unsigned int daifmt = info->daifmt;
...@@ -106,12 +105,8 @@ asoc_simple_card_sub_parse_of(struct device_node *np, ...@@ -106,12 +105,8 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
&dai->sysclk); &dai->sysclk);
} else { } else {
clk = of_clk_get(*node, 0); clk = of_clk_get(*node, 0);
if (IS_ERR(clk)) { if (!IS_ERR(clk))
ret = PTR_ERR(clk); dai->sysclk = clk_get_rate(clk);
goto parse_error;
}
dai->sysclk = clk_get_rate(clk);
} }
ret = 0; ret = 0;
...@@ -138,10 +133,12 @@ static int asoc_simple_card_parse_of(struct device_node *node, ...@@ -138,10 +133,12 @@ static int asoc_simple_card_parse_of(struct device_node *node,
(SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK); (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK);
/* DAPM routes */ /* DAPM routes */
ret = snd_soc_of_parse_audio_routing(&info->snd_card, if (of_property_read_bool(node, "simple-audio-card,routing")) {
"simple-audio-routing"); ret = snd_soc_of_parse_audio_routing(&info->snd_card,
if (ret) "simple-audio-card,routing");
return ret; if (ret)
return ret;
}
/* CPU sub-node */ /* CPU sub-node */
ret = -EINVAL; ret = -EINVAL;
...@@ -197,34 +194,37 @@ static int asoc_simple_card_probe(struct platform_device *pdev) ...@@ -197,34 +194,37 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct device_node *of_cpu, *of_codec, *of_platform; struct device_node *of_cpu, *of_codec, *of_platform;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
int ret;
cinfo = NULL; cinfo = NULL;
of_cpu = NULL; of_cpu = NULL;
of_codec = NULL; of_codec = NULL;
of_platform = NULL; of_platform = NULL;
cinfo = devm_kzalloc(dev, sizeof(*cinfo), GFP_KERNEL);
if (!cinfo)
return -ENOMEM;
if (np && of_device_is_available(np)) { if (np && of_device_is_available(np)) {
cinfo = devm_kzalloc(dev, sizeof(*cinfo), GFP_KERNEL); cinfo->snd_card.dev = dev;
if (cinfo) {
int ret; ret = asoc_simple_card_parse_of(np, cinfo, dev,
cinfo->snd_card.dev = &pdev->dev; &of_cpu,
ret = asoc_simple_card_parse_of(np, cinfo, dev, &of_codec,
&of_cpu, &of_platform);
&of_codec, if (ret < 0) {
&of_platform); if (ret != -EPROBE_DEFER)
if (ret < 0) { dev_err(dev, "parse error %d\n", ret);
if (ret != -EPROBE_DEFER) return ret;
dev_err(dev, "parse error %d\n", ret);
return ret;
}
} }
} else { } else {
cinfo->snd_card.dev = &pdev->dev; if (!dev->platform_data) {
cinfo = pdev->dev.platform_data; dev_err(dev, "no info for asoc-simple-card\n");
} return -EINVAL;
}
if (!cinfo) { memcpy(cinfo, dev->platform_data, sizeof(*cinfo));
dev_err(dev, "no info for asoc-simple-card\n"); cinfo->snd_card.dev = dev;
return -EINVAL;
} }
if (!cinfo->name || if (!cinfo->name ||
...@@ -259,6 +259,8 @@ static int asoc_simple_card_probe(struct platform_device *pdev) ...@@ -259,6 +259,8 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
cinfo->snd_card.dai_link = &cinfo->snd_link; cinfo->snd_card.dai_link = &cinfo->snd_link;
cinfo->snd_card.num_links = 1; cinfo->snd_card.num_links = 1;
snd_soc_card_set_drvdata(&cinfo->snd_card, cinfo);
return devm_snd_soc_register_card(&pdev->dev, &cinfo->snd_card); return devm_snd_soc_register_card(&pdev->dev, &cinfo->snd_card);
} }
......
...@@ -89,16 +89,6 @@ static struct snd_pcm_hardware sst_platform_pcm_hw = { ...@@ -89,16 +89,6 @@ static struct snd_pcm_hardware sst_platform_pcm_hw = {
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_SYNC_START), SNDRV_PCM_INFO_SYNC_START),
.formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 |
SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 |
SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32),
.rates = (SNDRV_PCM_RATE_8000|
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000),
.rate_min = SST_MIN_RATE,
.rate_max = SST_MAX_RATE,
.channels_min = SST_MIN_CHANNEL,
.channels_max = SST_MAX_CHANNEL,
.buffer_bytes_max = SST_MAX_BUFFER, .buffer_bytes_max = SST_MAX_BUFFER,
.period_bytes_min = SST_MIN_PERIOD_BYTES, .period_bytes_min = SST_MIN_PERIOD_BYTES,
.period_bytes_max = SST_MAX_PERIOD_BYTES, .period_bytes_max = SST_MAX_PERIOD_BYTES,
......
...@@ -33,10 +33,6 @@ ...@@ -33,10 +33,6 @@
#define SST_STEREO 2 #define SST_STEREO 2
#define SST_MAX_CAP 5 #define SST_MAX_CAP 5
#define SST_MIN_RATE 8000
#define SST_MAX_RATE 48000
#define SST_MIN_CHANNEL 1
#define SST_MAX_CHANNEL 5
#define SST_MAX_BUFFER (800*1024) #define SST_MAX_BUFFER (800*1024)
#define SST_MIN_BUFFER (800*1024) #define SST_MIN_BUFFER (800*1024)
#define SST_MIN_PERIOD_BYTES 32 #define SST_MIN_PERIOD_BYTES 32
......
...@@ -21,16 +21,6 @@ ...@@ -21,16 +21,6 @@
#include <sound/soc.h> #include <sound/soc.h>
#include "kirkwood.h" #include "kirkwood.h"
#define KIRKWOOD_RATES \
(SNDRV_PCM_RATE_8000_192000 | \
SNDRV_PCM_RATE_CONTINUOUS | \
SNDRV_PCM_RATE_KNOT)
#define KIRKWOOD_FORMATS \
(SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
static struct kirkwood_dma_data *kirkwood_priv(struct snd_pcm_substream *subs) static struct kirkwood_dma_data *kirkwood_priv(struct snd_pcm_substream *subs)
{ {
struct snd_soc_pcm_runtime *soc_runtime = subs->private_data; struct snd_soc_pcm_runtime *soc_runtime = subs->private_data;
...@@ -43,12 +33,6 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = { ...@@ -43,12 +33,6 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = {
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_PAUSE), SNDRV_PCM_INFO_PAUSE),
.formats = KIRKWOOD_FORMATS,
.rates = KIRKWOOD_RATES,
.rate_min = 8000,
.rate_max = 384000,
.channels_min = 1,
.channels_max = 8,
.buffer_bytes_max = KIRKWOOD_SND_MAX_BUFFER_BYTES, .buffer_bytes_max = KIRKWOOD_SND_MAX_BUFFER_BYTES,
.period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES, .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES,
.period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES, .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES,
......
...@@ -36,11 +36,6 @@ static const struct snd_pcm_hardware snd_mxs_hardware = { ...@@ -36,11 +36,6 @@ static const struct snd_pcm_hardware snd_mxs_hardware = {
SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_HALF_DUPLEX, SNDRV_PCM_INFO_HALF_DUPLEX,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE |
SNDRV_PCM_FMTBIT_S24_LE,
.channels_min = 2,
.channels_max = 2,
.period_bytes_min = 32, .period_bytes_min = 32,
.period_bytes_max = 8192, .period_bytes_max = 8192,
.periods_min = 1, .periods_min = 1,
...@@ -57,7 +52,6 @@ static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = { ...@@ -57,7 +52,6 @@ static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = {
int mxs_pcm_platform_register(struct device *dev) int mxs_pcm_platform_register(struct device *dev)
{ {
return devm_snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, return devm_snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config,
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX); SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX);
} }
EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); EXPORT_SYMBOL_GPL(mxs_pcm_platform_register);
......
...@@ -32,9 +32,6 @@ static const struct snd_pcm_hardware nuc900_pcm_hardware = { ...@@ -32,9 +32,6 @@ static const struct snd_pcm_hardware nuc900_pcm_hardware = {
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_RESUME, SNDRV_PCM_INFO_RESUME,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = 4*1024, .buffer_bytes_max = 4*1024,
.period_bytes_min = 1*1024, .period_bytes_min = 1*1024,
.period_bytes_max = 4*1024, .period_bytes_max = 4*1024,
......
...@@ -405,8 +405,7 @@ static int s6000_i2s_dai_probe(struct snd_soc_dai *dai) ...@@ -405,8 +405,7 @@ static int s6000_i2s_dai_probe(struct snd_soc_dai *dai)
return 0; return 0;
} }
#define S6000_I2S_RATES (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \ #define S6000_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS
SNDRV_PCM_RATE_8000_192000)
#define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) #define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
static const struct snd_soc_dai_ops s6000_i2s_dai_ops = { static const struct snd_soc_dai_ops s6000_i2s_dai_ops = {
......
...@@ -68,7 +68,6 @@ int samsung_asoc_dma_platform_register(struct device *dev) ...@@ -68,7 +68,6 @@ int samsung_asoc_dma_platform_register(struct device *dev)
{ {
return snd_dmaengine_pcm_register(dev, &samsung_dmaengine_pcm_config, return snd_dmaengine_pcm_register(dev, &samsung_dmaengine_pcm_config,
SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME | SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME |
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
SND_DMAENGINE_PCM_FLAG_COMPAT); SND_DMAENGINE_PCM_FLAG_COMPAT);
} }
EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register); EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register);
......
...@@ -89,29 +89,12 @@ struct camelot_pcm { ...@@ -89,29 +89,12 @@ struct camelot_pcm {
#define DMABRG_PREALLOC_BUFFER 32 * 1024 #define DMABRG_PREALLOC_BUFFER 32 * 1024
#define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024 #define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024
/* support everything the SSI supports */
#define DMABRG_RATES \
SNDRV_PCM_RATE_8000_192000
#define DMABRG_FMTS \
(SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)
static struct snd_pcm_hardware camelot_pcm_hardware = { static struct snd_pcm_hardware camelot_pcm_hardware = {
.info = (SNDRV_PCM_INFO_MMAP | .info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_BATCH), SNDRV_PCM_INFO_BATCH),
.formats = DMABRG_FMTS,
.rates = DMABRG_RATES,
.rate_min = 8000,
.rate_max = 192000,
.channels_min = 2,
.channels_max = 8, /* max of the SSI */
.buffer_bytes_max = DMABRG_PERIOD_MAX, .buffer_bytes_max = DMABRG_PERIOD_MAX,
.period_bytes_min = DMABRG_PERIOD_MIN, .period_bytes_min = DMABRG_PERIOD_MIN,
.period_bytes_max = DMABRG_PERIOD_MAX / 2, .period_bytes_max = DMABRG_PERIOD_MAX / 2,
......
...@@ -1787,12 +1787,6 @@ static struct snd_pcm_hardware fsi_pcm_hardware = { ...@@ -1787,12 +1787,6 @@ static struct snd_pcm_hardware fsi_pcm_hardware = {
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE, SNDRV_PCM_INFO_PAUSE,
.formats = FSI_FMTS,
.rates = FSI_RATES,
.rate_min = 8000,
.rate_max = 192000,
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = 64 * 1024, .buffer_bytes_max = 64 * 1024,
.period_bytes_min = 32, .period_bytes_min = 32,
.period_bytes_max = 8192, .period_bytes_max = 8192,
......
...@@ -628,12 +628,6 @@ static struct snd_pcm_hardware rsnd_pcm_hardware = { ...@@ -628,12 +628,6 @@ static struct snd_pcm_hardware rsnd_pcm_hardware = {
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE, SNDRV_PCM_INFO_PAUSE,
.formats = RSND_FMTS,
.rates = RSND_RATES,
.rate_min = 8000,
.rate_max = 192000,
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = 64 * 1024, .buffer_bytes_max = 64 * 1024,
.period_bytes_min = 32, .period_bytes_min = 32,
.period_bytes_max = 8192, .period_bytes_max = 8192,
......
...@@ -1728,6 +1728,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) ...@@ -1728,6 +1728,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
} }
snd_soc_dapm_link_dai_widgets(card); snd_soc_dapm_link_dai_widgets(card);
snd_soc_dapm_connect_dai_link_widgets(card);
if (card->controls) if (card->controls)
snd_soc_add_card_controls(card, card->controls, card->num_controls); snd_soc_add_card_controls(card, card->controls, card->num_controls);
...@@ -3484,7 +3485,7 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, ...@@ -3484,7 +3485,7 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
return dai->codec->driver->set_sysclk(dai->codec, clk_id, 0, return dai->codec->driver->set_sysclk(dai->codec, clk_id, 0,
freq, dir); freq, dir);
else else
return -EINVAL; return -ENOTSUPP;
} }
EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
...@@ -3505,7 +3506,7 @@ int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, ...@@ -3505,7 +3506,7 @@ int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
return codec->driver->set_sysclk(codec, clk_id, source, return codec->driver->set_sysclk(codec, clk_id, source,
freq, dir); freq, dir);
else else
return -EINVAL; return -ENOTSUPP;
} }
EXPORT_SYMBOL_GPL(snd_soc_codec_set_sysclk); EXPORT_SYMBOL_GPL(snd_soc_codec_set_sysclk);
......
...@@ -371,12 +371,16 @@ static void dapm_reset(struct snd_soc_card *card) ...@@ -371,12 +371,16 @@ static void dapm_reset(struct snd_soc_card *card)
} }
} }
static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg,
unsigned int *value)
{ {
if (w->codec) if (w->codec) {
return snd_soc_read(w->codec, reg); *value = snd_soc_read(w->codec, reg);
else if (w->platform) return 0;
return snd_soc_platform_read(w->platform, reg); } else if (w->platform) {
*value = snd_soc_platform_read(w->platform, reg);
return 0;
}
dev_err(w->dapm->dev, "ASoC: no valid widget read method\n"); dev_err(w->dapm->dev, "ASoC: no valid widget read method\n");
return -1; return -1;
...@@ -430,13 +434,12 @@ static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w, ...@@ -430,13 +434,12 @@ static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
return ret; return ret;
} else { } else {
soc_widget_lock(w); soc_widget_lock(w);
ret = soc_widget_read(w, reg); ret = soc_widget_read(w, reg, &old);
if (ret < 0) { if (ret < 0) {
soc_widget_unlock(w); soc_widget_unlock(w);
return ret; return ret;
} }
old = ret;
new = (old & ~mask) | (value & mask); new = (old & ~mask) | (value & mask);
change = old != new; change = old != new;
if (change) { if (change) {
...@@ -513,7 +516,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, ...@@ -513,7 +516,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
unsigned int invert = mc->invert; unsigned int invert = mc->invert;
if (reg != SND_SOC_NOPM) { if (reg != SND_SOC_NOPM) {
val = soc_widget_read(w, reg); soc_widget_read(w, reg, &val);
val = (val >> shift) & mask; val = (val >> shift) & mask;
if (invert) if (invert)
val = max - val; val = max - val;
...@@ -529,7 +532,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, ...@@ -529,7 +532,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
w->kcontrol_news[i].private_value; w->kcontrol_news[i].private_value;
int val, item; int val, item;
val = soc_widget_read(w, e->reg); soc_widget_read(w, e->reg, &val);
item = (val >> e->shift_l) & e->mask; item = (val >> e->shift_l) & e->mask;
if (item < e->max && !strcmp(p->name, e->texts[item])) if (item < e->max && !strcmp(p->name, e->texts[item]))
...@@ -558,7 +561,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, ...@@ -558,7 +561,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
w->kcontrol_news[i].private_value; w->kcontrol_news[i].private_value;
int val, item; int val, item;
val = soc_widget_read(w, e->reg); soc_widget_read(w, e->reg, &val);
val = (val >> e->shift_l) & e->mask; val = (val >> e->shift_l) & e->mask;
for (item = 0; item < e->max; item++) { for (item = 0; item < e->max; item++) {
if (val == e->values[item]) if (val == e->values[item])
...@@ -2782,7 +2785,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card) ...@@ -2782,7 +2785,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card)
/* Read the initial power state from the device */ /* Read the initial power state from the device */
if (w->reg >= 0) { if (w->reg >= 0) {
val = soc_widget_read(w, w->reg) >> w->shift; soc_widget_read(w, w->reg, &val);
val = val >> w->shift;
val &= w->mask; val &= w->mask;
if (val == w->on_val) if (val == w->on_val)
w->power = 1; w->power = 1;
...@@ -3634,6 +3638,55 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) ...@@ -3634,6 +3638,55 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
return 0; return 0;
} }
void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd = card->rtd;
struct snd_soc_dai *cpu_dai, *codec_dai;
struct snd_soc_dapm_route r;
int i;
memset(&r, 0, sizeof(r));
/* for each BE DAI link... */
for (i = 0; i < card->num_rtd; i++) {
rtd = &card->rtd[i];
cpu_dai = rtd->cpu_dai;
codec_dai = rtd->codec_dai;
/* dynamic FE links have no fixed DAI mapping */
if (rtd->dai_link->dynamic)
continue;
/* there is no point in connecting BE DAI links with dummies */
if (snd_soc_dai_is_dummy(codec_dai) ||
snd_soc_dai_is_dummy(cpu_dai))
continue;
/* connect BE DAI playback if widgets are valid */
if (codec_dai->playback_widget && cpu_dai->playback_widget) {
r.source = cpu_dai->playback_widget->name;
r.sink = codec_dai->playback_widget->name;
dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
cpu_dai->codec->name, r.source,
codec_dai->platform->name, r.sink);
snd_soc_dapm_add_route(&card->dapm, &r);
}
/* connect BE DAI capture if widgets are valid */
if (codec_dai->capture_widget && cpu_dai->capture_widget) {
r.source = codec_dai->capture_widget->name;
r.sink = cpu_dai->capture_widget->name;
dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
codec_dai->codec->name, r.source,
cpu_dai->platform->name, r.sink);
snd_soc_dapm_add_route(&card->dapm, &r);
}
}
}
static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
int event) int event)
{ {
......
...@@ -144,6 +144,8 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea ...@@ -144,6 +144,8 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
if (ret == 0) { if (ret == 0) {
if (dma_caps.cmd_pause) if (dma_caps.cmd_pause)
hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME; hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME;
if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT)
hw.info |= SNDRV_PCM_INFO_BATCH;
} }
return snd_soc_set_runtime_hwparams(substream, &hw); return snd_soc_set_runtime_hwparams(substream, &hw);
...@@ -187,6 +189,21 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel( ...@@ -187,6 +189,21 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel(
dma_data->filter_data); dma_data->filter_data);
} }
static bool dmaengine_pcm_can_report_residue(struct dma_chan *chan)
{
struct dma_slave_caps dma_caps;
int ret;
ret = dma_get_slave_caps(chan, &dma_caps);
if (ret != 0)
return true;
if (dma_caps.residue_granularity == DMA_RESIDUE_GRANULARITY_DESCRIPTOR)
return false;
return true;
}
static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
{ {
struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
...@@ -239,6 +256,16 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) ...@@ -239,6 +256,16 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
max_buffer_size); max_buffer_size);
if (ret) if (ret)
goto err_free; goto err_free;
/*
* This will only return false if we know for sure that at least
* one channel does not support residue reporting. If the DMA
* driver does not implement the slave_caps API we rely having
* the NO_RESIDUE flag set manually in case residue reporting is
* not supported.
*/
if (!dmaengine_pcm_can_report_residue(pcm->chan[i]))
pcm->flags |= SND_DMAENGINE_PCM_FLAG_NO_RESIDUE;
} }
return 0; return 0;
...@@ -248,6 +275,18 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) ...@@ -248,6 +275,18 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
return ret; return ret;
} }
static snd_pcm_uframes_t dmaengine_pcm_pointer(
struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE)
return snd_dmaengine_pcm_pointer_no_residue(substream);
else
return snd_dmaengine_pcm_pointer(substream);
}
static const struct snd_pcm_ops dmaengine_pcm_ops = { static const struct snd_pcm_ops dmaengine_pcm_ops = {
.open = dmaengine_pcm_open, .open = dmaengine_pcm_open,
.close = snd_dmaengine_pcm_close, .close = snd_dmaengine_pcm_close,
...@@ -255,7 +294,7 @@ static const struct snd_pcm_ops dmaengine_pcm_ops = { ...@@ -255,7 +294,7 @@ static const struct snd_pcm_ops dmaengine_pcm_ops = {
.hw_params = dmaengine_pcm_hw_params, .hw_params = dmaengine_pcm_hw_params,
.hw_free = snd_pcm_lib_free_pages, .hw_free = snd_pcm_lib_free_pages,
.trigger = snd_dmaengine_pcm_trigger, .trigger = snd_dmaengine_pcm_trigger,
.pointer = snd_dmaengine_pcm_pointer, .pointer = dmaengine_pcm_pointer,
}; };
static const struct snd_soc_platform_driver dmaengine_pcm_platform = { static const struct snd_soc_platform_driver dmaengine_pcm_platform = {
...@@ -265,23 +304,6 @@ static const struct snd_soc_platform_driver dmaengine_pcm_platform = { ...@@ -265,23 +304,6 @@ static const struct snd_soc_platform_driver dmaengine_pcm_platform = {
.probe_order = SND_SOC_COMP_ORDER_LATE, .probe_order = SND_SOC_COMP_ORDER_LATE,
}; };
static const struct snd_pcm_ops dmaengine_no_residue_pcm_ops = {
.open = dmaengine_pcm_open,
.close = snd_dmaengine_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = dmaengine_pcm_hw_params,
.hw_free = snd_pcm_lib_free_pages,
.trigger = snd_dmaengine_pcm_trigger,
.pointer = snd_dmaengine_pcm_pointer_no_residue,
};
static const struct snd_soc_platform_driver dmaengine_no_residue_pcm_platform = {
.ops = &dmaengine_no_residue_pcm_ops,
.pcm_new = dmaengine_pcm_new,
.pcm_free = dmaengine_pcm_free,
.probe_order = SND_SOC_COMP_ORDER_LATE,
};
static const char * const dmaengine_pcm_dma_channel_names[] = { static const char * const dmaengine_pcm_dma_channel_names[] = {
[SNDRV_PCM_STREAM_PLAYBACK] = "tx", [SNDRV_PCM_STREAM_PLAYBACK] = "tx",
[SNDRV_PCM_STREAM_CAPTURE] = "rx", [SNDRV_PCM_STREAM_CAPTURE] = "rx",
...@@ -374,12 +396,8 @@ int snd_dmaengine_pcm_register(struct device *dev, ...@@ -374,12 +396,8 @@ int snd_dmaengine_pcm_register(struct device *dev,
if (ret) if (ret)
goto err_free_dma; goto err_free_dma;
if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) ret = snd_soc_add_platform(dev, &pcm->platform,
ret = snd_soc_add_platform(dev, &pcm->platform, &dmaengine_pcm_platform);
&dmaengine_no_residue_pcm_platform);
else
ret = snd_soc_add_platform(dev, &pcm->platform,
&dmaengine_pcm_platform);
if (ret) if (ret)
goto err_free_dma; goto err_free_dma;
......
此差异已折叠。
...@@ -119,6 +119,13 @@ static struct snd_soc_dai_driver dummy_dai = { ...@@ -119,6 +119,13 @@ static struct snd_soc_dai_driver dummy_dai = {
}, },
}; };
int snd_soc_dai_is_dummy(struct snd_soc_dai *dai)
{
if (dai->driver == &dummy_dai)
return 1;
return 0;
}
static int snd_soc_dummy_probe(struct platform_device *pdev) static int snd_soc_dummy_probe(struct platform_device *pdev)
{ {
int ret; int ret;
......
...@@ -91,6 +91,8 @@ static int mop500_of_probe(struct platform_device *pdev, ...@@ -91,6 +91,8 @@ static int mop500_of_probe(struct platform_device *pdev,
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
mop500_dai_links[i].cpu_of_node = msp_np[i]; mop500_dai_links[i].cpu_of_node = msp_np[i];
mop500_dai_links[i].cpu_dai_name = NULL; mop500_dai_links[i].cpu_dai_name = NULL;
mop500_dai_links[i].platform_of_node = msp_np[i];
mop500_dai_links[i].platform_name = NULL;
mop500_dai_links[i].codec_of_node = codec_np; mop500_dai_links[i].codec_of_node = codec_np;
mop500_dai_links[i].codec_name = NULL; mop500_dai_links[i].codec_name = NULL;
} }
......
此差异已折叠。
此差异已折叠。
...@@ -475,7 +475,7 @@ struct ux500_msp_dma_params { ...@@ -475,7 +475,7 @@ struct ux500_msp_dma_params {
}; };
struct ux500_msp { struct ux500_msp {
enum msp_i2s_id id; int id;
void __iomem *registers; void __iomem *registers;
struct device *dev; struct device *dev;
struct ux500_msp_dma_params playback_dma_data; struct ux500_msp_dma_params playback_dma_data;
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册