Browse Source

Merge remote-tracking branches 'asoc/topic/adsp', 'asoc/topic/atmel', 'asoc/topic/bcm2835', 'asoc/topic/docs', 'asoc/topic/fsl', 'asoc/topic/generic', 'asoc/topic/kirkwood', 'asoc/topic/mc13783', 'asoc/topic/mxs', 'asoc/topic/nuc900', 'asoc/topic/sai', 'asoc/topic/sh', 'asoc/topic/ssm2602', 'asoc/topic/tlv320aic3x', 'asoc/topic/twl4030', 'asoc/topic/ux500', 'asoc/topic/width' and 'asoc/topic/x86' into for-tiwai

isee-imx_3.14.28.y
59 changed files with 2385 additions and 955 deletions
  1. +50
    -0
      Documentation/devicetree/bindings/sound/fsl,esai.txt
  2. +6
    -1
      Documentation/devicetree/bindings/sound/fsl,ssi.txt
  3. +1
    -1
      Documentation/devicetree/bindings/sound/simple-card.txt
  4. +1
    -0
      Documentation/devicetree/bindings/sound/tlv320aic3x.txt
  5. +18
    -9
      Documentation/sound/alsa/soc/overview.txt
  6. +4
    -4
      arch/arm/mach-ux500/board-mop500-audio.c
  7. +163
    -27
      drivers/mfd/twl-core.c
  8. +3
    -2
      include/linux/i2c/twl.h
  9. +1
    -8
      include/linux/platform_data/asoc-ux500-msp.h
  10. +0
    -1
      sound/soc/atmel/atmel-pcm-dma.c
  11. +0
    -1
      sound/soc/atmel/atmel-pcm-pdc.c
  12. +0
    -1
      sound/soc/bcm/Kconfig
  13. +5
    -5
      sound/soc/codecs/ad1836.c
  14. +5
    -5
      sound/soc/codecs/ad193x.c
  15. +5
    -5
      sound/soc/codecs/adau1373.c
  16. +16
    -18
      sound/soc/codecs/adau1701.c
  17. +14
    -16
      sound/soc/codecs/adav80x.c
  18. +5
    -5
      sound/soc/codecs/alc5623.c
  19. +4
    -4
      sound/soc/codecs/alc5632.c
  20. +9
    -8
      sound/soc/codecs/arizona.h
  21. +5
    -9
      sound/soc/codecs/cs42l51.c
  22. +5
    -5
      sound/soc/codecs/da7210.c
  23. +5
    -5
      sound/soc/codecs/da7213.c
  24. +5
    -5
      sound/soc/codecs/da732x.c
  25. +5
    -5
      sound/soc/codecs/da9055.c
  26. +3
    -3
      sound/soc/codecs/isabelle.c
  27. +3
    -3
      sound/soc/codecs/max98088.c
  28. +2
    -2
      sound/soc/codecs/max98090.c
  29. +3
    -3
      sound/soc/codecs/max98095.c
  30. +4
    -4
      sound/soc/codecs/max9850.c
  31. +10
    -24
      sound/soc/codecs/mc13783.c
  32. +10
    -4
      sound/soc/codecs/ssm2602.c
  33. +134
    -242
      sound/soc/codecs/twl4030.c
  34. +121
    -78
      sound/soc/codecs/wm_adsp.c
  35. +10
    -2
      sound/soc/codecs/wm_adsp.h
  36. +3
    -0
      sound/soc/fsl/Kconfig
  37. +2
    -0
      sound/soc/fsl/Makefile
  38. +0
    -7
      sound/soc/fsl/fsl_dma.c
  39. +815
    -0
      sound/soc/fsl/fsl_esai.c
  40. +354
    -0
      sound/soc/fsl/fsl_esai.h
  41. +3
    -4
      sound/soc/fsl/fsl_sai.c
  42. +400
    -183
      sound/soc/fsl/fsl_ssi.c
  43. +0
    -3
      sound/soc/fsl/imx-pcm-dma.c
  44. +0
    -3
      sound/soc/fsl/imx-pcm-fiq.c
  45. +0
    -4
      sound/soc/fsl/mpc5200_dma.c
  46. +36
    -34
      sound/soc/generic/simple-card.c
  47. +0
    -10
      sound/soc/intel/sst_platform.c
  48. +0
    -4
      sound/soc/intel/sst_platform.h
  49. +0
    -16
      sound/soc/kirkwood/kirkwood-dma.c
  50. +0
    -6
      sound/soc/mxs/mxs-pcm.c
  51. +0
    -3
      sound/soc/nuc900/nuc900-pcm.c
  52. +0
    -17
      sound/soc/sh/dma-sh7760.c
  53. +0
    -6
      sound/soc/sh/fsi.c
  54. +0
    -6
      sound/soc/sh/rcar/core.c
  55. +2
    -0
      sound/soc/ux500/mop500.c
  56. +60
    -86
      sound/soc/ux500/ux500_msp_dai.c
  57. +41
    -15
      sound/soc/ux500/ux500_msp_i2s.c
  58. +1
    -1
      sound/soc/ux500/ux500_msp_i2s.h
  59. +33
    -32
      sound/soc/ux500/ux500_pcm.c

