diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-01-16 14:54:00 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-01-16 14:54:00 +0100 |
commit | 2aff4c9ce898b9079658650c1ab33c44b100a203 (patch) | |
tree | 66f3d8367c315c7fa1267bdb27d0bd923b8ce46f | |
parent | c48ae0ab3790efba2dfb1a4709c0ef8da024de1a (diff) | |
parent | 701caa51a2ce74182d39380ca11defeb163d98c1 (diff) |
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()
80 files changed, 2656 insertions, 1034 deletions
diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt new file mode 100644 index 00000000000..d7b99fa637b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt @@ -0,0 +1,50 @@ +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"; +}; diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt index 4303b6ab620..b93e9a91e30 100644 --- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt +++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt @@ -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. 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. - reg: Offset and length of the register set for the device. - interrupts: <a b> where a is the interrupt number and b is a diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index 2ee80c76ca6..e9e20ec67d6 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt @@ -11,7 +11,7 @@ Optional properties: - simple-audio-card,format : CPU/CODEC common audio format. "i2s", "right_j", "left_j" , "dsp_a" "dsp_b", "ac97", "pdm", "msb", "lsb" -- simple-audio-routing : A list of the connections between audio components. +- simple-audio-card,routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, the second being the connection's source. diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt index 5e6040c2c2e..9d8ea14db49 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt @@ -6,6 +6,7 @@ Required properties: - compatible - "string" - One of: "ti,tlv320aic3x" - Generic TLV320AIC3x device + "ti,tlv320aic32x4" - TLV320AIC32x4 "ti,tlv320aic33" - TLV320AIC33 "ti,tlv320aic3007" - TLV320AIC3007 "ti,tlv320aic3106" - TLV320AIC3106 diff --git a/Documentation/sound/alsa/soc/overview.txt b/Documentation/sound/alsa/soc/overview.txt index 138ac88c146..ff88f52eec9 100644 --- a/Documentation/sound/alsa/soc/overview.txt +++ b/Documentation/sound/alsa/soc/overview.txt @@ -49,18 +49,23 @@ features :- * Machine specific controls: Allow machines to add controls to the sound card (e.g. volume control for speaker amplifier). -To achieve all this, ASoC basically splits an embedded audio system into 3 -components :- +To achieve all this, ASoC basically splits an embedded audio system into +multiple re-usable component drivers :- - * Codec driver: The codec driver is platform independent and contains audio - controls, audio interface capabilities, codec DAPM definition and codec IO - functions. + * Codec class drivers: The codec class driver is platform independent and + contains audio controls, audio interface capabilities, codec DAPM + 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 - interface drivers (e.g. I2S, AC97, PCM) for that platform. + * Platform class drivers: The platform class driver includes the audio DMA + 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 - audio events (e.g. turning on an amp at start of playback). + * Machine class driver: The machine driver class acts as the glue that + 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 @@ -84,3 +89,7 @@ machine.txt: Machine driver internals. pop_clicks.txt: How to minimise audio artifacts. clocking.txt: ASoC clocking for best power performance. + +jack.txt: ASoC jack detection. + +DPCM.txt: Dynamic PCM - Describes DPCM with DSP examples. diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c index 154e15f5970..43d6cb8c381 100644 --- a/arch/arm/mach-ux500/board-mop500-audio.c +++ b/arch/arm/mach-ux500/board-mop500-audio.c @@ -31,7 +31,7 @@ static struct stedma40_chan_cfg msp0_dma_tx = { }; struct msp_i2s_platform_data msp0_platform_data = { - .id = MSP_I2S_0, + .id = 0, .msp_i2s_dma_rx = &msp0_dma_rx, .msp_i2s_dma_tx = &msp0_dma_tx, }; @@ -49,7 +49,7 @@ static struct stedma40_chan_cfg msp1_dma_tx = { }; struct msp_i2s_platform_data msp1_platform_data = { - .id = MSP_I2S_1, + .id = 1, .msp_i2s_dma_rx = NULL, .msp_i2s_dma_tx = &msp1_dma_tx, }; @@ -69,13 +69,13 @@ static struct stedma40_chan_cfg msp2_dma_tx = { }; struct msp_i2s_platform_data msp2_platform_data = { - .id = MSP_I2S_2, + .id = 2, .msp_i2s_dma_rx = &msp2_dma_rx, .msp_i2s_dma_tx = &msp2_dma_tx, }; struct msp_i2s_platform_data msp3_platform_data = { - .id = MSP_I2S_3, + .id = 3, .msp_i2s_dma_rx = &msp1_dma_rx, .msp_i2s_dma_tx = NULL, }; diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 536632f6479..c90edecee46 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -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->cmd_pause = false; caps->cmd_terminate = true; + caps->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; return 0; } diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 29473c2c95a..6ef7685a4cf 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -47,6 +47,9 @@ #include <linux/i2c.h> #include <linux/i2c/twl.h> +/* Register descriptions for audio */ +#include <linux/mfd/twl4030-audio.h> + #include "twl-core.h" /* @@ -200,6 +203,105 @@ static struct twl_mapping twl4030_map[] = { { 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] = { { /* Address 0x48 */ @@ -212,6 +314,15 @@ static struct regmap_config twl4030_regmap_config[4] = { .reg_bits = 8, .val_bits = 8, .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 */ @@ -302,35 +413,50 @@ unsigned int twl_rev(void) 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 - * @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; struct twl_client *twl; if (unlikely(!twl_priv || !twl_priv->ready)) { pr_err("%s: not initialized\n", DRIVER_NAME); - return -EPERM; + return NULL; } if (unlikely(mod_no >= twl_get_last_module())) { pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); - return -EPERM; + return NULL; } sid = twl_priv->twl_map[mod_no].sid; twl = &twl_priv->twl_modules[sid]; - ret = regmap_bulk_write(twl->regmap, - twl_priv->twl_map[mod_no].base + reg, value, - num_bytes); + return twl->regmap; +} + +/** + * 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) pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n", @@ -351,25 +477,14 @@ EXPORT_SYMBOL(twl_i2c_write); */ 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 sid; - struct twl_client *twl; - if (unlikely(!twl_priv || !twl_priv->ready)) { - 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); + if (!regmap) return -EPERM; - } - - sid = twl_priv->twl_map[mod_no].sid; - twl = &twl_priv->twl_modules[sid]; - ret = regmap_bulk_read(twl->regmap, - twl_priv->twl_m |