summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/atmel/atmel-pcm.c2
-rw-r--r--sound/soc/blackfin/bf6xx-i2s.c1
-rw-r--r--sound/soc/codecs/88pm860x-codec.c78
-rw-r--r--sound/soc/codecs/88pm860x-codec.h117
-rw-r--r--sound/soc/codecs/ab8500-codec.c85
-rw-r--r--sound/soc/codecs/ak4104.c11
-rw-r--r--sound/soc/codecs/ak4642.c2
-rw-r--r--sound/soc/codecs/arizona.c23
-rw-r--r--sound/soc/codecs/cq93vc.c46
-rw-r--r--sound/soc/codecs/max98088.c624
-rw-r--r--sound/soc/codecs/max98095.c470
-rw-r--r--sound/soc/codecs/max9850.c39
-rw-r--r--sound/soc/codecs/mc13783.c59
-rw-r--r--sound/soc/codecs/rt5640.c15
-rw-r--r--sound/soc/davinci/davinci-evm.c64
-rw-r--r--sound/soc/fsl/fsl_spdif.c18
-rw-r--r--sound/soc/fsl/fsl_ssi.c22
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c11
-rw-r--r--sound/soc/fsl/imx-spdif.c4
-rw-r--r--sound/soc/fsl/imx-wm8962.c3
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c4
-rw-r--r--sound/soc/mid-x86/mfld_machine.c10
-rw-r--r--sound/soc/mxs/mxs-saif.c12
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c20
-rw-r--r--sound/soc/omap/omap-mcpdm.c12
-rw-r--r--sound/soc/omap/omap-twl4030.c5
-rw-r--r--sound/soc/pxa/mmp-sspa.c5
-rw-r--r--sound/soc/samsung/bells.c1
-rw-r--r--sound/soc/samsung/i2s.c14
-rw-r--r--sound/soc/samsung/smdk_wm8994.c12
-rw-r--r--sound/soc/sh/rcar/adg.c11
-rw-r--r--sound/soc/sh/rcar/core.c45
-rw-r--r--sound/soc/sh/rcar/gen.c261
-rw-r--r--sound/soc/sh/rcar/rsnd.h4
-rw-r--r--sound/soc/soc-cache.c263
-rw-r--r--sound/soc/soc-core.c319
-rw-r--r--sound/soc/soc-devres.c86
-rw-r--r--sound/soc/soc-io.c26
-rw-r--r--sound/soc/soc-utils.c6
40 files changed, 1229 insertions, 1583 deletions
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 61a64d281905..8b9e70105dd2 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,5 +1,5 @@
snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
-snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o
+snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o soc-devres.o
ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),)
snd-soc-core-objs += soc-generic-dmaengine-pcm.o
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 3109db7b9017..612e5801003f 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -50,7 +50,7 @@ static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
buf->area = dma_alloc_coherent(pcm->card->dev, size,
&buf->addr, GFP_KERNEL);
pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n",
- (void *)buf->area, (void *)buf->addr, size);
+ (void *)buf->area, (void *)(long)buf->addr, size);
if (!buf->area)
return -ENOMEM;
diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c
index c02405cc007d..5810a0603f2f 100644
--- a/sound/soc/blackfin/bf6xx-i2s.c
+++ b/sound/soc/blackfin/bf6xx-i2s.c
@@ -88,6 +88,7 @@ static int bfin_i2s_hw_params(struct snd_pcm_substream *substream,
case SNDRV_PCM_FORMAT_S8:
param.spctl |= 0x70;
sport->wdsize = 1;
+ break;
case SNDRV_PCM_FORMAT_S16_LE:
param.spctl |= 0xf0;
sport->wdsize = 2;
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 8af04343cc1a..75d0ad5d2dcb 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -16,6 +16,7 @@
#include <linux/mfd/88pm860x.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -140,6 +141,7 @@ struct pm860x_priv {
unsigned int filter;
struct snd_soc_codec *codec;
struct i2c_client *i2c;
+ struct regmap *regmap;
struct pm860x_chip *chip;
struct pm860x_det det;
@@ -269,48 +271,6 @@ static struct st_gain st_table[] = {
{ -86, 29, 0}, { -56, 30, 0}, { -28, 31, 0}, { 0, 0, 0},
};
-static int pm860x_volatile(unsigned int reg)
-{
- BUG_ON(reg >= REG_CACHE_SIZE);
-
- switch (reg) {
- case PM860X_AUDIO_SUPPLIES_2:
- return 1;
- }
-
- return 0;
-}
-
-static unsigned int pm860x_read_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- unsigned char *cache = codec->reg_cache;
-
- BUG_ON(reg >= REG_CACHE_SIZE);
-
- if (pm860x_volatile(reg))
- return cache[reg];
-
- reg += REG_CACHE_BASE;
-
- return pm860x_reg_read(codec->control_data, reg);
-}
-
-static int pm860x_write_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- unsigned char *cache = codec->reg_cache;
-
- BUG_ON(reg >= REG_CACHE_SIZE);
-
- if (!pm860x_volatile(reg))
- cache[reg] = (unsigned char)value;
-
- reg += REG_CACHE_BASE;
-
- return pm860x_reg_write(codec->control_data, reg, value);
-}
-
static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -349,6 +309,9 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol,
val = ucontrol->value.integer.value[0];
val2 = ucontrol->value.integer.value[1];
+ if (val >= ARRAY_SIZE(st_table) || val2 >= ARRAY_SIZE(st_table))
+ return -EINVAL;
+
err = snd_soc_update_bits(codec, reg, 0x3f, st_table[val].m);
if (err < 0)
return err;
@@ -1166,6 +1129,7 @@ static int pm860x_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
static int pm860x_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
int data;
switch (level) {
@@ -1179,17 +1143,17 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Enable Audio PLL & Audio section */
data = AUDIO_PLL | AUDIO_SECTION_ON;
- pm860x_reg_write(codec->control_data, REG_MISC2, data);
+ pm860x_reg_write(pm860x->i2c, REG_MISC2, data);
udelay(300);
data = AUDIO_PLL | AUDIO_SECTION_RESET
| AUDIO_SECTION_ON;
- pm860x_reg_write(codec->control_data, REG_MISC2, data);
+ pm860x_reg_write(pm860x->i2c, REG_MISC2, data);
}
break;
case SND_SOC_BIAS_OFF:
data = AUDIO_PLL | AUDIO_SECTION_RESET | AUDIO_SECTION_ON;
- pm860x_set_bits(codec->control_data, REG_MISC2, data, 0);
+ pm860x_set_bits(pm860x->i2c, REG_MISC2, data, 0);
break;
}
codec->dapm.bias_level = level;
@@ -1319,17 +1283,17 @@ int pm860x_hs_jack_detect(struct snd_soc_codec *codec,
pm860x->det.lo_shrt = lo_shrt;
if (det & SND_JACK_HEADPHONE)
- pm860x_set_bits(codec->control_data, REG_HS_DET,
+ pm860x_set_bits(pm860x->i2c, REG_HS_DET,
EN_HS_DET, EN_HS_DET);
/* headset short detect */
if (hs_shrt) {
data = CLR_SHORT_HS2 | CLR_SHORT_HS1;
- pm860x_set_bits(codec->control_data, REG_SHORTS, data, data);
+ pm860x_set_bits(pm860x->i2c, REG_SHORTS, data, data);
}
/* Lineout short detect */
if (lo_shrt) {
data = CLR_SHORT_LO2 | CLR_SHORT_LO1;
- pm860x_set_bits(codec->control_data, REG_SHORTS, data, data);
+ pm860x_set_bits(pm860x->i2c, REG_SHORTS, data, data);
}
/* sync status */
@@ -1347,7 +1311,7 @@ int pm860x_mic_jack_detect(struct snd_soc_codec *codec,
pm860x->det.mic_det = det;
if (det & SND_JACK_MICROPHONE)
- pm860x_set_bits(codec->control_data, REG_MIC_DET,
+ pm860x_set_bits(pm860x->i2c, REG_MIC_DET,
MICDET_MASK, MICDET_MASK);
/* sync status */
@@ -1363,7 +1327,7 @@ static int pm860x_probe(struct snd_soc_codec *codec)
pm860x->codec = codec;
- codec->control_data = pm860x->i2c;
+ codec->control_data = pm860x->regmap;
for (i = 0; i < 4; i++) {
ret = request_threaded_irq(pm860x->irq[i], NULL,
@@ -1377,14 +1341,6 @@ static int pm860x_probe(struct snd_soc_codec *codec)
pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- ret = pm860x_bulk_read(codec->control_data, REG_CACHE_BASE,
- REG_CACHE_SIZE, codec->reg_cache);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to fill register cache: %d\n",
- ret);
- goto out;
- }
-
return 0;
out:
@@ -1407,10 +1363,6 @@ static int pm860x_remove(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_dev_pm860x = {
.probe = pm860x_probe,
.remove = pm860x_remove,
- .read = pm860x_read_reg_cache,
- .write = pm860x_write_reg_cache,
- .reg_cache_size = REG_CACHE_SIZE,
- .reg_word_size = sizeof(u8),
.set_bias_level = pm860x_set_bias_level,
.controls = pm860x_snd_controls,
@@ -1436,6 +1388,8 @@ static int pm860x_codec_probe(struct platform_device *pdev)
pm860x->chip = chip;
pm860x->i2c = (chip->id == CHIP_PM8607) ? chip->client
: chip->companion;
+ pm860x->regmap = (chip->id == CHIP_PM8607) ? chip->regmap
+ : chip->regmap_companion;
platform_set_drvdata(pdev, pm860x);
for (i = 0; i < 4; i++) {
diff --git a/sound/soc/codecs/88pm860x-codec.h b/sound/soc/codecs/88pm860x-codec.h
index 3364ba4a3607..f7282f4f4a79 100644
--- a/sound/soc/codecs/88pm860x-codec.h
+++ b/sound/soc/codecs/88pm860x-codec.h
@@ -12,67 +12,66 @@
#ifndef __88PM860X_H
#define __88PM860X_H
-/* The offset of these registers are 0xb0 */
-#define PM860X_PCM_IFACE_1 0x00
-#define PM860X_PCM_IFACE_2 0x01
-#define PM860X_PCM_IFACE_3 0x02
-#define PM860X_PCM_RATE 0x03
-#define PM860X_EC_PATH 0x04
-#define PM860X_SIDETONE_L_GAIN 0x05
-#define PM860X_SIDETONE_R_GAIN 0x06
-#define PM860X_SIDETONE_SHIFT 0x07
-#define PM860X_ADC_OFFSET_1 0x08
-#define PM860X_ADC_OFFSET_2 0x09
-#define PM860X_DMIC_DELAY 0x0a
+#define PM860X_PCM_IFACE_1 0xb0
+#define PM860X_PCM_IFACE_2 0xb1
+#define PM860X_PCM_IFACE_3 0xb2
+#define PM860X_PCM_RATE 0xb3
+#define PM860X_EC_PATH 0xb4
+#define PM860X_SIDETONE_L_GAIN 0xb5
+#define PM860X_SIDETONE_R_GAIN 0xb6
+#define PM860X_SIDETONE_SHIFT 0xb7
+#define PM860X_ADC_OFFSET_1 0xb8
+#define PM860X_ADC_OFFSET_2 0xb9
+#define PM860X_DMIC_DELAY 0xba
-#define PM860X_I2S_IFACE_1 0x0b
-#define PM860X_I2S_IFACE_2 0x0c
-#define PM860X_I2S_IFACE_3 0x0d
-#define PM860X_I2S_IFACE_4 0x0e
-#define PM860X_EQUALIZER_N0_1 0x0f
-#define PM860X_EQUALIZER_N0_2 0x10
-#define PM860X_EQUALIZER_N1_1 0x11
-#define PM860X_EQUALIZER_N1_2 0x12
-#define PM860X_EQUALIZER_D1_1 0x13
-#define PM860X_EQUALIZER_D1_2 0x14
-#define PM860X_LOFI_GAIN_LEFT 0x15
-#define PM860X_LOFI_GAIN_RIGHT 0x16
-#define PM860X_HIFIL_GAIN_LEFT 0x17
-#define PM860X_HIFIL_GAIN_RIGHT 0x18
-#define PM860X_HIFIR_GAIN_LEFT 0x19
-#define PM860X_HIFIR_GAIN_RIGHT 0x1a
-#define PM860X_DAC_OFFSET 0x1b
-#define PM860X_OFFSET_LEFT_1 0x1c
-#define PM860X_OFFSET_LEFT_2 0x1d
-#define PM860X_OFFSET_RIGHT_1 0x1e
-#define PM860X_OFFSET_RIGHT_2 0x1f
-#define PM860X_ADC_ANA_1 0x20
-#define PM860X_ADC_ANA_2 0x21
-#define PM860X_ADC_ANA_3 0x22
-#define PM860X_ADC_ANA_4 0x23
-#define PM860X_ANA_TO_ANA 0x24
-#define PM860X_HS1_CTRL 0x25
-#define PM860X_HS2_CTRL 0x26
-#define PM860X_LO1_CTRL 0x27
-#define PM860X_LO2_CTRL 0x28
-#define PM860X_EAR_CTRL_1 0x29
-#define PM860X_EAR_CTRL_2 0x2a
-#define PM860X_AUDIO_SUPPLIES_1 0x2b
-#define PM860X_AUDIO_SUPPLIES_2 0x2c
-#define PM860X_ADC_EN_1 0x2d
-#define PM860X_ADC_EN_2 0x2e
-#define PM860X_DAC_EN_1 0x2f
-#define PM860X_DAC_EN_2 0x31
-#define PM860X_AUDIO_CAL_1 0x32
-#define PM860X_AUDIO_CAL_2 0x33
-#define PM860X_AUDIO_CAL_3 0x34
-#define PM860X_AUDIO_CAL_4 0x35
-#define PM860X_AUDIO_CAL_5 0x36
-#define PM860X_ANA_INPUT_SEL_1 0x37
-#define PM860X_ANA_INPUT_SEL_2 0x38
+#define PM860X_I2S_IFACE_1 0xbb
+#define PM860X_I2S_IFACE_2 0xbc
+#define PM860X_I2S_IFACE_3 0xbd
+#define PM860X_I2S_IFACE_4 0xbe
+#define PM860X_EQUALIZER_N0_1 0xbf
+#define PM860X_EQUALIZER_N0_2 0xc0
+#define PM860X_EQUALIZER_N1_1 0xc1
+#define PM860X_EQUALIZER_N1_2 0xc2
+#define PM860X_EQUALIZER_D1_1 0xc3
+#define PM860X_EQUALIZER_D1_2 0xc4
+#define PM860X_LOFI_GAIN_LEFT 0xc5
+#define PM860X_LOFI_GAIN_RIGHT 0xc6
+#define PM860X_HIFIL_GAIN_LEFT 0xc7
+#define PM860X_HIFIL_GAIN_RIGHT 0xc8
+#define PM860X_HIFIR_GAIN_LEFT 0xc9
+#define PM860X_HIFIR_GAIN_RIGHT 0xca
+#define PM860X_DAC_OFFSET 0xcb
+#define PM860X_OFFSET_LEFT_1 0xcc
+#define PM860X_OFFSET_LEFT_2 0xcd
+#define PM860X_OFFSET_RIGHT_1 0xce
+#define PM860X_OFFSET_RIGHT_2 0xcf
+#define PM860X_ADC_ANA_1 0xd0
+#define PM860X_ADC_ANA_2 0xd1
+#define PM860X_ADC_ANA_3 0xd2
+#define PM860X_ADC_ANA_4 0xd3
+#define PM860X_ANA_TO_ANA 0xd4
+#define PM860X_HS1_CTRL 0xd5
+#define PM860X_HS2_CTRL 0xd6
+#define PM860X_LO1_CTRL 0xd7
+#define PM860X_LO2_CTRL 0xd8
+#define PM860X_EAR_CTRL_1 0xd9
+#define PM860X_EAR_CTRL_2 0xda
+#define PM860X_AUDIO_SUPPLIES_1 0xdb
+#define PM860X_AUDIO_SUPPLIES_2 0xdc
+#define PM860X_ADC_EN_1 0xdd
+#define PM860X_ADC_EN_2 0xde
+#define PM860X_DAC_EN_1 0xdf
+#define PM860X_DAC_EN_2 0xe1
+#define PM860X_AUDIO_CAL_1 0xe2
+#define PM860X_AUDIO_CAL_2 0xe3
+#define PM860X_AUDIO_CAL_3 0xe4
+#define PM860X_AUDIO_CAL_4 0xe5
+#define PM860X_AUDIO_CAL_5 0xe6
+#define PM860X_ANA_INPUT_SEL_1 0xe7
+#define PM860X_ANA_INPUT_SEL_2 0xe8
-#define PM860X_PCM_IFACE_4 0x39
-#define PM860X_I2S_IFACE_5 0x3a
+#define PM860X_PCM_IFACE_4 0xe9
+#define PM860X_I2S_IFACE_5 0xea
#define PM860X_SHORTS 0x3b
#define PM860X_PLL_ADJ_1 0x3c
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index b8ba0adacfce..a0394a8f2257 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -126,6 +126,8 @@ struct ab8500_codec_drvdata_dbg {
/* Private data for AB8500 device-driver */
struct ab8500_codec_drvdata {
+ struct regmap *regmap;
+
/* Sidetone */
long *sid_fir_values;
enum sid_state sid_status;
@@ -166,49 +168,35 @@ static inline const char *amic_type_str(enum amic_type type)
*/
/* Read a register from the audio-bank of AB8500 */
-static unsigned int ab8500_codec_read_reg(struct snd_soc_codec *codec,
- unsigned int reg)
+static int ab8500_codec_read_reg(void *context, unsigned int reg,
+ unsigned int *value)
{
+ struct device *dev = context;
int status;
- unsigned int value = 0;
u8 value8;
- status = abx500_get_register_interruptible(codec->dev, AB8500_AUDIO,
- reg, &value8);
- if (status < 0) {
- dev_err(codec->dev,
- "%s: ERROR: Register (0x%02x:0x%02x) read failed (%d).\n",
- __func__, (u8)AB8500_AUDIO, (u8)reg, status);
- } else {
- dev_dbg(codec->dev,
- "%s: Read 0x%02x from register 0x%02x:0x%02x\n",
- __func__, value8, (u8)AB8500_AUDIO, (u8)reg);
- value = (unsigned int)value8;
- }
+ status = abx500_get_register_interruptible(dev, AB8500_AUDIO,
+ reg, &value8);
+ *value = (unsigned int)value8;
- return value;
+ return status;
}
/* Write to a register in the audio-bank of AB8500 */
-static int ab8500_codec_write_reg(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
+static int ab8500_codec_write_reg(void *context, unsigned int reg,
+ unsigned int value)
{
- int status;
-
- status = abx500_set_register_interruptible(codec->dev, AB8500_AUDIO,
- reg, value);
- if (status < 0)
- dev_err(codec->dev,
- "%s: ERROR: Register (%02x:%02x) write failed (%d).\n",
- __func__, (u8)AB8500_AUDIO, (u8)reg, status);
- else
- dev_dbg(codec->dev,
- "%s: Wrote 0x%02x into register %02x:%02x\n",
- __func__, (u8)value, (u8)AB8500_AUDIO, (u8)reg);
+ struct device *dev = context;
- return status;
+ return abx500_set_register_interruptible(dev, AB8500_AUDIO,
+ reg, value);
}
+static const struct regmap_config ab8500_codec_regmap = {
+ .reg_read = ab8500_codec_read_reg,
+ .reg_write = ab8500_codec_write_reg,
+};
+
/*
* Controls - DAPM
*/
@@ -1225,13 +1213,18 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol,
struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
struct device *dev = codec->dev;
bool apply_fir, apply_iir;
- int req, status;
+ unsigned int req;
+ int status;
dev_dbg(dev, "%s: Enter.\n", __func__);
mutex_lock(&drvdata->anc_lock);
req = ucontrol->value.integer.value[0];
+ if (req >= ARRAY_SIZE(enum_anc_state)) {
+ status = -EINVAL;
+ goto cleanup;
+ }
if (req != ANC_APPLY_FIR_IIR && req != ANC_APPLY_FIR &&
req != ANC_APPLY_IIR) {
dev_err(dev, "%s: ERROR: Unsupported status to set '%s'!\n",
@@ -2480,9 +2473,13 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
dev_dbg(dev, "%s: Enter.\n", __func__);
+ snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
+
/* Setup AB8500 according to board-settings */
pdata = dev_get_platdata(dev->parent);
+ codec->control_data = drvdata->regmap;
+
if (np) {
if (!pdata)
pdata = devm_kzalloc(dev,
@@ -2527,12 +2524,10 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
}
/* Override HW-defaults */
- ab8500_codec_write_reg(codec,
- AB8500_ANACONF5,
- BIT(AB8500_ANACONF5_HSAUTOEN));
- ab8500_codec_write_reg(codec,
- AB8500_SHORTCIRCONF,
- BIT(AB8500_SHORTCIRCONF_HSZCDDIS));
+ snd_soc_write(codec, AB8500_ANACONF5,
+ BIT(AB8500_ANACONF5_HSAUTOEN));
+ snd_soc_write(codec, AB8500_SHORTCIRCONF,
+ BIT(AB8500_SHORTCIRCONF_HSZCDDIS));
/* Add filter controls */
status = snd_soc_add_codec_controls(codec, ab8500_filter_controls,
@@ -2562,9 +2557,6 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver ab8500_codec_driver = {
.probe = ab8500_codec_probe,
- .read = ab8500_codec_read_reg,
- .write = ab8500_codec_write_reg,
- .reg_word_size = sizeof(u8),
.controls = ab8500_ctrls,
.num_controls = ARRAY_SIZE(ab8500_ctrls),
.dapm_widgets = ab8500_dapm_widgets,
@@ -2587,6 +2579,15 @@ static int ab8500_codec_driver_probe(struct platform_device *pdev)
drvdata->anc_status = ANC_UNCONFIGURED;
dev_set_drvdata(&pdev->dev, drvdata);
+ drvdata->regmap = devm_regmap_init(&pdev->dev, NULL, &pdev->dev,
+ &ab8500_codec_regmap);
+ if (IS_ERR(drvdata->regmap)) {
+ status = PTR_ERR(drvdata->regmap);
+ dev_err(&pdev->dev, "%s: Failed to allocate regmap: %d\n",
+ __func__, status);
+ return status;
+ }
+
dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__);
status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver,
ab8500_codec_dai,
@@ -2601,7 +2602,7 @@ static int ab8500_codec_driver_probe(struct platform_device *pdev)
static int ab8500_codec_driver_remove(struct platform_device *pdev)
{
- dev_info(&pdev->dev, "%s Enter.\n", __func__);
+ dev_dbg(&pdev->dev, "%s Enter.\n", __func__);
snd_soc_unregister_codec(&pdev->dev);
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 71059c07ae7b..b4819dcd4f4d 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -45,8 +45,6 @@
#define AK4104_TX_TXE (1 << 0)
#define AK4104_TX_V (1 << 1)
-#define DRV_NAME "ak4104-codec"
-
struct ak4104_private {
struct regmap *regmap;
};
@@ -291,12 +289,19 @@ static const struct of_device_id ak4104_of_match[] = {
};
MODULE_DEVICE_TABLE(of, ak4104_of_match);
+static const struct spi_device_id ak4104_id_table[] = {
+ { "ak4104", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, ak4104_id_table);
+
static struct spi_driver ak4104_spi_driver = {
.driver = {
- .name = DRV_NAME,
+ .name = "ak4104",
.owner = THIS_MODULE,
.of_match_table = ak4104_of_match,
},
+ .id_table = ak4104_id_table,
.probe = ak4104_spi_probe,
.remove = ak4104_spi_remove,
};
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 2d0378709702..21c35ed778cc 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -352,7 +352,6 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
*/
default:
return -EINVAL;
- break;
}
snd_soc_update_bits(codec, MD_CTL1, DIF_MASK, data);
@@ -405,7 +404,6 @@ static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
break;
default:
return -EINVAL;
- break;
}
snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate);
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 657808ba1418..6f05b17d1965 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1477,21 +1477,25 @@ static void arizona_enable_fll(struct arizona_fll *fll,
{
struct arizona *arizona = fll->arizona;
int ret;
+ bool use_sync = false;
/*
* If we have both REFCLK and SYNCCLK then enable both,
* otherwise apply the SYNCCLK settings to REFCLK.
*/
- if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) {
+ if (fll->ref_src >= 0 && fll->ref_freq &&
+ fll->ref_src != fll->sync_src) {
regmap_update_bits(arizona->regmap, fll->base + 5,
ARIZONA_FLL1_OUTDIV_MASK,
ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
false);
- if (fll->sync_src >= 0)
+ if (fll->sync_src >= 0) {
arizona_apply_fll(arizona, fll->base + 0x10, sync,
fll->sync_src, true);
+ use_sync = true;
+ }
} else if (fll->sync_src >= 0) {
regmap_update_bits(arizona->regmap, fll->base + 5,
ARIZONA_FLL1_OUTDIV_MASK,
@@ -1511,7 +1515,7 @@ static void arizona_enable_fll(struct arizona_fll *fll,
* Increase the bandwidth if we're not using a low frequency
* sync source.
*/
- if (fll->sync_src >= 0 && fll->sync_freq > 100000)
+ if (use_sync && fll->sync_freq > 100000)
regmap_update_bits(arizona->regmap, fll->base + 0x17,
ARIZONA_FLL1_SYNC_BW, 0);
else
@@ -1526,8 +1530,7 @@ static void arizona_enable_fll(struct arizona_fll *fll,
regmap_update_bits(arizona->regmap, fll->base + 1,
ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
- if (fll->ref_src >= 0 && fll->sync_src >= 0 &&
- fll->ref_src != fll->sync_src)
+ if (use_sync)
regmap_update_bits(arizona->regmap, fll->base + 0x11,
ARIZONA_FLL1_SYNC_ENA,
ARIZONA_FLL1_SYNC_ENA);
@@ -1561,10 +1564,12 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
if (fll->ref_src == source && fll->ref_freq == Fref)
return 0;
- if (fll->fout && Fref > 0) {
- ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
- if (ret != 0)
- return ret;
+ if (fll->fout) {
+ if (Fref > 0) {
+ ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
+ if (ret != 0)
+ return ret;
+ }
if (fll->sync_src >= 0) {
ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 23316c887b19..43737a27d79c 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -38,24 +38,6 @@
#include <sound/soc.h>
#include <sound/initval.h>
-static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- struct davinci_vc *davinci_vc = codec->control_data;
-
- return readl(davinci_vc->base + reg);
-}
-
-static inline int cq93vc_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- struct davinci_vc *davinci_vc = codec->control_data;
-
- writel(value, davinci_vc->base + reg);
-
- return 0;
-}
-
static const struct snd_kcontrol_new cq93vc_snd_controls[] = {
SOC_SINGLE("PGA Capture Volume", DAVINCI_VC_REG05, 0, 0x03, 0),
SOC_SINGLE("Mono DAC Playback Volume", DAVINCI_VC_REG09, 0, 0x3f, 0),
@@ -64,13 +46,15 @@ static const struct snd_kcontrol_new cq93vc_snd_controls[] = {
static int cq93vc_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
- u8 reg = cq93vc_read(codec, DAVINCI_VC_REG09) & ~DAVINCI_VC_REG09_MUTE;
+ u8 reg;
if (mute)
- cq93vc_write(codec, DAVINCI_VC_REG09,
- reg | DAVINCI_VC_REG09_MUTE);
+ reg = DAVINCI_VC_REG09_MUTE;
else
- cq93vc_write(codec, DAVINCI_VC_REG09, reg);
+ reg = 0;
+
+ snd_soc_update_bits(codec, DAVINCI_VC_REG09, DAVINCI_VC_REG09_MUTE,
+ reg);
return 0;
}
@@ -79,7 +63,7 @@ static int cq93vc_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_codec *codec = codec_dai->codec;
- struct davinci_vc *davinci_vc = codec->control_data;
+ struct davinci_vc *davinci_vc = codec->dev->platform_data;
switch (freq) {
case 22579200:
@@ -97,18 +81,18 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
{
switch (level) {
case SND_SOC_BIAS_ON:
- cq93vc_write(codec, DAVINCI_VC_REG12,
+ snd_soc_write(codec, DAVINCI_VC_REG12,
DAVINCI_VC_REG12_POWER_ALL_ON);
break;
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- cq93vc_write(codec, DAVINCI_VC_REG12,
+ snd_soc_write(codec, DAVINCI_VC_REG12,
DAVINCI_VC_REG12_POWER_ALL_OFF);
break;
case SND_SOC_BIAS_OFF:
/* force all power off */
- cq93vc_write(codec, DAVINCI_VC_REG12,
+ snd_soc_write(codec, DAVINCI_VC_REG12,
DAVINCI_VC_REG12_POWER_ALL_OFF);
break;
}
@@ -154,11 +138,9 @@ static int cq93vc_probe(struct snd_soc_codec *codec)
struct davinci_vc *davinci_vc = codec->dev->platform_data;
davinci_vc->cq93vc.codec = codec;
- codec->control_data = davinci_vc;
+ codec->control_data = davinci_vc->regmap;
- /* Set controls */
- snd_soc_add_codec_controls(codec, cq93vc_snd_controls,
- ARRAY_SIZE(cq93vc_snd_controls));
+ snd_soc_codec_set_cache_io(codec, 32, 32, SND_SOC_REGMAP);
/* Off, with power on */
cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -174,12 +156,12 @@ static int cq93vc_remove(struct snd_soc_codec *codec)
}
static struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
- .read = cq93vc_read,
- .write = cq93vc_write,
.set_bias_level = cq93vc_set_bias_level,
.probe = cq93vc_probe,
.remove = cq93vc_remove,
.resume = cq93vc_resume,
+ .controls = cq93vc_snd_controls,
+ .num_controls = ARRAY_SIZE(cq93vc_snd_controls),
};
static int cq93vc_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 566a367c94fa..66ceee22fdad 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -38,294 +39,223 @@ struct max98088_cdata {
};
struct max98088_priv {
- enum max98088_type devtype;
- struct max98088_pdata *pdata;
- unsigned int sysclk;
- struct max98088_cdata dai[2];
- int eq_textcnt;
- const char **eq_texts;
- struct soc_enum eq_enum;
- u8 ina_state;
- u8 inb_state;
- unsigned int ex_mode;
- unsigned int digmic;
- unsigned int mic1pre;
- unsigned int mic2pre;
- unsigned int extmic_mode;
+ struct regmap *regmap;
+ enum max98088_type devtype;
+ struct max98088_pdata *pdata;
+ unsigned int sysclk;
+ struct max98088_cdata dai[2];
+ int eq_textcnt;
+ const char **eq_texts;
+ struct soc_enum eq_enum;
+ u8 ina_state;
+ u8 inb_state;
+ unsigned int ex_mode;
+ unsigned int digmic;
+ unsigned int mic1pre;
+ unsigned int mic2pre;
+ unsigned int extmic_mode;
};
-static const u8 max98088_reg[M98088_REG_CNT] = {
- 0x00, /* 00 IRQ status */
- 0x00, /* 01 MIC status */
- 0x00, /* 02 jack status */
- 0x00, /* 03 battery voltage */
- 0x00, /* 04 */
- 0x00, /* 05 */
- 0x00, /* 06 */
- 0x00, /* 07 */
- 0x00, /* 08 */
- 0x00, /* 09 */
- 0x00, /* 0A */
- 0x00, /* 0B */
- 0x00, /* 0C */
- 0x00, /* 0D */
- 0x00, /* 0E */
- 0x00, /* 0F interrupt enable */
-
- 0x00, /* 10 master clock */
- 0x00, /* 11 DAI1 clock mode */
- 0x00, /* 12 DAI1 clock control */
- 0x00, /* 13 DAI1 clock control */
- 0x00, /* 14 DAI1 format */
- 0x00, /* 15 DAI1 clock */
- 0x00, /* 16 DAI1 config */
- 0x00, /* 17 DAI1 TDM */
- 0x00, /* 18 DAI1 filters */
- 0x00, /* 19 DAI2 clock mode */
- 0x00, /* 1A DAI2 clock control */
- 0x00, /* 1B DAI2 clock control */
- 0x00, /* 1C DAI2 format */
- 0x00, /* 1D DAI2 clock */
- 0x00, /* 1E DAI2 config */
- 0x00, /* 1F DAI2 TDM */
-
- 0x00, /* 20 DAI2 filters */
- 0x00, /* 21 data config */
- 0x00, /* 22 DAC mixer */
- 0x00, /* 23 left ADC mixer */
- 0x00, /* 24 right ADC mixer */
- 0x00, /* 25 left HP mixer */
- 0x00, /* 26 right HP mixer */
- 0x00, /* 27 HP control */
- 0x00, /* 28 left REC mixer */
- 0x00, /* 29 right REC mixer */
- 0x00, /* 2A REC control */
- 0x00, /* 2B left SPK mixer */
- 0x00, /* 2C right SPK mixer */
- 0x00, /* 2D SPK control */
- 0x00, /* 2E sidetone */
- 0x00, /* 2F DAI1 playback level */
-
- 0x00, /* 30 DAI1 playback level */
- 0x00, /* 31 DAI2 playback level */
- 0x00, /* 32 DAI2 playbakc level */
- 0x00, /* 33 left ADC level */
- 0x00, /* 34 right ADC level */
- 0x00, /* 35 MIC1 level */
- 0x00, /* 36 MIC2 level */
- 0x00, /* 37 INA level */
- 0x00, /* 38 INB level */
- 0x00, /* 39 left HP volume */
- 0x00, /* 3A right HP volume */
- 0x00, /* 3B left REC volume */
- 0x00, /* 3C right REC volume */
- 0x00, /* 3D left SPK volume */
- 0x00, /* 3E right SPK volume */
- 0x00, /* 3F MIC config */
-
- 0x00, /* 40 MIC threshold */
- 0x00, /* 41 excursion limiter filter */
- 0x00, /* 42 excursion limiter threshold */
- 0x00, /* 43 ALC */
- 0x00, /* 44 power limiter threshold */
- 0x00, /* 45 power limiter config */
- 0x00, /* 46 distortion limiter config */
- 0x00, /* 47 audio input */
- 0x00, /* 48 microphone */
- 0x00, /* 49 level control */
- 0x00, /* 4A bypass switches */
- 0x00, /* 4B jack detect */
- 0x00, /* 4C input enable */
- 0x00, /* 4D output enable */
- 0xF0, /* 4E bias control */
- 0x00, /* 4F DAC power */
-
- 0x0F, /* 50 DAC power */
- 0x00, /* 51 system */
- 0x00, /* 52 DAI1 EQ1 */
- 0x00, /* 53 DAI1 EQ1 */
- 0x00, /* 54 DAI1 EQ1 */
- 0x00, /* 55 DAI1 EQ1 */
- 0x00, /* 56 DAI1 EQ1 */
- 0x00, /* 57 DAI1 EQ1 */
- 0x00, /* 58 DAI1 EQ1 */
- 0x00, /* 59 DAI1 EQ1 */
- 0x00, /* 5A DAI1 EQ1 */
- 0x00, /* 5B DAI1 EQ1 */
- 0x00, /* 5C DAI1 EQ2 */
- 0x00, /* 5D DAI1 EQ2 */
- 0x00, /* 5E DAI1 EQ2 */
- 0x00, /* 5F DAI1 EQ2 */
-
- 0x00, /* 60 DAI1 EQ2 */
- 0x00, /* 61 DAI1 EQ2 */
- 0x00, /* 62 DAI1 EQ2 */
- 0x00, /* 63 DAI1 EQ2 */
- 0x00, /* 64 DAI1 EQ2 */
- 0x00, /* 65 DAI1 EQ2 */
- 0x00, /* 66 DAI1 EQ3 */
- 0x00, /* 67 DAI1 EQ3 */
- 0x00, /* 68 DAI1 EQ3 */
- 0x00, /* 69 DAI1 EQ3 */
- 0x00, /* 6A DAI1 EQ3 */
- 0x00, /* 6B DAI1 EQ3 */
- 0x00, /* 6C DAI1 EQ3 */
- 0x00, /* 6D DAI1 EQ3 */
- 0x00, /* 6E DAI1 EQ3 */
- 0x00, /* 6F DAI1 EQ3 */
-
- 0x00, /* 70 DAI1 EQ4 */
- 0x00, /* 71 DAI1 EQ4 */
- 0x00, /* 72 DAI1 EQ4 */
- 0x00, /* 73 DAI1 EQ4 */
- 0x00, /* 74 DAI1 EQ4 */
- 0x00, /* 75 DAI1 EQ4 */
- 0x00, /* 76 DAI1 EQ4 */
- 0x00, /* 77 DAI1 EQ4 */
- 0x00, /* 78 DAI1 EQ4 */
- 0x00, /* 79 DAI1 EQ4 */
- 0x00, /* 7A DAI1 EQ5 */
- 0x00, /* 7B DAI1 EQ5 */
- 0x00, /* 7C DAI1 EQ5 */
- 0x00, /* 7D DAI1 EQ5 */
- 0x00, /* 7E DAI1 EQ5 */
- 0x00, /* 7F DAI1 EQ5 */
-
- 0x00, /* 80 DAI1 EQ5 */
- 0x00, /* 81 DAI1 EQ5 */
- 0x00, /* 82 DAI1 EQ5 */
- 0x00, /* 83 DAI1 EQ5 */
- 0x00, /* 84 DAI2 EQ1 */
- 0x00, /* 85 DAI2 EQ1 */
- 0x00, /* 86 DAI2 EQ1 */
- 0x00, /* 87 DAI2 EQ1 */
- 0x00, /* 88 DAI2 EQ1 */
- 0x00, /* 89 DAI2 EQ1 */
- 0x00, /* 8A DAI2 EQ1 */
- 0x00, /* 8B DAI2 EQ1 */
- 0x00, /* 8C DAI2 EQ1 */
- 0x00, /* 8D DAI2 EQ1 */
- 0x00, /* 8E DAI2 EQ2 */
- 0x00, /* 8F DAI2 EQ2 */
-
- 0x00, /* 90 DAI2 EQ2 */
- 0x00, /* 91 DAI2 EQ2 */
- 0x00, /* 92 DAI2 EQ2 */
- 0x00, /* 93 DAI2 EQ2 */
- 0x00, /* 94 DAI2 EQ2 */
- 0x00, /* 95 DAI2 EQ2 */
- 0x00, /* 96 DAI2 EQ2 */
- 0x00, /* 97 DAI2 EQ2 */
- 0x00, /* 98 DAI2 EQ3 */
- 0x00, /* 99 DAI2 EQ3 */
- 0x00, /* 9A DAI2 EQ3 */
- 0x00, /* 9B DAI2 EQ3 */
- 0x00, /* 9C DAI2 EQ3 */
- 0x00, /* 9D DAI2 EQ3 */
- 0x00, /* 9E DAI2 EQ3 */
- 0x00, /* 9F DAI2 EQ3 */
-
- 0x00, /* A0 DAI2 EQ3 */
- 0x00, /* A1 DAI2 EQ3 */
- 0x00, /* A2 DAI2 EQ4 */
- 0x00, /* A3 DAI2 EQ4 */
- 0x00, /* A4 DAI2 EQ4 */
- 0x00, /* A5 DAI2 EQ4 */
- 0x00, /* A6 DAI2 EQ4 */
- 0x00, /* A7 DAI2 EQ4 */
- 0x00, /* A8 DAI2 EQ4 */
- 0x00, /* A9 DAI2 EQ4 */
- 0x00, /* AA DAI2 EQ4 */
- 0x00, /* AB DAI2 EQ4 */
- 0x00, /* AC DAI2 EQ5 */
- 0x00, /* AD DAI2 EQ5 */
- 0x00, /* AE DAI2 EQ5 */
- 0x00, /* AF DAI2 EQ5 */
-
- 0x00, /* B0 DAI2 EQ5 */
- 0x00, /* B1 DAI2 EQ5 */
- 0x00, /* B2 DAI2 EQ5 */
- 0x00, /* B3 DAI2 EQ5 */
- 0x00, /* B4 DAI2 EQ5 */
- 0x00, /* B5 DAI2 EQ5 */
- 0x00, /* B6 DAI1 biquad */
- 0x00, /* B7 DAI1 biquad */
- 0x00, /* B8 DAI1 biquad */
- 0x00, /* B9 DAI1 biquad */
- 0x00, /* BA DAI1 biquad */
- 0x00, /* BB DAI1 biquad */
- 0x00, /* BC DAI1 biquad */
- 0x00, /* BD DAI1 biquad */
- 0x00, /* BE DAI1 biquad */
- 0x00, /* BF DAI1 biquad */
-
- 0x00, /* C0 DAI2 biquad */
- 0x00, /* C1 DAI2 biquad */
- 0x00, /* C2 DAI2 biquad */
- 0x00, /* C3 DAI2 biquad */
- 0x00, /* C4 DAI2 biquad */
- 0x00, /* C5 DAI2 biquad */
- 0x00, /* C6 DAI2 biquad */
- 0x00, /* C7 DAI2 biquad */
- 0x00, /* C8 DAI2 biquad */
- 0x00, /* C9 DAI2 biquad */
- 0x00, /* CA */
- 0x00, /* CB */
- 0x00, /* CC */
- 0x00, /* CD */
- 0x00, /* CE */
- 0x00, /* CF */
-
- 0x00, /* D0 */
- 0x00, /* D1 */
- 0x00, /* D2 */
- 0x00, /* D3 */
- 0x00, /* D4 */
- 0x00, /* D5 */
- 0x00, /* D6 */
- 0x00, /* D7 */
- 0x00, /* D8 */
- 0x00, /* D9 */
- 0x00, /* DA */
- 0x70, /* DB */
- 0x00, /* DC */
- 0x00, /* DD */
- 0x00, /* DE */
- 0x00, /* DF */
-
- 0x00, /* E0 */
- 0x00, /* E1 */
- 0x00, /* E2 */
- 0x00, /* E3 */
- 0x00, /* E4 */
- 0x00, /* E5 */
- 0x00, /* E6 */
- 0x00, /* E7 */
- 0x00, /* E8 */
- 0x00, /* E9 */
- 0x00, /* EA */
- 0x00, /* EB */
- 0x00, /* EC */
- 0x00, /* ED */
- 0x00, /* EE */
- 0x00, /* EF */
-
- 0x00, /* F0 */
- 0x00, /* F1 */
- 0x00, /* F2 */
- 0x00, /* F3 */
- 0x00, /* F4 */
- 0x00, /* F5 */
- 0x00, /* F6 */
- 0x00, /* F7 */
- 0x00, /* F8 */
- 0x00, /* F9 */
- 0x00, /* FA */
- 0x00, /* FB */
- 0x00, /* FC */
- 0x00, /* FD */
- 0x00, /* FE */
- 0x00, /* FF */
+static const struct reg_default max98088_reg[] = {
+ { 0xf, 0x00 }, /* 0F interrupt enable */
+
+ { 0x10, 0x00 }, /* 10 master clock */
+ { 0x11, 0x00 }, /* 11 DAI1 clock mode */
+ { 0x12, 0x00 }, /* 12 DAI1 clock control */
+ { 0x13, 0x00 }, /* 13 DAI1 clock control */
+ { 0x14, 0x00 }, /* 14 DAI1 format */
+ { 0x15, 0x00 }, /* 15 DAI1 clock */
+ { 0x16, 0x00 }, /* 16 DAI1 config */
+ { 0x17, 0x00 }, /* 17 DAI1 TDM */
+ { 0x18, 0x00 }, /* 18 DAI1 filters */
+ { 0x19, 0x00 }, /* 19 DAI2 clock mode */
+ { 0x1a, 0x00 }, /* 1A DAI2 clock control */
+ { 0x1b, 0x00 }, /* 1B DAI2 clock control */
+ { 0x1c, 0x00 }, /* 1C DAI2 format */
+ { 0x1d, 0x00 }, /* 1D DAI2 clock */
+ { 0x1e, 0x00 }, /* 1E DAI2 config */
+ { 0x1f, 0x00 }, /* 1F DAI2 TDM */
+
+ { 0x20, 0x00 }, /* 20 DAI2 filters */
+ { 0x21, 0x00 }, /* 21 data config */
+ { 0x22, 0x00 }, /* 22 DAC mixer */
+ { 0x23, 0x00 }, /* 23 left ADC mixer */
+ { 0x24, 0x00 }, /* 24 right ADC mixer */
+ { 0x25, 0x00 }, /* 25 left HP mixer */
+ { 0x26, 0x00 }, /* 26 right HP mixer */
+ { 0x27, 0x00 }, /* 27 HP control */
+ { 0x28, 0x00 }, /* 28 left REC mixer */
+ { 0x29, 0x00 }, /* 29 right REC mixer */
+ { 0x2a, 0x00 }, /* 2A REC control */
+ { 0x2b, 0x00 }, /* 2B left SPK mixer */
+ { 0x2c, 0x00 }, /* 2C right SPK mixer */
+ { 0x2d, 0x00 }, /* 2D SPK control */
+ { 0x2e, 0x00 }, /* 2E sidetone */
+ { 0x2f, 0x00 }, /* 2F DAI1 playback level */
+
+ { 0x30, 0x00 }, /* 30 DAI1 playback level */
+ { 0x31, 0x00 }, /* 31 DAI2 playback level */
+ { 0x32, 0x00 }, /* 32 DAI2 playbakc level */
+ { 0x33, 0x00 }, /* 33 left ADC level */
+ { 0x34, 0x00 }, /* 34 right ADC level */
+ { 0x35, 0x00 }, /* 35 MIC1 level */
+ { 0x36, 0x00 }, /* 36 MIC2 level */
+ { 0x37, 0x00 }, /* 37 INA level */
+ { 0x38, 0x00 }, /* 38 INB level */
+ { 0x39, 0x00 }, /* 39 left HP volume */
+ { 0x3a, 0x00 }, /* 3A right HP volume */
+ { 0x3b, 0x00 }, /* 3B left REC volume */
+ { 0x3c, 0x00 }, /* 3C right REC volume */
+ { 0x3d, 0x00 }, /* 3D left SPK volume */
+ { 0x3e, 0x00 }, /* 3E right SPK volume */
+ { 0x3f, 0x00 }, /* 3F MIC config */
+
+ { 0x40, 0x00 }, /* 40 MIC threshold */
+ { 0x41, 0x00 }, /* 41 excursion limiter filter */
+ { 0x42, 0x00 }, /* 42 excursion limiter threshold */
+ { 0x43, 0x00 }, /* 43 ALC */
+ { 0x44, 0x00 }, /* 44 power limiter threshold */
+ { 0x45, 0x00 }, /* 45 power limiter config */
+ { 0x46, 0x00 }, /* 46 distortion limiter config */
+ { 0x47, 0x00 }, /* 47 audio input */
+ { 0x48, 0x00 }, /* 48 microphone */
+ { 0x49, 0x00 }, /* 49 level control */
+ { 0x4a, 0x00 }, /* 4A bypass switches */
+ { 0x4b, 0x00 }, /* 4B jack detect */
+ { 0x4c, 0x00 }, /* 4C input enable */
+ { 0x4d, 0x00 }, /* 4D output enable */
+ { 0x4e, 0xF0 }, /* 4E bias control */
+ { 0x4f, 0x00 }, /* 4F DAC power */
+
+ { 0x50, 0x0F }, /* 50 DAC power */
+ { 0x51, 0x00 }, /* 51 system */
+ { 0x52, 0x00 }, /* 52 DAI1 EQ1 */
+ { 0x53, 0x00 }, /* 53 DAI1 EQ1 */
+ { 0x54, 0x00 }, /* 54 DAI1 EQ1 */
+ { 0x55, 0x00 }, /* 55 DAI1 EQ1 */
+ { 0x56, 0x00 }, /* 56 DAI1 EQ1 */
+ { 0x57, 0x00 }, /* 57 DAI1 EQ1 */
+ { 0x58, 0x00 }, /* 58 DAI1 EQ1 */
+ { 0x59, 0x00 }, /* 59 DAI1 EQ1 */
+ { 0x5a, 0x00 }, /* 5A DAI1 EQ1 */
+ { 0x5b, 0x00 }, /* 5B DAI1 EQ1 */
+ { 0x5c, 0x00 }, /* 5C DAI1 EQ2 */
+ { 0x5d, 0x00 }, /* 5D DAI1 EQ2 */
+ { 0x5e, 0x00 }, /* 5E DAI1 EQ2 */
+ { 0x5f, 0x00 }, /* 5F DAI1 EQ2 */
+
+ { 0x60, 0x00 }, /* 60 DAI1 EQ2 */
+ { 0x61, 0x00 }, /* 61 DAI1 EQ2 */
+ { 0x62, 0x00 }, /* 62 DAI1 EQ2 */
+ { 0x63, 0x00 }, /* 63 DAI1 EQ2 */
+ { 0x64, 0x00 }, /* 64 DAI1 EQ2 */
+ { 0x65, 0x00 }, /* 65 DAI1 EQ2 */
+ { 0x66, 0x00 }, /* 66 DAI1 EQ3 */
+ { 0x67, 0x00 }, /* 67 DAI1 EQ3 */
+ { 0x68, 0x00 }, /* 68 DAI1 EQ3 */
+ { 0x69, 0x00 }, /* 69 DAI1 EQ3 */
+ { 0x6a, 0x00 }, /* 6A DAI1 EQ3 */
+ { 0x6b, 0x00 }, /* 6B DAI1 EQ3 */
+ { 0x6c, 0x00 }, /* 6C DAI1 EQ3 */
+ { 0x6d, 0x00 }, /* 6D DAI1 EQ3 */
+ { 0x6e, 0x00 }, /* 6E DAI1 EQ3 */
+ { 0x6f, 0x00 }, /* 6F DAI1 EQ3 */
+
+ { 0x70, 0x00 }, /* 70 DAI1 EQ4 */
+ { 0x71, 0x00 }, /* 71 DAI1 EQ4 */
+ { 0x72, 0x00 }, /* 72 DAI1 EQ4 */
+ { 0x73, 0x00 }, /* 73 DAI1 EQ4 */
+ { 0x74, 0x00 }, /* 74 DAI1 EQ4 */
+ { 0x75, 0x00 }, /* 75 DAI1 EQ4 */
+ { 0x76, 0x00 }, /* 76 DAI1 EQ4 */
+ { 0x77, 0x00 }, /* 77 DAI1 EQ4 */
+ { 0x78, 0x00 }, /* 78 DAI1 EQ4 */
+ { 0x79, 0x00 }, /* 79 DAI1 EQ4 */
+ { 0x7a, 0x00 }, /* 7A DAI1 EQ5 */
+ { 0x7b, 0x00 }, /* 7B DAI1 EQ5 */
+ { 0x7c, 0x00 }, /* 7C DAI1 EQ5 */
+ { 0x7d, 0x00 }, /* 7D DAI1 EQ5 */
+ { 0x7e, 0x00 }, /* 7E DAI1 EQ5 */
+ { 0x7f, 0x00 }, /* 7F DAI1 EQ5 */
+
+ { 0x80, 0x00 }, /* 80 DAI1 EQ5 */
+ { 0x81, 0x00 }, /* 81 DAI1 EQ5 */
+ { 0x82, 0x00 }, /* 82 DAI1 EQ5 */
+ { 0x83, 0x00 }, /* 83 DAI1 EQ5 */
+ { 0x84, 0x00 }, /* 84 DAI2 EQ1 */
+ { 0x85, 0x00 }, /* 85 DAI2 EQ1 */
+ { 0x86, 0x00 }, /* 86 DAI2 EQ1 */
+ { 0x87, 0x00 }, /* 87 DAI2 EQ1 */
+ { 0x88, 0x00 }, /* 88 DAI2 EQ1 */
+ { 0x89, 0x00 }, /* 89 DAI2 EQ1 */
+ { 0x8a, 0x00 }, /* 8A DAI2 EQ1 */
+ { 0x8b, 0x00 }, /* 8B DAI2 EQ1 */
+ { 0x8c, 0x00 }, /* 8C DAI2 EQ1 */
+ { 0x8d, 0x00 }, /* 8D DAI2 EQ1 */
+ { 0x8e, 0x00 }, /* 8E DAI2 EQ2 */
+ { 0x8f, 0x00 }, /* 8F DAI2 EQ2 */
+
+ { 0x90, 0x00 }, /* 90 DAI2 EQ2 */
+ { 0x91, 0x00 }, /* 91 DAI2 EQ2 */
+ { 0x92, 0x00 }, /* 92 DAI2 EQ2 */
+ { 0x93, 0x00 }, /* 93 DAI2 EQ2 */
+ { 0x94, 0x00 }, /* 94 DAI2 EQ2 */
+ { 0x95, 0x00 }, /* 95 DAI2 EQ2 */
+ { 0x96, 0x00 }, /* 96 DAI2 EQ2 */
+ { 0x97, 0x00 }, /* 97 DAI2 EQ2 */
+ { 0x98, 0x00 }, /* 98 DAI2 EQ3 */
+ { 0x99, 0x00 }, /* 99 DAI2 EQ3 */
+ { 0x9a, 0x00 }, /* 9A DAI2 EQ3 */
+ { 0x9b, 0x00 }, /* 9B DAI2 EQ3 */
+ { 0x9c, 0x00 }, /* 9C DAI2 EQ3 */
+ { 0x9d, 0x00 }, /* 9D DAI2 EQ3 */
+ { 0x9e, 0x00 }, /* 9E DAI2 EQ3 */
+ { 0x9f, 0x00 }, /* 9F DAI2 EQ3 */
+
+ { 0xa0, 0x00 }, /* A0 DAI2 EQ3 */
+ { 0xa1, 0x00 }, /* A1 DAI2 EQ3 */
+ { 0xa2, 0x00 }, /* A2 DAI2 EQ4 */
+ { 0xa3, 0x00 }, /* A3 DAI2 EQ4 */
+ { 0xa4, 0x00 }, /* A4 DAI2 EQ4 */
+ { 0xa5, 0x00 }, /* A5 DAI2 EQ4 */
+ { 0xa6, 0x00 }, /* A6 DAI2 EQ4 */
+ { 0xa7, 0x00 }, /* A7 DAI2 EQ4 */
+ { 0xa8, 0x00 }, /* A8 DAI2 EQ4 */
+ { 0xa9, 0x00 }, /* A9 DAI2 EQ4 */
+ { 0xaa, 0x00 }, /* AA DAI2 EQ4 */
+ { 0xab, 0x00 }, /* AB DAI2 EQ4 */
+ { 0xac, 0x00 }, /* AC DAI2 EQ5 */
+ { 0xad, 0x00 }, /* AD DAI2 EQ5 */
+ { 0xae, 0x00 }, /* AE DAI2 EQ5 */
+ { 0xaf, 0x00 }, /* AF DAI2 EQ5 */
+
+ { 0xb0, 0x00 }, /* B0 DAI2 EQ5 */
+ { 0xb1, 0x00 }, /* B1 DAI2 EQ5 */
+ { 0xb2, 0x00 }, /* B2 DAI2 EQ5 */
+ { 0xb3, 0x00 }, /* B3 DAI2 EQ5 */
+ { 0xb4, 0x00 }, /* B4 DAI2 EQ5 */
+ { 0xb5, 0x00 }, /* B5 DAI2 EQ5 */
+ { 0xb6, 0x00 }, /* B6 DAI1 biquad */
+ { 0xb7, 0x00 }, /* B7 DAI1 biquad */
+ { 0xb8 ,0x00 }, /* B8 DAI1 biquad */
+ { 0xb9, 0x00 }, /* B9 DAI1 biquad */
+ { 0xba, 0x00 }, /* BA DAI1 biquad */
+ { 0xbb, 0x00 }, /* BB DAI1 biquad */
+ { 0xbc, 0x00 }, /* BC DAI1 biquad */
+ { 0xbd, 0x00 }, /* BD DAI1 biquad */
+ { 0xbe, 0x00 }, /* BE DAI1 biquad */
+ { 0xbf, 0x00 }, /* BF DAI1 biquad */
+
+ { 0xc0, 0x00 }, /* C0 DAI2 biquad */
+ { 0xc1, 0x00 }, /* C1 DAI2 biquad */
+ { 0xc2, 0x00 }, /* C2 DAI2 biquad */
+ { 0xc3, 0x00 }, /* C3 DAI2 biquad */
+ { 0xc4, 0x00 }, /* C4 DAI2 biquad */
+ { 0xc5, 0x00 }, /* C5 DAI2 biquad */
+ { 0xc6, 0x00 }, /* C6 DAI2 biquad */
+ { 0xc7, 0x00 }, /* C7 DAI2 biquad */
+ { 0xc8, 0x00 }, /* C8 DAI2 biquad */
+ { 0xc9, 0x00 }, /* C9 DAI2 biquad */
};
static struct {
@@ -606,11 +536,28 @@ static struct {
{ 0xFF, 0x00, 1 }, /* FF */
};
-static int max98088_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool max98088_readable_register(struct device *dev, unsigned int reg)
+{
+ return max98088_access[reg].readable;
+}
+
+static bool max98088_volatile_register(struct device *dev, unsigned int reg)
{
return max98088_access[reg].vol;
}
+static const struct regmap_config max98088_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .readable_reg = max98088_readable_register,
+ .volatile_reg = max98088_volatile_register,
+ .max_register = 0xff,
+
+ .reg_defaults = max98088_reg,
+ .num_reg_defaults = ARRAY_SIZE(max98088_reg),
+ .cache_type = REGCACHE_RBTREE,
+};
/*
* Load equalizer DSP coefficient configurations registers
@@ -1610,58 +1557,34 @@ static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute)
return 0;
}
-static void max98088_sync_cache(struct snd_soc_codec *codec)
-{
- u8 *reg_cache = codec->reg_cache;
- int i;
-
- if (!codec->cache_sync)
- return;
-
- codec->cache_only = 0;
-
- /* write back cached values if they're writeable and
- * different from the hardware default.
- */
- for (i = 1; i < codec->driver->reg_cache_size; i++) {
- if (!max98088_access[i].writable)
- continue;
-
- if (reg_cache[i] == max98088_reg[i])
- continue;
-
- snd_soc_write(codec, i, reg_cache[i]);
- }
-
- codec->cache_sync = 0;
-}
-
static int max98088_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
- max98088_sync_cache(codec);
-
- snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
- M98088_MBEN, M98088_MBEN);
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
- M98088_MBEN, 0);
- codec->cache_sync = 1;
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
+ struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
+ regcache_sync(max98088->regmap);
+
+ snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
+ M98088_MBEN, M98088_MBEN);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
+ M98088_MBEN, 0);
+ regcache_mark_dirty(max98088->regmap);
+ break;
+ }
+ codec->dapm.bias_level = level;
+ return 0;
}
#define MAX98088_RATES SNDRV_PCM_RATE_8000_96000
@@ -1988,9 +1911,9 @@ static int max98088_probe(struct snd_soc_codec *codec)
struct max98088_cdata *cdata;
int ret = 0;
- codec->cache_sync = 1;
+ regcache_mark_dirty(max98088->regmap);
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
@@ -2048,9 +1971,6 @@ static int max98088_probe(struct snd_soc_codec *codec)
max98088_handle_pdata(codec);
- snd_soc_add_codec_controls(codec, max98088_snd_controls,
- ARRAY_SIZE(max98088_snd_controls));
-
err_access:
return ret;
}
@@ -2066,15 +1986,13 @@ static int max98088_remove(struct snd_soc_codec *codec)
}
static struct snd_soc_codec_driver soc_codec_dev_max98088 = {
- .probe = max98088_probe,
- .remove = max98088_remove,
- .suspend = max98088_suspend,
- .resume = max98088_resume,
- .set_bias_level = max98088_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(max98088_reg),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = max98088_reg,
- .volatile_register = max98088_volatile_register,
+ .probe = max98088_probe,
+ .remove = max98088_remove,
+ .suspend = max98088_suspend,
+ .resume = max98088_resume,
+ .set_bias_level = max98088_set_bias_level,
+ .controls = max98088_snd_controls,
+ .num_controls = ARRAY_SIZE(max98088_snd_controls),
.dapm_widgets = max98088_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets),
.dapm_routes = max98088_audio_map,
@@ -2082,7 +2000,7 @@ static struct snd_soc_codec_driver soc_codec_dev_max98088 = {
};
static int max98088_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct max98088_priv *max98088;
int ret;
@@ -2092,6 +2010,10 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
if (max98088 == NULL)
return -ENOMEM;
+ max98088->regmap = devm_regmap_init_i2c(i2c, &max98088_regmap);
+ if (IS_ERR(max98088->regmap))
+ return PTR_ERR(max98088->regmap);
+
max98088->devtype = id->driver_data;
i2c_set_clientdata(i2c, max98088);
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 41cdd1642970..8fb072455802 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -39,6 +39,7 @@ struct max98095_cdata {
};
struct max98095_priv {
+ struct regmap *regmap;
enum max98095_type devtype;
struct max98095_pdata *pdata;
unsigned int sysclk;
@@ -56,263 +57,145 @@ struct max98095_priv {
struct snd_soc_jack *mic_jack;
};
-static const u8 max98095_reg_def[M98095_REG_CNT] = {
- 0x00, /* 00 */
- 0x00, /* 01 */
- 0x00, /* 02 */
- 0x00, /* 03 */
- 0x00, /* 04 */
- 0x00, /* 05 */
- 0x00, /* 06 */
- 0x00, /* 07 */
- 0x00, /* 08 */
- 0x00, /* 09 */
- 0x00, /* 0A */
- 0x00, /* 0B */
- 0x00, /* 0C */
- 0x00, /* 0D */
- 0x00, /* 0E */
- 0x00, /* 0F */
- 0x00, /* 10 */
- 0x00, /* 11 */
- 0x00, /* 12 */
- 0x00, /* 13 */
- 0x00, /* 14 */
- 0x00, /* 15 */
- 0x00, /* 16 */
- 0x00, /* 17 */
- 0x00, /* 18 */
- 0x00, /* 19 */
- 0x00, /* 1A */
- 0x00, /* 1B */
- 0x00, /* 1C */
- 0x00, /* 1D */
- 0x00, /* 1E */
- 0x00, /* 1F */
- 0x00, /* 20 */
- 0x00, /* 21 */
- 0x00, /* 22 */
- 0x00, /* 23 */
- 0x00, /* 24 */
- 0x00, /* 25 */
- 0x00, /* 26 */
- 0x00, /* 27 */
- 0x00, /* 28 */
- 0x00, /* 29 */
- 0x00, /* 2A */
- 0x00, /* 2B */
- 0x00, /* 2C */
- 0x00, /* 2D */
- 0x00, /* 2E */
- 0x00, /* 2F */
- 0x00, /* 30 */
- 0x00, /* 31 */
- 0x00, /* 32 */
- 0x00, /* 33 */
- 0x00, /* 34 */
- 0x00, /* 35 */
- 0x00, /* 36 */
- 0x00, /* 37 */
- 0x00, /* 38 */
- 0x00, /* 39 */
- 0x00, /* 3A */
- 0x00, /* 3B */
- 0x00, /* 3C */
- 0x00, /* 3D */
- 0x00, /* 3E */
- 0x00, /* 3F */
- 0x00, /* 40 */
- 0x00, /* 41 */
- 0x00, /* 42 */
- 0x00, /* 43 */
- 0x00, /* 44 */
- 0x00, /* 45 */
- 0x00, /* 46 */
- 0x00, /* 47 */
- 0x00, /* 48 */
- 0x00, /* 49 */
- 0x00, /* 4A */
- 0x00, /* 4B */
- 0x00, /* 4C */
- 0x00, /* 4D */
- 0x00, /* 4E */
- 0x00, /* 4F */
- 0x00, /* 50 */
- 0x00, /* 51 */
- 0x00, /* 52 */
- 0x00, /* 53 */
- 0x00, /* 54 */
- 0x00, /* 55 */
- 0x00, /* 56 */
- 0x00, /* 57 */
- 0x00, /* 58 */
- 0x00, /* 59 */
- 0x00, /* 5A */
- 0x00, /* 5B */
- 0x00, /* 5C */
- 0x00, /* 5D */
- 0x00, /* 5E */
- 0x00, /* 5F */
- 0x00, /* 60 */
- 0x00, /* 61 */
- 0x00, /* 62 */
- 0x00, /* 63 */
- 0x00, /* 64 */
- 0x00, /* 65 */
- 0x00, /* 66 */
- 0x00, /* 67 */
- 0x00, /* 68 */
- 0x00, /* 69 */
- 0x00, /* 6A */
- 0x00, /* 6B */
- 0x00, /* 6C */
- 0x00, /* 6D */
- 0x00, /* 6E */
- 0x00, /* 6F */
- 0x00, /* 70 */
- 0x00, /* 71 */
- 0x00, /* 72 */
- 0x00, /* 73 */
- 0x00, /* 74 */
- 0x00, /* 75 */
- 0x00, /* 76 */
- 0x00, /* 77 */
- 0x00, /* 78 */
- 0x00, /* 79 */
- 0x00, /* 7A */
- 0x00, /* 7B */
- 0x00, /* 7C */
- 0x00, /* 7D */
- 0x00, /* 7E */
- 0x00, /* 7F */
- 0x00, /* 80 */
- 0x00, /* 81 */
- 0x00, /* 82 */
- 0x00, /* 83 */
- 0x00, /* 84 */
- 0x00, /* 85 */
- 0x00, /* 86 */
- 0x00, /* 87 */
- 0x00, /* 88 */
- 0x00, /* 89 */
- 0x00, /* 8A */
- 0x00, /* 8B */
- 0x00, /* 8C */
- 0x00, /* 8D */
- 0x00, /* 8E */
- 0x00, /* 8F */
- 0x00, /* 90 */
- 0x00, /* 91 */
- 0x30, /* 92 */
- 0xF0, /* 93 */
- 0x00, /* 94 */
- 0x00, /* 95 */
- 0x3F, /* 96 */
- 0x00, /* 97 */
- 0x00, /* 98 */
- 0x00, /* 99 */
- 0x00, /* 9A */
- 0x00, /* 9B */
- 0x00, /* 9C */
- 0x00, /* 9D */
- 0x00, /* 9E */
- 0x00, /* 9F */
- 0x00, /* A0 */
- 0x00, /* A1 */
- 0x00, /* A2 */
- 0x00, /* A3 */
- 0x00, /* A4 */
- 0x00, /* A5 */
- 0x00, /* A6 */
- 0x00, /* A7 */
- 0x00, /* A8 */
- 0x00, /* A9 */
- 0x00, /* AA */
- 0x00, /* AB */
- 0x00, /* AC */
- 0x00, /* AD */
- 0x00, /* AE */
- 0x00, /* AF */
- 0x00, /* B0 */
- 0x00, /* B1 */
- 0x00, /* B2 */
- 0x00, /* B3 */
- 0x00, /* B4 */
- 0x00, /* B5 */
- 0x00, /* B6 */
- 0x00, /* B7 */
- 0x00, /* B8 */
- 0x00, /* B9 */
- 0x00, /* BA */
- 0x00, /* BB */
- 0x00, /* BC */
- 0x00, /* BD */
- 0x00, /* BE */
- 0x00, /* BF */
- 0x00, /* C0 */
- 0x00, /* C1 */
- 0x00, /* C2 */
- 0x00, /* C3 */
- 0x00, /* C4 */
- 0x00, /* C5 */
- 0x00, /* C6 */
- 0x00, /* C7 */
- 0x00, /* C8 */
- 0x00, /* C9 */
- 0x00, /* CA */
- 0x00, /* CB */
- 0x00, /* CC */
- 0x00, /* CD */
- 0x00, /* CE */
- 0x00, /* CF */
- 0x00, /* D0 */
- 0x00, /* D1 */
- 0x00, /* D2 */
- 0x00, /* D3 */
- 0x00, /* D4 */
- 0x00, /* D5 */
- 0x00, /* D6 */
- 0x00, /* D7 */
- 0x00, /* D8 */
- 0x00, /* D9 */
- 0x00, /* DA */
- 0x00, /* DB */
- 0x00, /* DC */
- 0x00, /* DD */
- 0x00, /* DE */
- 0x00, /* DF */
- 0x00, /* E0 */
- 0x00, /* E1 */
- 0x00, /* E2 */
- 0x00, /* E3 */
- 0x00, /* E4 */
- 0x00, /* E5 */
- 0x00, /* E6 */
- 0x00, /* E7 */
- 0x00, /* E8 */
- 0x00, /* E9 */
- 0x00, /* EA */
- 0x00, /* EB */
- 0x00, /* EC */
- 0x00, /* ED */
- 0x00, /* EE */
- 0x00, /* EF */
- 0x00, /* F0 */
- 0x00, /* F1 */
- 0x00, /* F2 */
- 0x00, /* F3 */
- 0x00, /* F4 */
- 0x00, /* F5 */
- 0x00, /* F6 */
- 0x00, /* F7 */
- 0x00, /* F8 */
- 0x00, /* F9 */
- 0x00, /* FA */
- 0x00, /* FB */
- 0x00, /* FC */
- 0x00, /* FD */
- 0x00, /* FE */
- 0x00, /* FF */
+static const struct reg_default max98095_reg_def[] = {
+ { 0xf, 0x00 }, /* 0F */
+ { 0x10, 0x00 }, /* 10 */
+ { 0x11, 0x00 }, /* 11 */
+ { 0x12, 0x00 }, /* 12 */
+ { 0x13, 0x00 }, /* 13 */
+ { 0x14, 0x00 }, /* 14 */
+ { 0x15, 0x00 }, /* 15 */
+ { 0x16, 0x00 }, /* 16 */
+ { 0x17, 0x00 }, /* 17 */
+ { 0x18, 0x00 }, /* 18 */
+ { 0x19, 0x00 }, /* 19 */
+ { 0x1a, 0x00 }, /* 1A */
+ { 0x1b, 0x00 }, /* 1B */
+ { 0x1c, 0x00 }, /* 1C */
+ { 0x1d, 0x00 }, /* 1D */
+ { 0x1e, 0x00 }, /* 1E */
+ { 0x1f, 0x00 }, /* 1F */
+ { 0x20, 0x00 }, /* 20 */
+ { 0x21, 0x00 }, /* 21 */
+ { 0x22, 0x00 }, /* 22 */
+ { 0x23, 0x00 }, /* 23 */
+ { 0x24, 0x00 }, /* 24 */
+ { 0x25, 0x00 }, /* 25 */
+ { 0x26, 0x00 }, /* 26 */
+ { 0x27, 0x00 }, /* 27 */
+ { 0x28, 0x00 }, /* 28 */
+ { 0x29, 0x00 }, /* 29 */
+ { 0x2a, 0x00 }, /* 2A */
+ { 0x2b, 0x00 }, /* 2B */
+ { 0x2c, 0x00 }, /* 2C */
+ { 0x2d, 0x00 }, /* 2D */
+ { 0x2e, 0x00 }, /* 2E */
+ { 0x2f, 0x00 }, /* 2F */
+ { 0x30, 0x00 }, /* 30 */
+ { 0x31, 0x00 }, /* 31 */
+ { 0x32, 0x00 }, /* 32 */
+ { 0x33, 0x00 }, /* 33 */
+ { 0x34, 0x00 }, /* 34 */
+ { 0x35, 0x00 }, /* 35 */
+ { 0x36, 0x00 }, /* 36 */
+ { 0x37, 0x00 }, /* 37 */
+ { 0x38, 0x00 }, /* 38 */
+ { 0x39, 0x00 }, /* 39 */
+ { 0x3a, 0x00 }, /* 3A */
+ { 0x3b, 0x00 }, /* 3B */
+ { 0x3c, 0x00 }, /* 3C */
+ { 0x3d, 0x00 }, /* 3D */
+ { 0x3e, 0x00 }, /* 3E */
+ { 0x3f, 0x00 }, /* 3F */
+ { 0x40, 0x00 }, /* 40 */
+ { 0x41, 0x00 }, /* 41 */
+ { 0x42, 0x00 }, /* 42 */
+ { 0x43, 0x00 }, /* 43 */
+ { 0x44, 0x00 }, /* 44 */
+ { 0x45, 0x00 }, /* 45 */
+ { 0x46, 0x00 }, /* 46 */
+ { 0x47, 0x00 }, /* 47 */
+ { 0x48, 0x00 }, /* 48 */
+ { 0x49, 0x00 }, /* 49 */
+ { 0x4a, 0x00 }, /* 4A */
+ { 0x4b, 0x00 }, /* 4B */
+ { 0x4c, 0x00 }, /* 4C */
+ { 0x4d, 0x00 }, /* 4D */
+ { 0x4e, 0x00 }, /* 4E */
+ { 0x4f, 0x00 }, /* 4F */
+ { 0x50, 0x00 }, /* 50 */
+ { 0x51, 0x00 }, /* 51 */
+ { 0x52, 0x00 }, /* 52 */
+ { 0x53, 0x00 }, /* 53 */
+ { 0x54, 0x00 }, /* 54 */
+ { 0x55, 0x00 }, /* 55 */
+ { 0x56, 0x00 }, /* 56 */
+ { 0x57, 0x00 }, /* 57 */
+ { 0x58, 0x00 }, /* 58 */
+ { 0x59, 0x00 }, /* 59 */
+ { 0x5a, 0x00 }, /* 5A */
+ { 0x5b, 0x00 }, /* 5B */
+ { 0x5c, 0x00 }, /* 5C */
+ { 0x5d, 0x00 }, /* 5D */
+ { 0x5e, 0x00 }, /* 5E */
+ { 0x5f, 0x00 }, /* 5F */
+ { 0x60, 0x00 }, /* 60 */
+ { 0x61, 0x00 }, /* 61 */
+ { 0x62, 0x00 }, /* 62 */
+ { 0x63, 0x00 }, /* 63 */
+ { 0x64, 0x00 }, /* 64 */
+ { 0x65, 0x00 }, /* 65 */
+ { 0x66, 0x00 }, /* 66 */
+ { 0x67, 0x00 }, /* 67 */
+ { 0x68, 0x00 }, /* 68 */
+ { 0x69, 0x00 }, /* 69 */
+ { 0x6a, 0x00 }, /* 6A */
+ { 0x6b, 0x00 }, /* 6B */
+ { 0x6c, 0x00 }, /* 6C */
+ { 0x6d, 0x00 }, /* 6D */
+ { 0x6e, 0x00 }, /* 6E */
+ { 0x6f, 0x00 }, /* 6F */
+ { 0x70, 0x00 }, /* 70 */
+ { 0x71, 0x00 }, /* 71 */
+ { 0x72, 0x00 }, /* 72 */
+ { 0x73, 0x00 }, /* 73 */
+ { 0x74, 0x00 }, /* 74 */
+ { 0x75, 0x00 }, /* 75 */
+ { 0x76, 0x00 }, /* 76 */
+ { 0x77, 0x00 }, /* 77 */
+ { 0x78, 0x00 }, /* 78 */
+ { 0x79, 0x00 }, /* 79 */
+ { 0x7a, 0x00 }, /* 7A */
+ { 0x7b, 0x00 }, /* 7B */
+ { 0x7c, 0x00 }, /* 7C */
+ { 0x7d, 0x00 }, /* 7D */
+ { 0x7e, 0x00 }, /* 7E */
+ { 0x7f, 0x00 }, /* 7F */
+ { 0x80, 0x00 }, /* 80 */
+ { 0x81, 0x00 }, /* 81 */
+ { 0x82, 0x00 }, /* 82 */
+ { 0x83, 0x00 }, /* 83 */
+ { 0x84, 0x00 }, /* 84 */
+ { 0x85, 0x00 }, /* 85 */
+ { 0x86, 0x00 }, /* 86 */
+ { 0x87, 0x00 }, /* 87 */
+ { 0x88, 0x00 }, /* 88 */
+ { 0x89, 0x00 }, /* 89 */
+ { 0x8a, 0x00 }, /* 8A */
+ { 0x8b, 0x00 }, /* 8B */
+ { 0x8c, 0x00 }, /* 8C */
+ { 0x8d, 0x00 }, /* 8D */
+ { 0x8e, 0x00 }, /* 8E */
+ { 0x8f, 0x00 }, /* 8F */
+ { 0x90, 0x00 }, /* 90 */
+ { 0x91, 0x00 }, /* 91 */
+ { 0x92, 0x30 }, /* 92 */
+ { 0x93, 0xF0 }, /* 93 */
+ { 0x94, 0x00 }, /* 94 */
+ { 0x95, 0x00 }, /* 95 */
+ { 0x96, 0x3F }, /* 96 */
+ { 0x97, 0x00 }, /* 97 */
+ { 0xff, 0x00 }, /* FF */
};
static struct {
@@ -577,14 +460,14 @@ static struct {
{ 0xFF, 0x00 }, /* FF */
};
-static int max98095_readable(struct snd_soc_codec *codec, unsigned int reg)
+static bool max98095_readable(struct device *dev, unsigned int reg)
{
if (reg >= M98095_REG_CNT)
return 0;
return max98095_access[reg].readable != 0;
}
-static int max98095_volatile(struct snd_soc_codec *codec, unsigned int reg)
+static bool max98095_volatile(struct device *dev, unsigned int reg)
{
if (reg > M98095_REG_MAX_CACHED)
return 1;
@@ -611,22 +494,18 @@ static int max98095_volatile(struct snd_soc_codec *codec, unsigned int reg)
return 0;
}
-/*
- * Filter coefficients are in a separate register segment
- * and they share the address space of the normal registers.
- * The coefficient registers do not need or share the cache.
- */
-static int max98095_hw_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- int ret;
+static const struct regmap_config max98095_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
- codec->cache_bypass = 1;
- ret = snd_soc_write(codec, reg, value);
- codec->cache_bypass = 0;
+ .reg_defaults = max98095_reg_def,
+ .num_reg_defaults = ARRAY_SIZE(max98095_reg_def),
+ .max_register = M98095_0FF_REV_ID,
+ .cache_type = REGCACHE_RBTREE,
- return ret ? -EIO : 0;
-}
+ .readable_reg = max98095_readable,
+ .volatile_reg = max98095_volatile,
+};
/*
* Load equalizer DSP coefficient configurations registers
@@ -648,8 +527,8 @@ static void m98095_eq_band(struct snd_soc_codec *codec, unsigned int dai,
/* Step through the registers and coefs */
for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
- max98095_hw_write(codec, eq_reg++, M98095_BYTE1(coefs[i]));
- max98095_hw_write(codec, eq_reg++, M98095_BYTE0(coefs[i]));
+ snd_soc_write(codec, eq_reg++, M98095_BYTE1(coefs[i]));
+ snd_soc_write(codec, eq_reg++, M98095_BYTE0(coefs[i]));
}
}
@@ -673,8 +552,8 @@ static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai,
/* Step through the registers and coefs */
for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
- max98095_hw_write(codec, bq_reg++, M98095_BYTE1(coefs[i]));
- max98095_hw_write(codec, bq_reg++, M98095_BYTE0(coefs[i]));
+ snd_soc_write(codec, bq_reg++, M98095_BYTE1(coefs[i]));
+ snd_soc_write(codec, bq_reg++, M98095_BYTE0(coefs[i]));
}
}
@@ -1285,14 +1164,6 @@ static const struct snd_soc_dapm_route max98095_audio_map[] = {
{"MIC2 Input", NULL, "MIC2"},
};
-static int max98095_add_widgets(struct snd_soc_codec *codec)
-{
- snd_soc_add_codec_controls(codec, max98095_snd_controls,
- ARRAY_SIZE(max98095_snd_controls));
-
- return 0;
-}
-
/* codec mclk clock divider coefficients */
static const struct {
u32 rate;
@@ -1748,6 +1619,7 @@ static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
static int max98095_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
int ret;
switch (level) {
@@ -1759,7 +1631,7 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = snd_soc_cache_sync(codec);
+ ret = regcache_sync(max98095->regmap);
if (ret != 0) {
dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
@@ -1774,7 +1646,7 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_OFF:
snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
M98095_MBEN, 0);
- codec->cache_sync = 1;
+ regcache_mark_dirty(max98095->regmap);
break;
}
codec->dapm.bias_level = level;
@@ -1863,7 +1735,7 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
struct max98095_pdata *pdata = max98095->pdata;
int channel = max98095_get_eq_channel(kcontrol->id.name);
struct max98095_cdata *cdata;
- int sel = ucontrol->value.integer.value[0];
+ unsigned int sel = ucontrol->value.integer.value[0];
struct max98095_eq_cfg *coef_set;
int fs, best, best_val, i;
int regmask, regsave;
@@ -2016,7 +1888,7 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
struct max98095_pdata *pdata = max98095->pdata;
int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
struct max98095_cdata *cdata;
- int sel = ucontrol->value.integer.value[0];
+ unsigned int sel = ucontrol->value.integer.value[0];
struct max98095_biquad_cfg *coef_set;
int fs, best, best_val, i;
int regmask, regsave;
@@ -2341,7 +2213,7 @@ static int max98095_reset(struct snd_soc_codec *codec)
/* Reset to hardware default for registers, as there is not
* a soft reset hardware control register */
for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
- ret = snd_soc_write(codec, i, max98095_reg_def[i]);
+ ret = snd_soc_write(codec, i, snd_soc_read(codec, i));
if (ret < 0) {
dev_err(codec->dev, "Failed to reset: %d\n", ret);
return ret;
@@ -2358,7 +2230,7 @@ static int max98095_probe(struct snd_soc_codec *codec)
struct i2c_client *client;
int ret = 0;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
@@ -2447,8 +2319,6 @@ static int max98095_probe(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, M98095_097_PWR_SYS, M98095_SHDNRUN,
M98095_SHDNRUN);
- max98095_add_widgets(codec);
-
return 0;
err_irq:
@@ -2480,11 +2350,8 @@ static struct snd_soc_codec_driver soc_codec_dev_max98095 = {
.suspend = max98095_suspend,
.resume = max98095_resume,
.set_bias_level = max98095_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(max98095_reg_def),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = max98095_reg_def,
- .readable_register = max98095_readable,
- .volatile_register = max98095_volatile,
+ .controls = max98095_snd_controls,
+ .num_controls = ARRAY_SIZE(max98095_snd_controls),
.dapm_widgets = max98095_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets),
.dapm_routes = max98095_audio_map,
@@ -2502,6 +2369,13 @@ static int max98095_i2c_probe(struct i2c_client *i2c,
if (max98095 == NULL)
return -ENOMEM;
+ max98095->regmap = devm_regmap_init_i2c(i2c, &max98095_regmap);
+ if (IS_ERR(max98095->regmap)) {
+ ret = PTR_ERR(max98095->regmap);
+ dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
+ return ret;
+ }
+
max98095->devtype = id->driver_data;
i2c_set_clientdata(i2c, max98095);
max98095->pdata = i2c->dev.platform_data;
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index 58c38a5b481c..c5dd61785f8d 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -27,18 +28,26 @@
#include "max9850.h"
struct max9850_priv {
+ struct regmap *regmap;
unsigned int sysclk;
};
/* max9850 register cache */
-static const u8 max9850_reg[MAX9850_CACHEREGNUM] = {
- 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+static const struct reg_default max9850_reg[] = {
+ { 2, 0x0c },
+ { 3, 0x00 },
+ { 4, 0x00 },
+ { 5, 0x00 },
+ { 6, 0x00 },
+ { 7, 0x00 },
+ { 8, 0x00 },
+ { 9, 0x00 },
+ { 10, 0x00 },
};
/* these registers are not used at the moment but provided for the sake of
* completeness */
-static int max9850_volatile_register(struct snd_soc_codec *codec,
- unsigned int reg)
+static bool max9850_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case MAX9850_STATUSA:
@@ -49,6 +58,15 @@ static int max9850_volatile_register(struct snd_soc_codec *codec,
}
}
+static const struct regmap_config max9850_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = MAX9850_DIGITAL_AUDIO,
+ .volatile_reg = max9850_volatile_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
static const unsigned int max9850_tlv[] = {
TLV_DB_RANGE_HEAD(4),
0x18, 0x1f, TLV_DB_SCALE_ITEM(-7450, 400, 0),
@@ -225,6 +243,7 @@ static int max9850_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
static int max9850_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
int ret;
switch (level) {
@@ -234,7 +253,7 @@ static int max9850_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = snd_soc_cache_sync(codec);
+ ret = regcache_sync(max9850->regmap);
if (ret) {
dev_err(codec->dev,
"Failed to sync cache: %d\n", ret);
@@ -295,7 +314,7 @@ static int max9850_probe(struct snd_soc_codec *codec)
{
int ret;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
@@ -316,10 +335,6 @@ static struct snd_soc_codec_driver soc_codec_dev_max9850 = {
.suspend = max9850_suspend,
.resume = max9850_resume,
.set_bias_level = max9850_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(max9850_reg),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = max9850_reg,
- .volatile_register = max9850_volatile_register,
.controls = max9850_controls,
.num_controls = ARRAY_SIZE(max9850_controls),
@@ -340,6 +355,10 @@ static int max9850_i2c_probe(struct i2c_client *i2c,
if (max9850 == NULL)
return -ENOMEM;
+ max9850->regmap = devm_regmap_init_i2c(i2c, &max9850_regmap);
+ if (IS_ERR(max9850->regmap))
+ return PTR_ERR(max9850->regmap);
+
i2c_set_clientdata(i2c, max9850);
ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index ea141e1d6f28..eedbf05b8e96 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -30,16 +30,10 @@
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/soc-dapm.h>
+#include <linux/regmap.h>
#include "mc13783.h"
-#define MC13783_AUDIO_RX0 36
-#define MC13783_AUDIO_RX1 37
-#define MC13783_AUDIO_TX 38
-#define MC13783_SSI_NETWORK 39
-#define MC13783_AUDIO_CODEC 40
-#define MC13783_AUDIO_DAC 41
-
#define AUDIO_RX0_ALSPEN (1 << 5)
#define AUDIO_RX0_ALSPSEL (1 << 7)
#define AUDIO_RX0_ADDCDC (1 << 21)
@@ -95,45 +89,12 @@
struct mc13783_priv {
struct mc13xxx *mc13xxx;
+ struct regmap *regmap;
enum mc13783_ssi_port adc_ssi_port;
enum mc13783_ssi_port dac_ssi_port;
};
-static unsigned int mc13783_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
- unsigned int value = 0;
-
- mc13xxx_lock(priv->mc13xxx);
-
- mc13xxx_reg_read(priv->mc13xxx, reg, &value);
-
- mc13xxx_unlock(priv->mc13xxx);
-
- return value;
-}
-
-static int mc13783_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- mc13xxx_lock(priv->mc13xxx);
-
- ret = mc13xxx_reg_write(priv->mc13xxx, reg, value);
-
- /* include errata fix for spi audio problems */
- if (reg == MC13783_AUDIO_CODEC || reg == MC13783_AUDIO_DAC)
- ret = mc13xxx_reg_write(priv->mc13xxx, reg, value);
-
- mc13xxx_unlock(priv->mc13xxx);
-
- return ret;
-}
-
/* Mapping between sample rates and register value */
static unsigned int mc13783_rates[] = {
8000, 11025, 12000, 16000,
@@ -587,8 +548,14 @@ static struct snd_kcontrol_new mc13783_control_list[] = {
static int mc13783_probe(struct snd_soc_codec *codec)
{
struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
+ int ret;
- mc13xxx_lock(priv->mc13xxx);
+ codec->control_data = dev_get_regmap(codec->dev->parent, NULL);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 24, SND_SOC_REGMAP);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
/* these are the reset values */
mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893);
@@ -612,8 +579,6 @@ static int mc13783_probe(struct snd_soc_codec *codec)
mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC,
0, AUDIO_SSI_SEL);
- mc13xxx_unlock(priv->mc13xxx);
-
return 0;
}
@@ -621,13 +586,9 @@ static int mc13783_remove(struct snd_soc_codec *codec)
{
struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
- mc13xxx_lock(priv->mc13xxx);
-
/* Make sure VAUDIOON is off */
mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_RX0, 0x3, 0);
- mc13xxx_unlock(priv->mc13xxx);
-
return 0;
}
@@ -717,8 +678,6 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = {
static struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
.probe = mc13783_probe,
.remove = mc13783_remove,
- .read = mc13783_read,
- .write = mc13783_write,
.controls = mc13783_control_list,
.num_controls = ARRAY_SIZE(mc13783_control_list),
.dapm_widgets = mc13783_dapm_widgets,
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index c26a8f814b18..641eeeb00c5c 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -21,6 +21,7 @@
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/acpi.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -926,7 +927,7 @@ static int rt5640_set_dmic2_event(struct snd_soc_dapm_widget *w,
return 0;
}
-void hp_amp_power_on(struct snd_soc_codec *codec)
+static void hp_amp_power_on(struct snd_soc_codec *codec)
{
struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
@@ -1609,7 +1610,8 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream,
rt5640->lrck[dai->id] = params_rate(params);
pre_div = get_clk_info(rt5640->sysclk, rt5640->lrck[dai->id]);
if (pre_div < 0) {
- dev_err(codec->dev, "Unsupported clock setting\n");
+ dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
+ rt5640->lrck[dai->id], dai->id);
return -EINVAL;
}
frame_size = snd_soc_params_to_frame_size(params);
@@ -2080,6 +2082,14 @@ static const struct i2c_device_id rt5640_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id);
+#ifdef CONFIG_ACPI
+static struct acpi_device_id rt5640_acpi_match[] = {
+ { "INT33CA", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match);
+#endif
+
static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np)
{
rt5640->pdata.in1_diff = of_property_read_bool(np,
@@ -2199,6 +2209,7 @@ static struct i2c_driver rt5640_i2c_driver = {
.driver = {
.name = "rt5640",
.owner = THIS_MODULE,
+ .acpi_match_table = ACPI_PTR(rt5640_acpi_match),
},
.probe = rt5640_i2c_probe,
.remove = rt5640_i2c_remove,
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index fd7c45b9ed5a..2f8161c1d5f0 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -27,6 +27,10 @@
#include "davinci-i2s.h"
#include "davinci-mcasp.h"
+struct snd_soc_card_drvdata_davinci {
+ unsigned sysclk;
+};
+
#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
static int evm_hw_params(struct snd_pcm_substream *substream,
@@ -35,27 +39,11 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_card *soc_card = codec->card;
int ret = 0;
- unsigned sysclk;
-
- /* ASP1 on DM355 EVM is clocked by an external oscillator */
- if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() ||
- machine_is_davinci_dm365_evm())
- sysclk = 27000000;
-
- /* ASP0 in DM6446 EVM is clocked by U55, as configured by
- * board-dm644x-evm.c using GPIOs from U18. There are six
- * options; here we "know" we use a 48 KHz sample rate.
- */
- else if (machine_is_davinci_evm())
- sysclk = 12288000;
-
- else if (machine_is_davinci_da830_evm() ||
- machine_is_davinci_da850_evm())
- sysclk = 24576000;
-
- else
- return -EINVAL;
+ unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
+ snd_soc_card_get_drvdata(soc_card))->sysclk;
/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT);
@@ -243,35 +231,65 @@ static struct snd_soc_dai_link da850_evm_dai = {
};
/* davinci dm6446 evm audio machine driver */
+/*
+ * ASP0 in DM6446 EVM is clocked by U55, as configured by
+ * board-dm644x-evm.c using GPIOs from U18. There are six
+ * options; here we "know" we use a 48 KHz sample rate.
+ */
+static struct snd_soc_card_drvdata_davinci dm6446_snd_soc_card_drvdata = {
+ .sysclk = 12288000,
+};
+
static struct snd_soc_card dm6446_snd_soc_card_evm = {
.name = "DaVinci DM6446 EVM",
.owner = THIS_MODULE,
.dai_link = &dm6446_evm_dai,
.num_links = 1,
+ .drvdata = &dm6446_snd_soc_card_drvdata,
};
/* davinci dm355 evm audio machine driver */
+/* ASP1 on DM355 EVM is clocked by an external oscillator */
+static struct snd_soc_card_drvdata_davinci dm355_snd_soc_card_drvdata = {
+ .sysclk = 27000000,
+};
+
static struct snd_soc_card dm355_snd_soc_card_evm = {
.name = "DaVinci DM355 EVM",
.owner = THIS_MODULE,
.dai_link = &dm355_evm_dai,
.num_links = 1,
+ .drvdata = &dm355_snd_soc_card_drvdata,
};
/* davinci dm365 evm audio machine driver */
+static struct snd_soc_card_drvdata_davinci dm365_snd_soc_card_drvdata = {
+ .sysclk = 27000000,
+};
+
static struct snd_soc_card dm365_snd_soc_card_evm = {
.name = "DaVinci DM365 EVM",
.owner = THIS_MODULE,
.dai_link = &dm365_evm_dai,
.num_links = 1,
+ .drvdata = &dm365_snd_soc_card_drvdata,
};
/* davinci dm6467 evm audio machine driver */
+static struct snd_soc_card_drvdata_davinci dm6467_snd_soc_card_drvdata = {
+ .sysclk = 27000000,
+};
+
static struct snd_soc_card dm6467_snd_soc_card_evm = {
.name = "DaVinci DM6467 EVM",
.owner = THIS_MODULE,
.dai_link = dm6467_evm_dai,
.num_links = ARRAY_SIZE(dm6467_evm_dai),
+ .drvdata = &dm6467_snd_soc_card_drvdata,
+};
+
+static struct snd_soc_card_drvdata_davinci da830_snd_soc_card_drvdata = {
+ .sysclk = 24576000,
};
static struct snd_soc_card da830_snd_soc_card = {
@@ -279,6 +297,11 @@ static struct snd_soc_card da830_snd_soc_card = {
.owner = THIS_MODULE,
.dai_link = &da830_evm_dai,
.num_links = 1,
+ .drvdata = &da830_snd_soc_card_drvdata,
+};
+
+static struct snd_soc_card_drvdata_davinci da850_snd_soc_card_drvdata = {
+ .sysclk = 24576000,
};
static struct snd_soc_card da850_snd_soc_card = {
@@ -286,6 +309,7 @@ static struct snd_soc_card da850_snd_soc_card = {
.owner = THIS_MODULE,
.dai_link = &da850_evm_dai,
.num_links = 1,
+ .drvdata = &da850_snd_soc_card_drvdata,
};
static struct platform_device *evm_snd_device;
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 3920c3e849ce..ff1f34766ee3 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -963,7 +963,7 @@ static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg)
return true;
default:
return false;
- };
+ }
}
static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg)
@@ -982,7 +982,7 @@ static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg)
return true;
default:
return false;
- };
+ }
}
static const struct regmap_config fsl_spdif_regmap_config = {
@@ -1172,23 +1172,16 @@ static int fsl_spdif_probe(struct platform_device *pdev)
/* Register with ASoC */
dev_set_drvdata(&pdev->dev, spdif_priv);
- ret = snd_soc_register_component(&pdev->dev, &fsl_spdif_component,
- &spdif_priv->cpu_dai_drv, 1);
+ ret = devm_snd_soc_register_component(&pdev->dev, &fsl_spdif_component,
+ &spdif_priv->cpu_dai_drv, 1);
if (ret) {
dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
return ret;
}
ret = imx_pcm_dma_init(pdev);
- if (ret) {
+ if (ret)
dev_err(&pdev->dev, "imx_pcm_dma_init failed: %d\n", ret);
- goto error_component;
- }
-
- return ret;
-
-error_component:
- snd_soc_unregister_component(&pdev->dev);
return ret;
}
@@ -1196,7 +1189,6 @@ error_component:
static int fsl_spdif_remove(struct platform_device *pdev)
{
imx_pcm_dma_exit(pdev);
- snd_soc_unregister_component(&pdev->dev);
return 0;
}
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index c6b743978d5e..35e277379b86 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -469,19 +469,12 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
* parameters, then the second stream may be
* constrained to the wrong sample rate or size.
*/
- if (!first_runtime->sample_bits) {
- dev_err(substream->pcm->card->dev,
- "set sample size in %s stream first\n",
- substream->stream ==
- SNDRV_PCM_STREAM_PLAYBACK
- ? "capture" : "playback");
- return -EAGAIN;
- }
-
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+ if (first_runtime->sample_bits) {
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
first_runtime->sample_bits,
first_runtime->sample_bits);
+ }
}
ssi_private->second_stream = substream;
@@ -748,7 +741,7 @@ static void fsl_ssi_ac97_init(void)
fsl_ssi_setup(fsl_ac97_data);
}
-void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
unsigned short val)
{
struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
@@ -770,7 +763,7 @@ void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
udelay(100);
}
-unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
+static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
unsigned short reg)
{
struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
@@ -936,7 +929,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
ssi_private->ssi_phys = res.start;
ssi_private->irq = irq_of_parse_and_map(np, 0);
- if (ssi_private->irq == NO_IRQ) {
+ if (!ssi_private->irq) {
dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
return -ENXIO;
}
@@ -1135,7 +1128,6 @@ static int fsl_ssi_remove(struct platform_device *pdev)
if (ssi_private->ssi_on_imx)
imx_pcm_dma_exit(pdev);
snd_soc_unregister_component(&pdev->dev);
- dev_set_drvdata(&pdev->dev, NULL);
device_remove_file(&pdev->dev, &ssi_private->dev_attr);
if (ssi_private->ssi_on_imx)
clk_disable_unprepare(ssi_private->clk);
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index 46c5b4fdfc52..6f4bdc89ae3c 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -62,7 +62,7 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
struct device_node *ssi_np, *codec_np;
struct platform_device *ssi_pdev;
struct i2c_client *codec_dev;
- struct imx_sgtl5000_data *data;
+ struct imx_sgtl5000_data *data = NULL;
int int_port, ext_port;
int ret;
@@ -128,7 +128,7 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
goto fail;
}
- data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
+ data->codec_clk = clk_get(&codec_dev->dev, NULL);
if (IS_ERR(data->codec_clk)) {
ret = PTR_ERR(data->codec_clk);
goto fail;
@@ -159,7 +159,7 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
data->card.dapm_widgets = imx_sgtl5000_dapm_widgets;
data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets);
- ret = snd_soc_register_card(&data->card);
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
goto fail;
@@ -172,6 +172,8 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
return 0;
fail:
+ if (data && !IS_ERR(data->codec_clk))
+ clk_put(data->codec_clk);
if (ssi_np)
of_node_put(ssi_np);
if (codec_np)
@@ -184,7 +186,7 @@ static int imx_sgtl5000_remove(struct platform_device *pdev)
{
struct imx_sgtl5000_data *data = platform_get_drvdata(pdev);
- snd_soc_unregister_card(&data->card);
+ clk_put(data->codec_clk);
return 0;
}
@@ -202,7 +204,6 @@ static struct platform_driver imx_sgtl5000_driver = {
.of_match_table = imx_sgtl5000_dt_ids,
},
.probe = imx_sgtl5000_probe,
- .remove = imx_sgtl5000_remove,
};
module_platform_driver(imx_sgtl5000_driver);
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c
index 816013b0ebba..8499d5292f08 100644
--- a/sound/soc/fsl/imx-spdif.c
+++ b/sound/soc/fsl/imx-spdif.c
@@ -87,7 +87,7 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
if (ret)
goto error_dir;
- ret = snd_soc_register_card(&data->card);
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret);
goto error_dir;
@@ -119,8 +119,6 @@ static int imx_spdif_audio_remove(struct platform_device *pdev)
if (data->txdev)
platform_device_unregister(data->txdev);
- snd_soc_unregister_card(&data->card);
-
return 0;
}
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index 722afe69169e..6c6066618f3b 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -266,7 +266,7 @@ static int imx_wm8962_probe(struct platform_device *pdev)
data->card.late_probe = imx_wm8962_late_probe;
data->card.set_bias_level = imx_wm8962_set_bias_level;
- ret = snd_soc_register_card(&data->card);
+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
goto clk_fail;
@@ -296,7 +296,6 @@ static int imx_wm8962_remove(struct platform_device *pdev)
if (!IS_ERR(data->codec_clk))
clk_disable_unprepare(data->codec_clk);
- snd_soc_unregister_card(&data->card);
return 0;
}
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index b238434f92b0..0c85c4e1a1ae 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -29,9 +29,7 @@
#define KIRKWOOD_FORMATS \
(SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S32_LE | \
- SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | \
- SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE)
+ SNDRV_PCM_FMTBIT_S32_LE)
static struct kirkwood_dma_data *kirkwood_priv(struct snd_pcm_substream *subs)
{
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index ee363845759e..d3d4c32434f7 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -400,7 +400,7 @@ static int snd_mfld_mc_probe(struct platform_device *pdev)
}
/* register the soc card */
snd_soc_card_mfld.dev = &pdev->dev;
- ret_val = snd_soc_register_card(&snd_soc_card_mfld);
+ ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_mfld);
if (ret_val) {
pr_debug("snd_soc_register_card failed %d\n", ret_val);
return ret_val;
@@ -410,20 +410,12 @@ static int snd_mfld_mc_probe(struct platform_device *pdev)
return 0;
}
-static int snd_mfld_mc_remove(struct platform_device *pdev)
-{
- pr_debug("snd_mfld_mc_remove called\n");
- snd_soc_unregister_card(&snd_soc_card_mfld);
- return 0;
-}
-
static struct platform_driver snd_mfld_mc_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "msic_audio",
},
.probe = snd_mfld_mc_probe,
- .remove = snd_mfld_mc_remove,
};
module_platform_driver(snd_mfld_mc_driver);
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index b56b8a0e8deb..14152f6f70dd 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -768,8 +768,8 @@ static int mxs_saif_probe(struct platform_device *pdev)
dev_warn(&pdev->dev, "failed to init clocks\n");
}
- ret = snd_soc_register_component(&pdev->dev, &mxs_saif_component,
- &mxs_saif_dai, 1);
+ ret = devm_snd_soc_register_component(&pdev->dev, &mxs_saif_component,
+ &mxs_saif_dai, 1);
if (ret) {
dev_err(&pdev->dev, "register DAI failed\n");
return ret;
@@ -778,21 +778,15 @@ static int mxs_saif_probe(struct platform_device *pdev)
ret = mxs_pcm_platform_register(&pdev->dev);
if (ret) {
dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
- goto failed_pdev_alloc;
+ return ret;
}
return 0;
-
-failed_pdev_alloc:
- snd_soc_unregister_component(&pdev->dev);
-
- return ret;
}
static int mxs_saif_remove(struct platform_device *pdev)
{
mxs_pcm_platform_unregister(&pdev->dev);
- snd_soc_unregister_component(&pdev->dev);
return 0;
}
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index 4bb273786ff3..61822cc53bd3 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -122,14 +122,12 @@ static struct snd_soc_card mxs_sgtl5000 = {
.num_links = ARRAY_SIZE(mxs_sgtl5000_dai),
};
-static int mxs_sgtl5000_probe_dt(struct platform_device *pdev)
+static int mxs_sgtl5000_probe(struct platform_device *pdev)
{
+ struct snd_soc_card *card = &mxs_sgtl5000;
+ int ret, i;
struct device_node *np = pdev->dev.of_node;
struct device_node *saif_np[2], *codec_np;
- int i;
-
- if (!np)
- return 1; /* no device tree */
saif_np[0] = of_parse_phandle(np, "saif-controllers", 0);
saif_np[1] = of_parse_phandle(np, "saif-controllers", 1);
@@ -152,18 +150,6 @@ static int mxs_sgtl5000_probe_dt(struct platform_device *pdev)
of_node_put(saif_np[0]);
of_node_put(saif_np[1]);
- return 0;
-}
-
-static int mxs_sgtl5000_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &mxs_sgtl5000;
- int ret;
-
- ret = mxs_sgtl5000_probe_dt(pdev);
- if (ret < 0)
- return ret;
-
/*
* Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w).
* The Sgtl5000 sysclk is derived from saif0 mclk and it's range
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 90d2a7cd2563..cd9ee167959d 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -490,14 +490,9 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
mcpdm->dev = &pdev->dev;
- return snd_soc_register_component(&pdev->dev, &omap_mcpdm_component,
- &omap_mcpdm_dai, 1);
-}
-
-static int asoc_mcpdm_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_component(&pdev->dev);
- return 0;
+ return devm_snd_soc_register_component(&pdev->dev,
+ &omap_mcpdm_component,
+ &omap_mcpdm_dai, 1);
}
static const struct of_device_id omap_mcpdm_of_match[] = {
@@ -514,7 +509,6 @@ static struct platform_driver asoc_mcpdm_driver = {
},
.probe = asoc_mcpdm_probe,
- .remove = asoc_mcpdm_remove,
};
module_platform_driver(asoc_mcpdm_driver);
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
index 2a9324f794d8..6a8d6b5f160d 100644
--- a/sound/soc/omap/omap-twl4030.c
+++ b/sound/soc/omap/omap-twl4030.c
@@ -338,9 +338,9 @@ static int omap_twl4030_probe(struct platform_device *pdev)
}
snd_soc_card_set_drvdata(card, priv);
- ret = snd_soc_register_card(card);
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ dev_err(&pdev->dev, "devm_snd_soc_register_card() failed: %d\n",
ret);
return ret;
}
@@ -357,7 +357,6 @@ static int omap_twl4030_remove(struct platform_device *pdev)
snd_soc_jack_free_gpios(&priv->hs_jack,
ARRAY_SIZE(hs_jack_gpios),
hs_jack_gpios);
- snd_soc_unregister_card(card);
return 0;
}
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
index 41752a5fe3b0..5bf5f1f7cac5 100644
--- a/sound/soc/pxa/mmp-sspa.c
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -455,8 +455,8 @@ static int asoc_mmp_sspa_probe(struct platform_device *pdev)
priv->dai_fmt = (unsigned int) -1;
platform_set_drvdata(pdev, priv);
- return snd_soc_register_component(&pdev->dev, &mmp_sspa_component,
- &mmp_sspa_dai, 1);
+ return devm_snd_soc_register_component(&pdev->dev, &mmp_sspa_component,
+ &mmp_sspa_dai, 1);
}
static int asoc_mmp_sspa_remove(struct platform_device *pdev)
@@ -466,7 +466,6 @@ static int asoc_mmp_sspa_remove(struct platform_device *pdev)
clk_disable(priv->audio_clk);
clk_put(priv->audio_clk);
clk_put(priv->sysclk);
- snd_soc_unregister_component(&pdev->dev);
return 0;
}
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
index 29e246803626..84f5d8b76679 100644
--- a/sound/soc/samsung/bells.c
+++ b/sound/soc/samsung/bells.c
@@ -356,6 +356,7 @@ static struct snd_soc_dapm_widget bells_widgets[] = {
static struct snd_soc_dapm_route bells_routes[] = {
{ "Sub CLK_SYS", NULL, "OPCLK" },
+ { "CLKIN", NULL, "OPCLK" },
{ "DMIC", NULL, "MICBIAS2" },
{ "IN2L", NULL, "DMIC" },
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index b302f3b7a587..32956df8f50c 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1060,7 +1060,7 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops;
i2s->i2s_dai_drv.suspend = i2s_suspend;
i2s->i2s_dai_drv.resume = i2s_resume;
- i2s->i2s_dai_drv.playback.channels_min = 2;
+ i2s->i2s_dai_drv.playback.channels_min = 1;
i2s->i2s_dai_drv.playback.channels_max = 2;
i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES;
i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS;
@@ -1143,9 +1143,9 @@ static int samsung_i2s_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Unable to get drvdata\n");
return -EFAULT;
}
- snd_soc_register_component(&sec_dai->pdev->dev,
- &samsung_i2s_component,
- &sec_dai->i2s_dai_drv, 1);
+ devm_snd_soc_register_component(&sec_dai->pdev->dev,
+ &samsung_i2s_component,
+ &sec_dai->i2s_dai_drv, 1);
samsung_asoc_dma_platform_register(&pdev->dev);
return 0;
}
@@ -1258,8 +1258,9 @@ static int samsung_i2s_probe(struct platform_device *pdev)
goto err;
}
- snd_soc_register_component(&pri_dai->pdev->dev, &samsung_i2s_component,
- &pri_dai->i2s_dai_drv, 1);
+ devm_snd_soc_register_component(&pri_dai->pdev->dev,
+ &samsung_i2s_component,
+ &pri_dai->i2s_dai_drv, 1);
pm_runtime_enable(&pdev->dev);
@@ -1294,7 +1295,6 @@ static int samsung_i2s_remove(struct platform_device *pdev)
i2s->sec_dai = NULL;
samsung_asoc_dma_platform_unregister(&pdev->dev);
- snd_soc_unregister_component(&pdev->dev);
return 0;
}
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
index 5fd7a05a9b9e..831972d24fb9 100644
--- a/sound/soc/samsung/smdk_wm8994.c
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -193,7 +193,7 @@ static int smdk_audio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, board);
- ret = snd_soc_register_card(card);
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret);
@@ -201,15 +201,6 @@ static int smdk_audio_probe(struct platform_device *pdev)
return ret;
}
-static int smdk_audio_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
-
- return 0;
-}
-
static struct platform_driver smdk_audio_driver = {
.driver = {
.name = "smdk-audio-wm8894",
@@ -217,7 +208,6 @@ static struct platform_driver smdk_audio_driver = {
.of_match_table = of_match_ptr(samsung_wm8994_of_match),
},
.probe = smdk_audio_probe,
- .remove = smdk_audio_remove,
};
module_platform_driver(smdk_audio_driver);
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index d80deb7ccf13..9430097979a5 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -8,7 +8,6 @@
* for more details.
*/
#include <linux/sh_clk.h>
-#include <mach/clock.h>
#include "rsnd.h"
#define CLKA 0
@@ -22,6 +21,7 @@ struct rsnd_adg {
int rate_of_441khz_div_6;
int rate_of_48khz_div_6;
+ u32 ckr;
};
#define for_each_rsnd_clk(pos, adg, i) \
@@ -116,6 +116,11 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
found_clock:
+ /* see rsnd_adg_ssi_clk_init() */
+ rsnd_mod_bset(mod, SSICKR, 0x00FF0000, adg->ckr);
+ rsnd_mod_write(mod, BRRA, 0x00000002); /* 1/6 */
+ rsnd_mod_write(mod, BRRB, 0x00000002); /* 1/6 */
+
/*
* This "mod" = "ssi" here.
* we can get "ssi id" from mod
@@ -182,9 +187,7 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
}
}
- rsnd_priv_bset(priv, SSICKR, 0x00FF0000, ckr);
- rsnd_priv_write(priv, BRRA, 0x00000002); /* 1/6 */
- rsnd_priv_write(priv, BRRB, 0x00000002); /* 1/6 */
+ adg->ckr = ckr;
}
int rsnd_adg_probe(struct platform_device *pdev,
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index a35706028514..fc83f0f2aead 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -106,51 +106,6 @@
(!(priv->info->func) ? -ENODEV : \
priv->info->func(param))
-
-/*
- * basic function
- */
-u32 rsnd_read(struct rsnd_priv *priv,
- struct rsnd_mod *mod, enum rsnd_reg reg)
-{
- void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
-
- BUG_ON(!base);
-
- return ioread32(base);
-}
-
-void rsnd_write(struct rsnd_priv *priv,
- struct rsnd_mod *mod,
- enum rsnd_reg reg, u32 data)
-{
- void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
- struct device *dev = rsnd_priv_to_dev(priv);
-
- BUG_ON(!base);
-
- dev_dbg(dev, "w %p : %08x\n", base, data);
-
- iowrite32(data, base);
-}
-
-void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
- enum rsnd_reg reg, u32 mask, u32 data)
-{
- void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
- struct device *dev = rsnd_priv_to_dev(priv);
- u32 val;
-
- BUG_ON(!base);
-
- val = ioread32(base);
- val &= ~mask;
- val |= data & mask;
- iowrite32(val, base);
-
- dev_dbg(dev, "s %p : %08x\n", base, val);
-}
-
/*
* rsnd_mod functions
*/
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index babb203b43b7..61212ee97c28 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -11,6 +11,11 @@
#include "rsnd.h"
struct rsnd_gen_ops {
+ int (*probe)(struct platform_device *pdev,
+ struct rcar_snd_info *info,
+ struct rsnd_priv *priv);
+ void (*remove)(struct platform_device *pdev,
+ struct rsnd_priv *priv);
int (*path_init)(struct rsnd_priv *priv,
struct rsnd_dai *rdai,
struct rsnd_dai_stream *io);
@@ -19,21 +24,97 @@ struct rsnd_gen_ops {
struct rsnd_dai_stream *io);
};
-struct rsnd_gen_reg_map {
- int index; /* -1 : not supported */
- u32 offset_id; /* offset of ssi0, ssi1, ssi2... */
- u32 offset_adr; /* offset of SSICR, SSISR, ... */
-};
-
struct rsnd_gen {
void __iomem *base[RSND_BASE_MAX];
- struct rsnd_gen_reg_map reg_map[RSND_REG_MAX];
struct rsnd_gen_ops *ops;
+
+ struct regmap *regmap;
+ struct regmap_field *regs[RSND_REG_MAX];
};
#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
+#define RSND_REG_SET(gen, id, reg_id, offset, _id_offset, _id_size) \
+ [id] = { \
+ .reg = (unsigned int)gen->base[reg_id] + offset, \
+ .lsb = 0, \
+ .msb = 31, \
+ .id_size = _id_size, \
+ .id_offset = _id_offset, \
+ }
+
+/*
+ * basic function
+ */
+static int rsnd_regmap_write32(void *context, const void *_data, size_t count)
+{
+ struct rsnd_priv *priv = context;
+ struct device *dev = rsnd_priv_to_dev(priv);
+ u32 *data = (u32 *)_data;
+ u32 val = data[1];
+ void __iomem *reg = (void *)data[0];
+
+ iowrite32(val, reg);
+
+ dev_dbg(dev, "w %p : %08x\n", reg, val);
+
+ return 0;
+}
+
+static int rsnd_regmap_read32(void *context,
+ const void *_data, size_t reg_size,
+ void *_val, size_t val_size)
+{
+ struct rsnd_priv *priv = context;
+ struct device *dev = rsnd_priv_to_dev(priv);
+ u32 *data = (u32 *)_data;
+ u32 *val = (u32 *)_val;
+ void __iomem *reg = (void *)data[0];
+
+ *val = ioread32(reg);
+
+ dev_dbg(dev, "r %p : %08x\n", reg, *val);
+
+ return 0;
+}
+
+static struct regmap_bus rsnd_regmap_bus = {
+ .write = rsnd_regmap_write32,
+ .read = rsnd_regmap_read32,
+ .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+ .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+u32 rsnd_read(struct rsnd_priv *priv,
+ struct rsnd_mod *mod, enum rsnd_reg reg)
+{
+ struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+ u32 val;
+
+ regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
+
+ return val;
+}
+
+void rsnd_write(struct rsnd_priv *priv,
+ struct rsnd_mod *mod,
+ enum rsnd_reg reg, u32 data)
+{
+ struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+ regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
+}
+
+void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
+ enum rsnd_reg reg, u32 mask, u32 data)
+{
+ struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+ regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
+ mask, data);
+}
+
/*
* Gen2
* will be filled in the future
@@ -98,44 +179,64 @@ static int rsnd_gen1_path_exit(struct rsnd_priv *priv,
return ret;
}
-static struct rsnd_gen_ops rsnd_gen1_ops = {
- .path_init = rsnd_gen1_path_init,
- .path_exit = rsnd_gen1_path_exit,
-};
+/* single address mapping */
+#define RSND_GEN1_S_REG(gen, reg, id, offset) \
+ RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 9)
-#define RSND_GEN1_REG_MAP(g, s, i, oi, oa) \
- do { \
- (g)->reg_map[RSND_REG_##i].index = RSND_GEN1_##s; \
- (g)->reg_map[RSND_REG_##i].offset_id = oi; \
- (g)->reg_map[RSND_REG_##i].offset_adr = oa; \
- } while (0)
+/* multi address mapping */
+#define RSND_GEN1_M_REG(gen, reg, id, offset, _id_offset) \
+ RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, _id_offset, 9)
-static void rsnd_gen1_reg_map_init(struct rsnd_gen *gen)
+static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
{
- RSND_GEN1_REG_MAP(gen, SRU, SRC_ROUTE_SEL, 0x0, 0x00);
- RSND_GEN1_REG_MAP(gen, SRU, SRC_TMG_SEL0, 0x0, 0x08);
- RSND_GEN1_REG_MAP(gen, SRU, SRC_TMG_SEL1, 0x0, 0x0c);
- RSND_GEN1_REG_MAP(gen, SRU, SRC_TMG_SEL2, 0x0, 0x10);
- RSND_GEN1_REG_MAP(gen, SRU, SRC_CTRL, 0x0, 0xc0);
- RSND_GEN1_REG_MAP(gen, SRU, SSI_MODE0, 0x0, 0xD0);
- RSND_GEN1_REG_MAP(gen, SRU, SSI_MODE1, 0x0, 0xD4);
- RSND_GEN1_REG_MAP(gen, SRU, BUSIF_MODE, 0x4, 0x20);
- RSND_GEN1_REG_MAP(gen, SRU, BUSIF_ADINR, 0x40, 0x214);
-
- RSND_GEN1_REG_MAP(gen, ADG, BRRA, 0x0, 0x00);
- RSND_GEN1_REG_MAP(gen, ADG, BRRB, 0x0, 0x04);
- RSND_GEN1_REG_MAP(gen, ADG, SSICKR, 0x0, 0x08);
- RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL0, 0x0, 0x0c);
- RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL1, 0x0, 0x10);
- RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL3, 0x0, 0x18);
- RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL4, 0x0, 0x1c);
- RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL5, 0x0, 0x20);
-
- RSND_GEN1_REG_MAP(gen, SSI, SSICR, 0x40, 0x00);
- RSND_GEN1_REG_MAP(gen, SSI, SSISR, 0x40, 0x04);
- RSND_GEN1_REG_MAP(gen, SSI, SSITDR, 0x40, 0x08);
- RSND_GEN1_REG_MAP(gen, SSI, SSIRDR, 0x40, 0x0c);
- RSND_GEN1_REG_MAP(gen, SSI, SSIWSR, 0x40, 0x20);
+ int i;
+ struct device *dev = rsnd_priv_to_dev(priv);
+ struct regmap_config regc;
+ struct reg_field regf[RSND_REG_MAX] = {
+ RSND_GEN1_S_REG(gen, SRU, SRC_ROUTE_SEL, 0x00),
+ RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL0, 0x08),
+ RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL1, 0x0c),
+ RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL2, 0x10),
+ RSND_GEN1_S_REG(gen, SRU, SRC_CTRL, 0xc0),
+ RSND_GEN1_S_REG(gen, SRU, SSI_MODE0, 0xD0),
+ RSND_GEN1_S_REG(gen, SRU, SSI_MODE1, 0xD4),
+ RSND_GEN1_M_REG(gen, SRU, BUSIF_MODE, 0x20, 0x4),
+ RSND_GEN1_M_REG(gen, SRU, BUSIF_ADINR, 0x214, 0x40),
+
+ RSND_GEN1_S_REG(gen, ADG, BRRA, 0x00),
+ RSND_GEN1_S_REG(gen, ADG, BRRB, 0x04),
+ RSND_GEN1_S_REG(gen, ADG, SSICKR, 0x08),
+ RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c),
+ RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10),
+ RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL3, 0x18),
+ RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL4, 0x1c),
+ RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL5, 0x20),
+
+ RSND_GEN1_M_REG(gen, SSI, SSICR, 0x00, 0x40),
+ RSND_GEN1_M_REG(gen, SSI, SSISR, 0x04, 0x40),
+ RSND_GEN1_M_REG(gen, SSI, SSITDR, 0x08, 0x40),
+ RSND_GEN1_M_REG(gen, SSI, SSIRDR, 0x0c, 0x40),
+ RSND_GEN1_M_REG(gen, SSI, SSIWSR, 0x20, 0x40),
+ };
+
+ memset(&regc, 0, sizeof(regc));
+ regc.reg_bits = 32;
+ regc.val_bits = 32;
+
+ gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, &regc);
+ if (IS_ERR(gen->regmap)) {
+ dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap));
+ return PTR_ERR(gen->regmap);
+ }
+
+ for (i = 0; i < RSND_REG_MAX; i++) {
+ gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]);
+ if (IS_ERR(gen->regs[i]))
+ return PTR_ERR(gen->regs[i]);
+
+ }
+
+ return 0;
}
static int rsnd_gen1_probe(struct platform_device *pdev,
@@ -147,6 +248,7 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
struct resource *sru_res;
struct resource *adg_res;
struct resource *ssi_res;
+ int ret;
/*
* map address
@@ -163,8 +265,9 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
IS_ERR(gen->base[RSND_GEN1_SSI]))
return -ENODEV;
- gen->ops = &rsnd_gen1_ops;
- rsnd_gen1_reg_map_init(gen);
+ ret = rsnd_gen1_regmap_init(priv, gen);
+ if (ret < 0)
+ return ret;
dev_dbg(dev, "Gen1 device probed\n");
dev_dbg(dev, "SRU : %08x => %p\n", sru_res->start,
@@ -183,6 +286,13 @@ static void rsnd_gen1_remove(struct platform_device *pdev,
{
}
+static struct rsnd_gen_ops rsnd_gen1_ops = {
+ .probe = rsnd_gen1_probe,
+ .remove = rsnd_gen1_remove,
+ .path_init = rsnd_gen1_path_init,
+ .path_exit = rsnd_gen1_path_exit,
+};
+
/*
* Gen
*/
@@ -204,46 +314,12 @@ int rsnd_gen_path_exit(struct rsnd_priv *priv,
return gen->ops->path_exit(priv, rdai, io);
}
-void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
- struct rsnd_mod *mod,
- enum rsnd_reg reg)
-{
- struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
- struct device *dev = rsnd_priv_to_dev(priv);
- int index;
- u32 offset_id, offset_adr;
-
- if (reg >= RSND_REG_MAX) {
- dev_err(dev, "rsnd_reg reg error\n");
- return NULL;
- }
-
- index = gen->reg_map[reg].index;
- offset_id = gen->reg_map[reg].offset_id;
- offset_adr = gen->reg_map[reg].offset_adr;
-
- if (index < 0) {
- dev_err(dev, "unsupported reg access %d\n", reg);
- return NULL;
- }
-
- if (offset_id && mod)
- offset_id *= rsnd_mod_id(mod);
-
- /*
- * index/offset were set on gen1/gen2
- */
-
- return gen->base[index] + offset_id + offset_adr;
-}
-
int rsnd_gen_probe(struct platform_device *pdev,
struct rcar_snd_info *info,
struct rsnd_priv *priv)
{
struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_gen *gen;
- int i;
gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
if (!gen) {
@@ -251,30 +327,23 @@ int rsnd_gen_probe(struct platform_device *pdev,
return -ENOMEM;
}
- priv->gen = gen;
-
- /*
- * see
- * rsnd_reg_get()
- * rsnd_gen_probe()
- */
- for (i = 0; i < RSND_REG_MAX; i++)
- gen->reg_map[i].index = -1;
-
- /*
- * init each module
- */
if (rsnd_is_gen1(priv))
- return rsnd_gen1_probe(pdev, info, priv);
+ gen->ops = &rsnd_gen1_ops;
- dev_err(dev, "unknown generation R-Car sound device\n");
+ if (!gen->ops) {
+ dev_err(dev, "unknown generation R-Car sound device\n");
+ return -ENODEV;
+ }
- return -ENODEV;
+ priv->gen = gen;
+
+ return gen->ops->probe(pdev, info, priv);
}
void rsnd_gen_remove(struct platform_device *pdev,
struct rsnd_priv *priv)
{
- if (rsnd_is_gen1(priv))
- rsnd_gen1_remove(pdev, priv);
+ struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+ gen->ops->remove(pdev, priv);
}
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 9cc6986a8cfb..3868aaf41cc4 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -78,10 +78,6 @@ struct rsnd_dai_stream;
#define rsnd_mod_bset(m, r, s, d) \
rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d)
-#define rsnd_priv_read(p, r) rsnd_read(p, NULL, RSND_REG_##r)
-#define rsnd_priv_write(p, r, d) rsnd_write(p, NULL, RSND_REG_##r, d)
-#define rsnd_priv_bset(p, r, s, d) rsnd_bset(p, NULL, RSND_REG_##r, s, d)
-
u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg);
void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
enum rsnd_reg reg, u32 data);
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index e72f55428f0b..1b6663f45b34 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -11,12 +11,9 @@
* option) any later version.
*/
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
#include <sound/soc.h>
-#include <linux/bitmap.h>
-#include <linux/rbtree.h>
#include <linux/export.h>
+#include <linux/slab.h>
#include <trace/events/asoc.h>
@@ -66,126 +63,42 @@ static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
return -1;
}
-static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
+int snd_soc_cache_init(struct snd_soc_codec *codec)
{
- int i;
- int ret;
- const struct snd_soc_codec_driver *codec_drv;
- unsigned int val;
+ const struct snd_soc_codec_driver *codec_drv = codec->driver;
+ size_t reg_size;
- codec_drv = codec->driver;
- for (i = 0; i < codec_drv->reg_cache_size; ++i) {
- ret = snd_soc_cache_read(codec, i, &val);
- if (ret)
- return ret;
- if (codec->reg_def_copy)
- if (snd_soc_get_cache_val(codec->reg_def_copy,
- i, codec_drv->reg_word_size) == val)
- continue;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
- WARN_ON(!snd_soc_codec_writable_register(codec, i));
-
- ret = snd_soc_write(codec, i, val);
- if (ret)
- return ret;
- dev_dbg(codec->dev, "ASoC: Synced register %#x, value = %#x\n",
- i, val);
- }
- return 0;
-}
-
-static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- snd_soc_set_cache_val(codec->reg_cache, reg, value,
- codec->driver->reg_word_size);
- return 0;
-}
-
-static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int *value)
-{
- *value = snd_soc_get_cache_val(codec->reg_cache, reg,
- codec->driver->reg_word_size);
- return 0;
-}
+ mutex_init(&codec->cache_rw_mutex);
-static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
-{
- if (!codec->reg_cache)
- return 0;
- kfree(codec->reg_cache);
- codec->reg_cache = NULL;
- return 0;
-}
+ dev_dbg(codec->dev, "ASoC: Initializing cache for %s codec\n",
+ codec->name);
-static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
-{
- if (codec->reg_def_copy)
- codec->reg_cache = kmemdup(codec->reg_def_copy,
- codec->reg_size, GFP_KERNEL);
+ if (codec_drv->reg_cache_default)
+ codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
+ reg_size, GFP_KERNEL);
else
- codec->reg_cache = kzalloc(codec->reg_size, GFP_KERNEL);
+ codec->reg_cache = kzalloc(reg_size, GFP_KERNEL);
if (!codec->reg_cache)
return -ENOMEM;
return 0;
}
-/* an array of all supported compression types */
-static const struct snd_soc_cache_ops cache_types[] = {
- /* Flat *must* be the first entry for fallback */
- {
- .id = SND_SOC_FLAT_COMPRESSION,
- .name = "flat",
- .init = snd_soc_flat_cache_init,
- .exit = snd_soc_flat_cache_exit,
- .read = snd_soc_flat_cache_read,
- .write = snd_soc_flat_cache_write,
- .sync = snd_soc_flat_cache_sync
- },
-};
-
-int snd_soc_cache_init(struct snd_soc_codec *codec)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
- if (cache_types[i].id == codec->compress_type)
- break;
-
- /* Fall back to flat compression */
- if (i == ARRAY_SIZE(cache_types)) {
- dev_warn(codec->dev, "ASoC: Could not match compress type: %d\n",
- codec->compress_type);
- i = 0;
- }
-
- mutex_init(&codec->cache_rw_mutex);
- codec->cache_ops = &cache_types[i];
-
- if (codec->cache_ops->init) {
- if (codec->cache_ops->name)
- dev_dbg(codec->dev, "ASoC: Initializing %s cache for %s codec\n",
- codec->cache_ops->name, codec->name);
- return codec->cache_ops->init(codec);
- }
- return -ENOSYS;
-}
-
/*
* NOTE: keep in mind that this function might be called
* multiple times.
*/
int snd_soc_cache_exit(struct snd_soc_codec *codec)
{
- if (codec->cache_ops && codec->cache_ops->exit) {
- if (codec->cache_ops->name)
- dev_dbg(codec->dev, "ASoC: Destroying %s cache for %s codec\n",
- codec->cache_ops->name, codec->name);
- return codec->cache_ops->exit(codec);
- }
- return -ENOSYS;
+ dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n",
+ codec->name);
+ if (!codec->reg_cache)
+ return 0;
+ kfree(codec->reg_cache);
+ codec->reg_cache = NULL;
+ return 0;
}
/**
@@ -198,18 +111,15 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec)
int snd_soc_cache_read(struct snd_soc_codec *codec,
unsigned int reg, unsigned int *value)
{
- int ret;
+ if (!value)
+ return -EINVAL;
mutex_lock(&codec->cache_rw_mutex);
-
- if (value && codec->cache_ops && codec->cache_ops->read) {
- ret = codec->cache_ops->read(codec, reg, value);
- mutex_unlock(&codec->cache_rw_mutex);
- return ret;
- }
-
+ *value = snd_soc_get_cache_val(codec->reg_cache, reg,
+ codec->driver->reg_word_size);
mutex_unlock(&codec->cache_rw_mutex);
- return -ENOSYS;
+
+ return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_cache_read);
@@ -223,20 +133,42 @@ EXPORT_SYMBOL_GPL(snd_soc_cache_read);
int snd_soc_cache_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int value)
{
+ mutex_lock(&codec->cache_rw_mutex);
+ snd_soc_set_cache_val(codec->reg_cache, reg, value,
+ codec->driver->reg_word_size);
+ mutex_unlock(&codec->cache_rw_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_cache_write);
+
+static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
+{
+ int i;
int ret;
+ const struct snd_soc_codec_driver *codec_drv;
+ unsigned int val;
- mutex_lock(&codec->cache_rw_mutex);
+ codec_drv = codec->driver;
+ for (i = 0; i < codec_drv->reg_cache_size; ++i) {
+ ret = snd_soc_cache_read(codec, i, &val);
+ if (ret)
+ return ret;
+ if (codec_drv->reg_cache_default)
+ if (snd_soc_get_cache_val(codec_drv->reg_cache_default,
+ i, codec_drv->reg_word_size) == val)
+ continue;
- if (codec->cache_ops && codec->cache_ops->write) {
- ret = codec->cache_ops->write(codec, reg, value);
- mutex_unlock(&codec->cache_rw_mutex);
- return ret;
- }
+ WARN_ON(!snd_soc_codec_writable_register(codec, i));
- mutex_unlock(&codec->cache_rw_mutex);
- return -ENOSYS;
+ ret = snd_soc_write(codec, i, val);
+ if (ret)
+ return ret;
+ dev_dbg(codec->dev, "ASoC: Synced register %#x, value = %#x\n",
+ i, val);
+ }
+ return 0;
}
-EXPORT_SYMBOL_GPL(snd_soc_cache_write);
/**
* snd_soc_cache_sync: Sync the register cache with the hardware.
@@ -249,92 +181,19 @@ EXPORT_SYMBOL_GPL(snd_soc_cache_write);
*/
int snd_soc_cache_sync(struct snd_soc_codec *codec)
{
+ const char *name = "flat";
int ret;
- const char *name;
- if (!codec->cache_sync) {
+ if (!codec->cache_sync)
return 0;
- }
-
- if (!codec->cache_ops || !codec->cache_ops->sync)
- return -ENOSYS;
- if (codec->cache_ops->name)
- name = codec->cache_ops->name;
- else
- name = "unknown";
-
- if (codec->cache_ops->name)
- dev_dbg(codec->dev, "ASoC: Syncing %s cache for %s codec\n",
- codec->cache_ops->name, codec->name);
+ dev_dbg(codec->dev, "ASoC: Syncing cache for %s codec\n",
+ codec->name);
trace_snd_soc_cache_sync(codec, name, "start");
- ret = codec->cache_ops->sync(codec);
+ ret = snd_soc_flat_cache_sync(codec);
if (!ret)
codec->cache_sync = 0;
trace_snd_soc_cache_sync(codec, name, "end");
return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
-
-static int snd_soc_get_reg_access_index(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- const struct snd_soc_codec_driver *codec_drv;
- unsigned int min, max, index;
-
- codec_drv = codec->driver;
- min = 0;
- max = codec_drv->reg_access_size - 1;
- do {
- index = (min + max) / 2;
- if (codec_drv->reg_access_default[index].reg == reg)
- return index;
- if (codec_drv->reg_access_default[index].reg < reg)
- min = index + 1;
- else
- max = index;
- } while (min <= max);
- return -1;
-}
-
-int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- int index;
-
- if (reg >= codec->driver->reg_cache_size)
- return 1;
- index = snd_soc_get_reg_access_index(codec, reg);
- if (index < 0)
- return 0;
- return codec->driver->reg_access_default[index].vol;
-}
-EXPORT_SYMBOL_GPL(snd_soc_default_volatile_register);
-
-int snd_soc_default_readable_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- int index;
-
- if (reg >= codec->driver->reg_cache_size)
- return 1;
- index = snd_soc_get_reg_access_index(codec, reg);
- if (index < 0)
- return 0;
- return codec->driver->reg_access_default[index].read;
-}
-EXPORT_SYMBOL_GPL(snd_soc_default_readable_register);
-
-int snd_soc_default_writable_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- int index;
-
- if (reg >= codec->driver->reg_cache_size)
- return 1;
- index = snd_soc_get_reg_access_index(codec, reg);
- if (index < 0)
- return 0;
- return codec->driver->reg_access_default[index].write;
-}
-EXPORT_SYMBOL_GPL(snd_soc_default_writable_register);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4d0561312f3b..4280c70ba0ee 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1380,7 +1380,6 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
return -ENODEV;
list_add(&cpu_dai->dapm.list, &card->dapm_list);
- snd_soc_dapm_new_dai_widgets(&cpu_dai->dapm, cpu_dai);
}
if (cpu_dai->driver->probe) {
@@ -1590,17 +1589,13 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
soc_remove_codec(codec);
}
-static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
- enum snd_soc_compress_type compress_type)
+static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
{
int ret;
if (codec->cache_init)
return 0;
- /* override the compress_type if necessary */
- if (compress_type && codec->compress_type != compress_type)
- codec->compress_type = compress_type;
ret = snd_soc_cache_init(codec);
if (ret < 0) {
dev_err(codec->dev,
@@ -1615,8 +1610,6 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
static int snd_soc_instantiate_card(struct snd_soc_card *card)
{
struct snd_soc_codec *codec;
- struct snd_soc_codec_conf *codec_conf;
- enum snd_soc_compress_type compress_type;
struct snd_soc_dai_link *dai_link;
int ret, i, order, dai_fmt;
@@ -1640,19 +1633,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
list_for_each_entry(codec, &codec_list, list) {
if (codec->cache_init)
continue;
- /* by default we don't override the compress_type */
- compress_type = 0;
- /* check to see if we need to override the compress_type */
- for (i = 0; i < card->num_configs; ++i) {
- codec_conf = &card->codec_conf[i];
- if (!strcmp(codec->name, codec_conf->dev_name)) {
- compress_type = codec_conf->compress_type;
- if (compress_type && compress_type
- != codec->compress_type)
- break;
- }
- }
- ret = snd_soc_init_codec_cache(codec, compress_type);
+ ret = snd_soc_init_codec_cache(codec);
if (ret < 0)
goto base_error;
}
@@ -2298,13 +2279,6 @@ unsigned int snd_soc_write(struct snd_soc_codec *codec,
}
EXPORT_SYMBOL_GPL(snd_soc_write);
-unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec,
- unsigned int reg, const void *data, size_t len)
-{
- return codec->bulk_write_raw(codec, reg, data, len);
-}
-EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw);
-
/**
* snd_soc_update_bits - update codec register bits
* @codec: audio codec
@@ -3577,6 +3551,22 @@ int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll);
/**
+ * snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio.
+ * @dai: DAI
+ * @ratio Ratio of BCLK to Sample rate.
+ *
+ * Configures the DAI for a preset BCLK to sample rate ratio.
+ */
+int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+ if (dai->driver && dai->driver->ops->set_bclk_ratio)
+ return dai->driver->ops->set_bclk_ratio(dai, ratio);
+ else
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_ratio);
+
+/**
* snd_soc_dai_set_fmt - configure DAI hardware audio format.
* @dai: DAI
* @fmt: SND_SOC_DAIFMT_ format value.
@@ -4021,6 +4011,112 @@ static void snd_soc_unregister_dais(struct device *dev, size_t count)
}
/**
+ * snd_soc_register_component - Register a component with the ASoC core
+ *
+ */
+static int
+__snd_soc_register_component(struct device *dev,
+ struct snd_soc_component *cmpnt,
+ const struct snd_soc_component_driver *cmpnt_drv,
+ struct snd_soc_dai_driver *dai_drv,
+ int num_dai, bool allow_single_dai)
+{
+ int ret;
+
+ dev_dbg(dev, "component register %s\n", dev_name(dev));
+
+ if (!cmpnt) {
+ dev_err(dev, "ASoC: Failed to connecting component\n");
+ return -ENOMEM;
+ }
+
+ cmpnt->name = fmt_single_name(dev, &cmpnt->id);
+ if (!cmpnt->name) {
+ dev_err(dev, "ASoC: Failed to simplifying name\n");
+ return -ENOMEM;
+ }
+
+ cmpnt->dev = dev;
+ cmpnt->driver = cmpnt_drv;
+ cmpnt->num_dai = num_dai;
+
+ /*
+ * snd_soc_register_dai() uses fmt_single_name(), and
+ * snd_soc_register_dais() uses fmt_multiple_name()
+ * for dai->name which is used for name based matching
+ *
+ * this function is used from cpu/codec.
+ * allow_single_dai flag can ignore "codec" driver reworking
+ * since it had been used snd_soc_register_dais(),
+ */
+ if ((1 == num_dai) && allow_single_dai)
+ ret = snd_soc_register_dai(dev, dai_drv);
+ else
+ ret = snd_soc_register_dais(dev, dai_drv, num_dai);
+ if (ret < 0) {
+ dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
+ goto error_component_name;
+ }
+
+ mutex_lock(&client_mutex);
+ list_add(&cmpnt->list, &component_list);
+ mutex_unlock(&client_mutex);
+
+ dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name);
+
+ return ret;
+
+error_component_name:
+ kfree(cmpnt->name);
+
+ return ret;
+}
+
+int snd_soc_register_component(struct device *dev,
+ const struct snd_soc_component_driver *cmpnt_drv,
+ struct snd_soc_dai_driver *dai_drv,
+ int num_dai)
+{
+ struct snd_soc_component *cmpnt;
+
+ cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL);
+ if (!cmpnt) {
+ dev_err(dev, "ASoC: Failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ return __snd_soc_register_component(dev, cmpnt, cmpnt_drv,
+ dai_drv, num_dai, true);
+}
+EXPORT_SYMBOL_GPL(snd_soc_register_component);
+
+/**
+ * snd_soc_unregister_component - Unregister a component from the ASoC core
+ *
+ */
+void snd_soc_unregister_component(struct device *dev)
+{
+ struct snd_soc_component *cmpnt;
+
+ list_for_each_entry(cmpnt, &component_list, list) {
+ if (dev == cmpnt->dev)
+ goto found;
+ }
+ return;
+
+found:
+ snd_soc_unregister_dais(dev, cmpnt->num_dai);
+
+ mutex_lock(&client_mutex);
+ list_del(&cmpnt->list);
+ mutex_unlock(&client_mutex);
+
+ dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name);
+ kfree(cmpnt->name);
+}
+EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
+
+/**
* snd_soc_add_platform - Add a platform to the ASoC core
* @dev: The parent device for the platform
* @platform: The platform to add
@@ -4166,7 +4262,6 @@ int snd_soc_register_codec(struct device *dev,
struct snd_soc_dai_driver *dai_drv,
int num_dai)
{
- size_t reg_size;
struct snd_soc_codec *codec;
int ret, i;
@@ -4183,11 +4278,6 @@ int snd_soc_register_codec(struct device *dev,
goto fail_codec;
}
- if (codec_drv->compress_type)
- codec->compress_type = codec_drv->compress_type;
- else
- codec->compress_type = SND_SOC_FLAT_COMPRESSION;
-
codec->write = codec_drv->write;
codec->read = codec_drv->read;
codec->volatile_register = codec_drv->volatile_register;
@@ -4204,35 +4294,6 @@ int snd_soc_register_codec(struct device *dev,
codec->num_dai = num_dai;
mutex_init(&codec->mutex);
- /* allocate CODEC register cache */
- if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
- reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
- codec->reg_size = reg_size;
- /* it is necessary to make a copy of the default register cache
- * because in the case of using a compression type that requires
- * the default register cache to be marked as the
- * kernel might have freed the array by the time we initialize
- * the cache.
- */
- if (codec_drv->reg_cache_default) {
- codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default,
- reg_size, GFP_KERNEL);
- if (!codec->reg_def_copy) {
- ret = -ENOMEM;
- goto fail_codec_name;
- }
- }
- }
-
- if (codec_drv->reg_access_size && codec_drv->reg_access_default) {
- if (!codec->volatile_register)
- codec->volatile_register = snd_soc_default_volatile_register;
- if (!codec->readable_register)
- codec->readable_register = snd_soc_default_readable_register;
- if (!codec->writable_register)
- codec->writable_register = snd_soc_default_writable_register;
- }
-
for (i = 0; i < num_dai; i++) {
fixup_codec_formats(&dai_drv[i].playback);
fixup_codec_formats(&dai_drv[i].capture);
@@ -4242,10 +4303,12 @@ int snd_soc_register_codec(struct device *dev,
list_add(&codec->list, &codec_list);
mutex_unlock(&client_mutex);
- /* register any DAIs */
- ret = snd_soc_register_dais(dev, dai_drv, num_dai);
+ /* register component */
+ ret = __snd_soc_register_component(dev, &codec->component,
+ &codec_drv->component_driver,
+ dai_drv, num_dai, false);
if (ret < 0) {
- dev_err(codec->dev, "ASoC: Failed to regster DAIs: %d\n", ret);
+ dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret);
goto fail_codec_name;
}
@@ -4280,7 +4343,7 @@ void snd_soc_unregister_codec(struct device *dev)
return;
found:
- snd_soc_unregister_dais(dev, codec->num_dai);
+ snd_soc_unregister_component(dev);
mutex_lock(&client_mutex);
list_del(&codec->list);
@@ -4289,98 +4352,11 @@ found:
dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n", codec->name);
snd_soc_cache_exit(codec);
- kfree(codec->reg_def_copy);
kfree(codec->name);
kfree(codec);
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
-
-/**
- * snd_soc_register_component - Register a component with the ASoC core
- *
- */
-int snd_soc_register_component(struct device *dev,
- const struct snd_soc_component_driver *cmpnt_drv,
- struct snd_soc_dai_driver *dai_drv,
- int num_dai)
-{
- struct snd_soc_component *cmpnt;
- int ret;
-
- dev_dbg(dev, "component register %s\n", dev_name(dev));
-
- cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL);
- if (!cmpnt) {
- dev_err(dev, "ASoC: Failed to allocate memory\n");
- return -ENOMEM;
- }
-
- cmpnt->name = fmt_single_name(dev, &cmpnt->id);
- if (!cmpnt->name) {
- dev_err(dev, "ASoC: Failed to simplifying name\n");
- return -ENOMEM;
- }
-
- cmpnt->dev = dev;
- cmpnt->driver = cmpnt_drv;
- cmpnt->num_dai = num_dai;
-
- /*
- * snd_soc_register_dai() uses fmt_single_name(), and
- * snd_soc_register_dais() uses fmt_multiple_name()
- * for dai->name which is used for name based matching
- */
- if (1 == num_dai)
- ret = snd_soc_register_dai(dev, dai_drv);
- else
- ret = snd_soc_register_dais(dev, dai_drv, num_dai);
- if (ret < 0) {
- dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
- goto error_component_name;
- }
-
- mutex_lock(&client_mutex);
- list_add(&cmpnt->list, &component_list);
- mutex_unlock(&client_mutex);
-
- dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name);
-
- return ret;
-
-error_component_name:
- kfree(cmpnt->name);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_register_component);
-
-/**
- * snd_soc_unregister_component - Unregister a component from the ASoC core
- *
- */
-void snd_soc_unregister_component(struct device *dev)
-{
- struct snd_soc_component *cmpnt;
-
- list_for_each_entry(cmpnt, &component_list, list) {
- if (dev == cmpnt->dev)
- goto found;
- }
- return;
-
-found:
- snd_soc_unregister_dais(dev, cmpnt->num_dai);
-
- mutex_lock(&client_mutex);
- list_del(&cmpnt->list);
- mutex_unlock(&client_mutex);
-
- dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name);
- kfree(cmpnt->name);
-}
-EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
-
/* Retrieve a card's name from device tree */
int snd_soc_of_parse_card_name(struct snd_soc_card *card,
const char *propname)
@@ -4568,6 +4544,41 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
}
EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
+int snd_soc_of_get_dai_name(struct device_node *of_node,
+ const char **dai_name)
+{
+ struct snd_soc_component *pos;
+ struct of_phandle_args args;
+ int ret;
+
+ ret = of_parse_phandle_with_args(of_node, "sound-dai",
+ "#sound-dai-cells", 0, &args);
+ if (ret)
+ return ret;
+
+ ret = -EPROBE_DEFER;
+
+ mutex_lock(&client_mutex);
+ list_for_each_entry(pos, &component_list, list) {
+ if (pos->dev->of_node != args.np)
+ continue;
+
+ if (!pos->driver->of_xlate_dai_name) {
+ ret = -ENOSYS;
+ break;
+ }
+
+ ret = pos->driver->of_xlate_dai_name(pos, &args, dai_name);
+ break;
+ }
+ mutex_unlock(&client_mutex);
+
+ of_node_put(args.np);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);
+
static int __init snd_soc_init(void)
{
#ifdef CONFIG_DEBUG_FS
diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c
new file mode 100644
index 000000000000..b1d732255c02
--- /dev/null
+++ b/sound/soc/soc-devres.c
@@ -0,0 +1,86 @@
+/*
+ * soc-devres.c -- ALSA SoC Audio Layer devres functions
+ *
+ * Copyright (C) 2013 Linaro Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <sound/soc.h>
+
+static void devm_component_release(struct device *dev, void *res)
+{
+ snd_soc_unregister_component(*(struct device **)res);
+}
+
+/**
+ * devm_snd_soc_register_component - resource managed component registration
+ * @dev: Device used to manage component
+ * @cmpnt_drv: Component driver
+ * @dai_drv: DAI driver
+ * @num_dai: Number of DAIs to register
+ *
+ * Register a component with automatic unregistration when the device is
+ * unregistered.
+ */
+int devm_snd_soc_register_component(struct device *dev,
+ const struct snd_soc_component_driver *cmpnt_drv,
+ struct snd_soc_dai_driver *dai_drv, int num_dai)
+{
+ struct device **ptr;
+ int ret;
+
+ ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai);
+ if (ret == 0) {
+ *ptr = dev;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(devm_snd_soc_register_component);
+
+static void devm_card_release(struct device *dev, void *res)
+{
+ snd_soc_unregister_card(*(struct snd_soc_card **)res);
+}
+
+/**
+ * devm_snd_soc_register_card - resource managed card registration
+ * @dev: Device used to manage card
+ * @card: Card to register
+ *
+ * Register a card with automatic unregistration when the device is
+ * unregistered.
+ */
+int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card)
+{
+ struct device **ptr;
+ int ret;
+
+ ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ ret = snd_soc_register_card(card);
+ if (ret == 0) {
+ *ptr = dev;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(devm_snd_soc_register_card);
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 122c0c18b9dd..4f11d23f2062 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -65,31 +65,6 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
return val;
}
-/* Primitive bulk write support for soc-cache. The data pointed to by
- * `data' needs to already be in the form the hardware expects. Any
- * data written through this function will not go through the cache as
- * it only handles writing to volatile or out of bounds registers.
- *
- * This is currently only supported for devices using the regmap API
- * wrappers.
- */
-static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec,
- unsigned int reg,
- const void *data, size_t len)
-{
- /* To ensure that we don't get out of sync with the cache, check
- * whether the base register is volatile or if we've directly asked
- * to bypass the cache. Out of bounds registers are considered
- * volatile.
- */
- if (!codec->cache_bypass
- && !snd_soc_codec_volatile_register(codec, reg)
- && reg < codec->driver->reg_cache_size)
- return -EINVAL;
-
- return regmap_raw_write(codec->control_data, reg, data, len);
-}
-
/**
* snd_soc_codec_set_cache_io: Set up standard I/O functions.
*
@@ -119,7 +94,6 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
memset(&config, 0, sizeof(config));
codec->write = hw_write;
codec->read = hw_read;
- codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
config.reg_bits = addr_bits;
config.val_bits = data_bits;
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 29b211e9c060..5e633659c1b3 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -75,7 +75,11 @@ static const struct snd_pcm_hardware dummy_dma_hardware = {
static int dummy_dma_open(struct snd_pcm_substream *substream)
{
- snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware);
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+
+ /* BE's dont need dummy params */
+ if (!rtd->dai_link->no_pcm)
+ snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware);
return 0;
}