+ 50
- 0
Documentation/devicetree/bindings/sound/fsl,esai.txt View File

@ -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";
};

+ 6
- 1
Documentation/devicetree/bindings/sound/fsl,ssi.txt View File

@ -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


+ 1
- 1
Documentation/devicetree/bindings/sound/simple-card.txt View File

@ -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.


+ 1
- 0
Documentation/devicetree/bindings/sound/tlv320aic3x.txt View File

@ -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


+ 18
- 9
Documentation/sound/alsa/soc/overview.txt View File

@ -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.

+ 4
- 4
arch/arm/mach-ux500/board-mop500-audio.c View File

@ -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,
};

+ 163
- 27
drivers/mfd/twl-core.c View File

@ -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_map[mod_no].base + reg, value,
num_bytes);
ret = regmap_bulk_read(regmap, twl_priv->twl_map[mod_no].base + reg,
value, num_bytes);
if (ret)
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)
}
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);
/*----------------------------------------------------------------------*/
/**


+ 3
- 2
include/linux/i2c/twl.h View File

@ -175,6 +175,9 @@ static inline int twl_class_is_ ##class(void) \
TWL_CLASS_IS(4030, TWL4030_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.
*/
@ -667,8 +670,6 @@ struct twl4030_codec_data {
unsigned int digimic_delay; /* in ms */
unsigned int ramp_delay_value;
unsigned int offset_cncl_path;
unsigned int check_defaults:1;
unsigned int reset_registers:1;
unsigned int hs_extmute:1;
int hs_extmute_gpio;
};


+ 1
- 8
include/linux/platform_data/asoc-ux500-msp.h View File

@ -10,16 +10,9 @@
#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 */
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_tx;
};


+ 0
- 1
sound/soc/atmel/atmel-pcm-dma.c View File

@ -50,7 +50,6 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = {
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_PAUSE,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.period_bytes_min = 256, /* lighting DMA overhead */
.period_bytes_max = 2 * 0xffff, /* if 2 bytes format */
.periods_min = 8,


+ 0
- 1
sound/soc/atmel/atmel-pcm-pdc.c View File

@ -58,7 +58,6 @@ static const struct snd_pcm_hardware atmel_pcm_hardware = {
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.period_bytes_min = 32,
.period_bytes_max = 8192,
.periods_min = 2,


+ 0
- 1
sound/soc/bcm/Kconfig View File

@ -1,7 +1,6 @@
config SND_BCM2835_SOC_I2S
tristate "SoC Audio support for the Broadcom BCM2835 I2S module"
depends on ARCH_BCM2835 || COMPILE_TEST
select SND_SOC_DMAENGINE_PCM
select SND_SOC_GENERIC_DMAENGINE_PCM
select REGMAP_MMIO
help


+ 5
- 5
sound/soc/codecs/ad1836.c View File

@ -168,15 +168,15 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
int word_len = 0;
/* bit size */
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
word_len = AD1836_WORD_LEN_16;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
word_len = AD1836_WORD_LEN_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S32_LE:
case 24:
case 32:
word_len = AD1836_WORD_LEN_24;
break;
default:


+ 5
- 5
sound/soc/codecs/ad193x.c View File

@ -249,15 +249,15 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
/* bit size */
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
word_len = 3;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
word_len = 1;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S32_LE:
case 24:
case 32:
word_len = 0;
break;
}


+ 5
- 5
sound/soc/codecs/adau1373.c View File

@ -1078,17 +1078,17 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream,
ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK,
(div << 2) | ADAU1373_BCLKDIV_64);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
ctrl = ADAU1373_DAI_WLEN_16;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
ctrl = ADAU1373_DAI_WLEN_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
ctrl = ADAU1373_DAI_WLEN_24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
case 32:
ctrl = ADAU1373_DAI_WLEN_32;
break;
default:


+ 16
- 18
sound/soc/codecs/adau1701.c View File

@ -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,
snd_pcm_format_t format)
struct snd_pcm_hw_params *params)
{
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK;
unsigned int val;
switch (format) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
val = ADAU1701_SEROCTL_WORD_LEN_16;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
val = ADAU1701_SEROCTL_WORD_LEN_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
val = ADAU1701_SEROCTL_WORD_LEN_24;
break;
default:
@ -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) {
switch (format) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
val |= ADAU1701_SEROCTL_MSB_DEALY16;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
val |= ADAU1701_SEROCTL_MSB_DEALY12;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
val |= ADAU1701_SEROCTL_MSB_DEALY8;
break;
}
@ -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,
snd_pcm_format_t format)
struct snd_pcm_hw_params *params)
{
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
unsigned int val;
@ -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)
return 0;
switch (format) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
val = ADAU1701_SERICTL_RIGHTJ_16;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
val = ADAU1701_SERICTL_RIGHTJ_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
val = ADAU1701_SERICTL_RIGHTJ_24;
break;
default:
@ -374,7 +374,6 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec;
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
unsigned int clkdiv = adau1701->sysclk / params_rate(params);
snd_pcm_format_t format;
unsigned int val;
int ret;
@ -406,11 +405,10 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL,
ADAU1701_DSPCTRL_SR_MASK, val);
format = params_format(params);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return adau1701_set_playback_pcm_format(codec, format);
return adau1701_set_playback_pcm_format(codec, params);
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,


+ 14
- 16
sound/soc/codecs/adav80x.c View File

@ -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,
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);
unsigned int val;
switch (format) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
val = ADAV80X_CAPTURE_WORD_LEN16;
break;
case SNDRV_PCM_FORMAT_S18_3LE:
case 18:
val = ADAV80X_CAPTRUE_WORD_LEN18;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
val = ADAV80X_CAPTURE_WORD_LEN20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
val = ADAV80X_CAPTURE_WORD_LEN24;
break;
default:
@ -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,
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);
unsigned int val;
@ -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)
return 0;
switch (format) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_16;
break;
case SNDRV_PCM_FORMAT_S18_3LE:
case 18:
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_18;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_24;
break;
default:
@ -524,12 +524,10 @@ static int adav80x_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
adav80x_set_playback_pcm_format(codec, dai,
params_format(params));
adav80x_set_playback_pcm_format(codec, dai, params);
adav80x_set_dac_clock(codec, rate);
} else {
adav80x_set_capture_pcm_format(codec, dai,
params_format(params));
adav80x_set_capture_pcm_format(codec, dai, params);
adav80x_set_adc_clock(codec, rate);
}
adav80x->rate = rate;


+ 5
- 5
sound/soc/codecs/alc5623.c View File

@ -714,17 +714,17 @@ static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
iface &= ~ALC5623_DAI_I2S_DL_MASK;
/* bit size */
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
iface |= ALC5623_DAI_I2S_DL_16;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
iface |= ALC5623_DAI_I2S_DL_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
iface |= ALC5623_DAI_I2S_DL_24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
case 32:
iface |= ALC5623_DAI_I2S_DL_32;
break;
default:


+ 4
- 4
sound/soc/codecs/alc5632.c View File

@ -869,14 +869,14 @@ static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
iface &= ~ALC5632_DAI_I2S_DL_MASK;
/* bit size */
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
iface |= ALC5632_DAI_I2S_DL_16;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
iface |= ALC5632_DAI_I2S_DL_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
iface |= ALC5632_DAI_I2S_DL_24;
break;
default:


+ 9
- 8
sound/soc/codecs/arizona.h View File

@ -166,20 +166,21 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
ARIZONA_MIXER_INPUT_ROUTES(name " Input 4")
#define ARIZONA_DSP_ROUTES(name) \
{ name, NULL, name " Aux 1" }, \
{ name, NULL, name " Aux 2" }, \
{ name, NULL, name " Aux 3" }, \
{ name, NULL, name " Aux 4" }, \
{ name, NULL, name " Aux 5" }, \
{ name, NULL, name " Aux 6" }, \
{ name, NULL, name " Preloader"}, \
{ name " Preloader", NULL, name " Aux 1" }, \
{ name " Preloader", NULL, name " Aux 2" }, \
{ name " Preloader", NULL, name " Aux 3" }, \
{ name " Preloader", NULL, name " Aux 4" }, \
{ 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 2"), \
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \
ARIZONA_MIXER_ROUTES(name, name "L"), \
ARIZONA_MIXER_ROUTES(name, name "R")
ARIZONA_MIXER_ROUTES(name " Preloader", name "L"), \
ARIZONA_MIXER_ROUTES(name " Preloader", name "R")
#define ARIZONA_RATE_ENUM_SIZE 4
extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];


+ 5
- 9
sound/soc/codecs/cs42l51.c View File

@ -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);
break;
case SND_SOC_DAIFMT_RIGHT_J:
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
case SNDRV_PCM_FORMAT_S16_BE:
switch (params_width(params)) {
case 16:
fmt = CS42L51_DAC_DIF_RJ16;
break;
case SNDRV_PCM_FORMAT_S18_3LE:
case SNDRV_PCM_FORMAT_S18_3BE:
case 18:
fmt = CS42L51_DAC_DIF_RJ18;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case SNDRV_PCM_FORMAT_S20_3BE:
case 20:
fmt = CS42L51_DAC_DIF_RJ20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S24_BE:
case 24:
fmt = CS42L51_DAC_DIF_RJ24;
break;
default:


+ 5
- 5
sound/soc/codecs/da7210.c View File

@ -778,17 +778,17 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
dai_cfg1 |= DA7210_DAI_WORD_S20_3LE;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
break;
case SNDRV_PCM_FORMAT_S32_LE:
case 32:
dai_cfg1 |= DA7210_DAI_WORD_S32_LE;
break;
default:


+ 5
- 5
sound/soc/codecs/da7213.c View File

@ -1067,17 +1067,17 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
u8 fs;
/* Set DAI format */
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S16_LE;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S20_LE;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S24_LE;
break;
case SNDRV_PCM_FORMAT_S32_LE:
case 32:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S32_LE;
break;
default:


+ 5
- 5
sound/soc/codecs/da732x.c View File

@ -973,17 +973,17 @@ static int da732x_hw_params(struct snd_pcm_substream *substream,
reg_aif = dai->driver->base;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
aif |= DA732X_AIF_WORD_16;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
aif |= DA732X_AIF_WORD_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
aif |= DA732X_AIF_WORD_24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
case 32:
aif |= DA732X_AIF_WORD_32;
break;
default:


+ 5
- 5
sound/soc/codecs/da9055.c View File

@ -1058,17 +1058,17 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
u8 aif_ctrl, fs;
u32 sysclk;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
aif_ctrl = DA9055_AIF_WORD_S16_LE;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
aif_ctrl = DA9055_AIF_WORD_S20_3LE;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
aif_ctrl = DA9055_AIF_WORD_S24_LE;
break;
case SNDRV_PCM_FORMAT_S32_LE:
case 32:
aif_ctrl = DA9055_AIF_WORD_S32_LE;
break;
default:


+ 3
- 3
sound/soc/codecs/isabelle.c View File

@ -951,11 +951,11 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
ISABELLE_FS_RATE_MASK, fs_val);
/* bit size */
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S20_3LE:
switch (params_width(params)) {
case 20:
aif |= ISABELLE_AIF_LENGTH_20;
break;
case SNDRV_PCM_FORMAT_S32_LE:
case 32:
aif |= ISABELLE_AIF_LENGTH_32;
break;
default:


+ 3
- 3
sound/soc/codecs/max98088.c View File

@ -1233,12 +1233,12 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,
rate = params_rate(params);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
M98088_DAI_WS, 0);
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
M98088_DAI_WS, M98088_DAI_WS);
break;


+ 2
- 2
sound/soc/codecs/max98090.c View File

@ -1840,8 +1840,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
max98090->lrclk = params_rate(params);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
snd_soc_update_bits(codec, M98090_REG_INTERFACE_FORMAT,
M98090_WS_MASK, 0);
break;


+ 3
- 3
sound/soc/codecs/max98095.c View File

@ -1213,12 +1213,12 @@ static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
rate = params_rate(params);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
M98095_DAI_WS, 0);
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
M98095_DAI_WS, M98095_DAI_WS);
break;


+ 4
- 4
sound/soc/codecs/max9850.c View File

@ -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_LSB, lrclk_div & 0xff);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
switch (params_width(params)) {
case 16:
da = 0;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case 20:
da = 0x2;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case 24:
da = 0x3;
break;
default:


+ 10
- 24
sound/soc/codecs/mc13783.c View File

@ -750,30 +750,26 @@ static struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
.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 mc13xxx_codec_platform_data *pdata = pdev->dev.platform_data;
int ret;
mc13xxx = dev_get_drvdata(pdev->dev.parent);
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (priv == NULL)
if (!priv)
return -ENOMEM;
dev_set_drvdata(&pdev->dev, priv);
priv->mc13xxx = mc13xxx;
if (pdata) {
priv->adc_ssi_port = pdata->adc_ssi_port;
priv->dac_ssi_port = pdata->dac_ssi_port;
} else {
priv->adc_ssi_port = MC13783_SSI1_PORT;
priv->dac_ssi_port = MC13783_SSI2_PORT;
return -ENOSYS;
}
dev_set_drvdata(&pdev->dev, priv);
priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
if (priv->adc_ssi_port == priv->dac_ssi_port)
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
mc13783_dai_sync, ARRAY_SIZE(mc13783_dai_sync));
@ -781,14 +777,6 @@ static int mc13783_codec_probe(struct platform_device *pdev)
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
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;
}
@ -801,14 +789,12 @@ static int mc13783_codec_remove(struct platform_device *pdev)
static struct platform_driver mc13783_codec_driver = {
.driver = {
.name = "mc13783-codec",
.owner = THIS_MODULE,
},
.probe = mc13783_codec_probe,
.name = "mc13783-codec",
.owner = THIS_MODULE,
},
.remove = mc13783_codec_remove,
};
module_platform_driver(mc13783_codec_driver);
module_platform_driver_probe(mc13783_codec_driver, mc13783_codec_probe);
MODULE_DESCRIPTION("ASoC MC13783 driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>");


+ 10
- 4
sound/soc/codecs/ssm2602.c View File

@ -194,7 +194,7 @@ static const struct snd_soc_dapm_route ssm2604_routes[] = {
};
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 = {
@ -231,6 +231,11 @@ static const struct ssm2602_coeff ssm2602_coeff_table[] = {
{18432000, 32000, SSM2602_COEFF_SRATE(0x6, 0x1, 0x0)},
{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 */
{12288000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x0)},
{18432000, 8000, SSM2602_COEFF_SRATE(0x3, 0x1, 0x0)},
@ -473,9 +478,10 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 |\
SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
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 |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)


+ 134
- 242
sound/soc/codecs/twl4030.c View File

@ -48,86 +48,6 @@
#define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1)
/*
* twl4030 register cache & default register settings
*/
static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
0x00, /* this register not used */
0x00, /* REG_CODEC_MODE (0x1) */
0x00, /* REG_OPTION (0x2) */
0x00, /* REG_UNKNOWN (0x3) */
0x00, /* REG_MICBIAS_CTL (0x4) */
0x00, /* REG_ANAMICL (0x5) */
0x00, /* REG_ANAMICR (0x6) */
0x00, /* REG_AVADC_CTL (0x7) */
0x00, /* REG_ADCMICSEL (0x8) */
0x00, /* REG_DIGMIXING (0x9) */
0x0f, /* REG_ATXL1PGA (0xA) */
0x0f, /* REG_ATXR1PGA (0xB) */
0x0f, /* REG_AVTXL2PGA (0xC) */
0x0f, /* REG_AVTXR2PGA (0xD) */
0x00, /* REG_AUDIO_IF (0xE) */
0x00, /* REG_VOICE_IF (0xF) */
0x3f, /* REG_ARXR1PGA (0x10) */
0x3f, /* REG_ARXL1PGA (0x11) */
0x3f, /* REG_ARXR2PGA (0x12) */
0x3f, /* REG_ARXL2PGA (0x13) */
0x25, /* REG_VRXPGA (0x14) */
0x00, /* REG_VSTPGA (0x15) */
0x00, /* REG_VRX2ARXPGA (0x16) */
0x00, /* REG_AVDAC_CTL (0x17) */
0x00, /* REG_ARX2VTXPGA (0x18) */
0x32, /* REG_ARXL1_APGA_CTL (0x19) */
0x32, /* REG_ARXR1_APGA_CTL (0x1A) */
0x32, /* REG_ARXL2_APGA_CTL (0x1B) */
0x32, /* REG_ARXR2_APGA_CTL (0x1C) */
0x00, /* REG_ATX2ARXPGA (0x1D) */
0x00, /* REG_BT_IF (0x1E) */
0x55, /* REG_BTPGA (0x1F) */
0x00, /* REG_BTSTPGA (0x20) */
0x00, /* REG_EAR_CTL (0x21) */
0x00, /* REG_HS_SEL (0x22) */
0x00, /* REG_HS_GAIN_SET (0x23) */
0x00, /* REG_HS_POPN_SET (0x24) */
0x00, /* REG_PREDL_CTL (0x25) */
0x00, /* REG_PREDR_CTL (0x26) */
0x00, /* REG_PRECKL_CTL (0x27) */
0x00, /* REG_PRECKR_CTL (0x28) */
0x00, /* REG_HFL_CTL (0x29) */
0x00, /* REG_HFR_CTL (0x2A) */
0x05, /* REG_ALC_CTL (0x2B) */
0x00, /* REG_ALC_SET1 (0x2C) */
0x00, /* REG_ALC_SET2 (0x2D) */
0x00, /* REG_BOOST_CTL (0x2E) */
0x00, /* REG_SOFTVOL_CTL (0x2F) */
0x13, /* REG_DTMF_FREQSEL (0x30) */
0x00, /* REG_DTMF_TONEXT1H (0x31) */
0x00, /* REG_DTMF_TONEXT1L (0x32) */
0x00, /* REG_DTMF_TONEXT2H (0x33) */
0x00, /* REG_DTMF_TONEXT2L (0x34) */
0x79, /* REG_DTMF_TONOFF (0x35) */
0x11, /* REG_DTMF_WANONOFF (0x36) */
0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
0x06, /* REG_APLL_CTL (0x3A) */
0x00, /* REG_DTMF_CTL (0x3B) */
0x44, /* REG_DTMF_PGA_CTL2 (0x3C) */
0x69, /* REG_DTMF_PGA_CTL1 (0x3D) */
0x00, /* REG_MISC_SET_1 (0x3E) */
0x00, /* REG_PCMBTMUX (0x3F) */
0x00, /* not used (0x40) */
0x00, /* not used (0x41) */
0x00, /* not used (0x42) */
0x00, /* REG_RX_PATH_SEL (0x43) */
0x32, /* REG_VDL_APGA_CTL (0x44) */
0x00, /* REG_VIBRA_CTL (0x45) */
0x00, /* REG_VIBRA_SET (0x46) */
0x00, /* REG_VIBRA_PWM_SET (0x47) */
0x00, /* REG_ANAMIC_GAIN (0x48) */
0x00, /* REG_MISC_SET_2 (0x49) */
};
/* codec private data */
struct twl4030_priv {
unsigned int codec_powered;
@ -150,81 +70,108 @@ struct twl4030_priv {
u8 earpiece_enabled;
u8 predrivel_enabled, predriver_enabled;
u8 carkitl_enabled, carkitr_enabled;
u8 ctl_cache[TWL4030_REG_PRECKR_CTL - TWL4030_REG_EAR_CTL + 1];
struct twl4030_codec_data *pdata;
};
/*
* read twl4030 register cache
*/
static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
unsigned int reg)
static void tw4030_init_ctl_cache(struct twl4030_priv *twl4030)
{
u8 *cache = codec->reg_cache;
if (reg >= TWL4030_CACHEREGNUM)
return -EIO;
int i;
u8 byte;
return cache[reg];
for (i = TWL4030_REG_EAR_CTL; i <= TWL4030_REG_PRECKR_CTL; i++) {
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, i);
twl4030->ctl_cache[i - TWL4030_REG_EAR_CTL] = byte;
}
}
/*
* write twl4030 register cache
*/
static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
u8 reg, u8 value)
static unsigned int twl4030_read(struct snd_soc_codec *codec, unsigned int reg)
{
u8 *cache = codec->reg_cache;
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
u8 value = 0;
if (reg >= TWL4030_CACHEREGNUM)
return;
cache[reg] = value;
return -EIO;
switch (reg) {
case TWL4030_REG_EAR_CTL:
case TWL4030_REG_PREDL_CTL:
case TWL4030_REG_PREDR_CTL:
case TWL4030_REG_PRECKL_CTL:
case TWL4030_REG_PRECKR_CTL:
case TWL4030_REG_HS_GAIN_SET:
value = twl4030->ctl_cache[reg - TWL4030_REG_EAR_CTL];
break;
default:
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &value, reg);
break;
}
return value;
}
/*
* write to the twl4030 register space
*/
static int twl4030_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int value)
static bool twl4030_can_write_to_chip(struct twl4030_priv *twl4030,
unsigned int reg)
{
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
int write_to_reg = 0;
bool write_to_reg = false;
twl4030_write_reg_cache(codec, reg, value);
/* Decide if the given register can be written */
switch (reg) {
case TWL4030_REG_EAR_CTL:
if (twl4030->earpiece_enabled)
write_to_reg = 1;
write_to_reg = true;
break;
case TWL4030_REG_PREDL_CTL:
if (twl4030->predrivel_enabled)
write_to_reg = 1;
write_to_reg = true;
break;
case TWL4030_REG_PREDR_CTL:
if (twl4030->predriver_enabled)
write_to_reg = 1;
write_to_reg = true;
break;
case TWL4030_REG_PRECKL_CTL:
if (twl4030->carkitl_enabled)
write_to_reg = 1;
write_to_reg = true;
break;
case TWL4030_REG_PRECKR_CTL:
if (twl4030->carkitr_enabled)
write_to_reg = 1;
write_to_reg = true;
break;
case TWL4030_REG_HS_GAIN_SET:
if (twl4030->hsl_enabled || twl4030->hsr_enabled)
write_to_reg = 1;
write_to_reg = true;
break;
default:
/* All other register can be written */
write_to_reg = 1;
write_to_reg = true;
break;
}
return write_to_reg;
}
static int twl4030_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
/* Update the ctl cache */
switch (reg) {
case TWL4030_REG_EAR_CTL:
case TWL4030_REG_PREDL_CTL:
case TWL4030_REG_PREDR_CTL:
case TWL4030_REG_PRECKL_CTL:
case TWL4030_REG_PRECKR_CTL:
case TWL4030_REG_HS_GAIN_SET:
twl4030->ctl_cache[reg - TWL4030_REG_EAR_CTL] = value;
break;
default:
break;
}
if (write_to_reg)
return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
value, reg);
if (twl4030_can_write_to_chip(twl4030, reg))
return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
return 0;
}
@ -252,46 +199,14 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
else
mode = twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER);
if (mode >= 0) {
twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
if (mode >= 0)
twl4030->codec_powered = enable;
}
/* REVISIT: this delay is present in TI sample drivers */
/* but there seems to be no TRM requirement for it */
udelay(10);
}
static inline void twl4030_check_defaults(struct snd_soc_codec *codec)
{
int i, difference = 0;
u8 val;
dev_dbg(codec->dev, "Checking TWL audio default configuration\n");
for (i = 1; i <= TWL4030_REG_MISC_SET_2; i++) {
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, i);
if (val != twl4030_reg[i]) {
difference++;
dev_dbg(codec->dev,
"Reg 0x%02x: chip: 0x%02x driver: 0x%02x\n",
i, val, twl4030_reg[i]);
}
}
dev_dbg(codec->dev, "Found %d non-matching registers. %s\n",
difference, difference ? "Not OK" : "OK");
}
static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
{
int i;
/* set all audio section registers to reasonable defaults */
for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
if (i != TWL4030_REG_APLL_CTL)
twl4030_write(codec, i, twl4030_reg[i]);
}
static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata,
struct device_node *node)
{
@ -372,27 +287,17 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
}
}
/* Check defaults, if instructed before anything else */
if (pdata && pdata->check_defaults)
twl4030_check_defaults(codec);
/* Reset registers, if no setup data or if instructed to do so */
if (!pdata || (pdata && pdata->reset_registers))
twl4030_reset_registers(codec);
/* Refresh APLL_CTL register from HW */
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
TWL4030_REG_APLL_CTL);
twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, byte);
/* Initialize the local ctl register cache */
tw4030_init_ctl_cache(twl4030);
/* anti-pop when changing analog gain */
reg = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
reg = twl4030_read(codec, TWL4030_REG_MISC_SET_1);
twl4030_write(codec, TWL4030_REG_MISC_SET_1,
reg | TWL4030_SMOOTH_ANAVOL_EN);
reg | TWL4030_SMOOTH_ANAVOL_EN);
twl4030_write(codec, TWL4030_REG_OPTION,
TWL4030_ATXL1_EN | TWL4030_ATXR1_EN |
TWL4030_ARXL2_EN | TWL4030_ARXR2_EN);
TWL4030_ATXL1_EN | TWL4030_ATXR1_EN |
TWL4030_ARXL2_EN | TWL4030_ARXR2_EN);
/* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */
twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
@ -403,19 +308,19 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
twl4030->pdata = pdata;
reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
reg = twl4030_read(codec, TWL4030_REG_HS_POPN_SET);
reg &= ~TWL4030_RAMP_DELAY;
reg |= (pdata->ramp_delay_value << 2);
twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg);
twl4030_write(codec, TWL4030_REG_HS_POPN_SET, reg);