aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/core/pcm_lib.c1
-rw-r--r--sound/pci/hda/hda_codec.c34
-rw-r--r--sound/pci/hda/hda_generic.c8
-rw-r--r--sound/pci/hda/hda_generic.h1
-rw-r--r--sound/pci/hda/hda_intel.c2
-rw-r--r--sound/pci/hda/patch_analog.c31
-rw-r--r--sound/pci/hda/patch_ca0132.c68
-rw-r--r--sound/pci/hda/patch_conexant.c3
-rw-r--r--sound/pci/hda/patch_realtek.c73
-rw-r--r--sound/pci/hda/patch_sigmatel.c60
-rw-r--r--sound/pci/hda/thinkpad_helper.c1
-rw-r--r--sound/soc/atmel/Kconfig2
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c13
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c20
-rw-r--r--sound/soc/blackfin/Kconfig17
-rw-r--r--sound/soc/cirrus/Kconfig4
-rw-r--r--sound/soc/codecs/88pm860x-codec.c119
-rw-r--r--sound/soc/codecs/Kconfig167
-rw-r--r--sound/soc/codecs/Makefile24
-rw-r--r--sound/soc/codecs/ad1836.c4
-rw-r--r--sound/soc/codecs/ad193x-i2c.c54
-rw-r--r--sound/soc/codecs/ad193x-spi.c48
-rw-r--r--sound/soc/codecs/ad193x.c144
-rw-r--r--sound/soc/codecs/ad193x.h7
-rw-r--r--sound/soc/codecs/ad1980.c4
-rw-r--r--sound/soc/codecs/adau1373.c32
-rw-r--r--sound/soc/codecs/adau1977-i2c.c59
-rw-r--r--sound/soc/codecs/adau1977-spi.c76
-rw-r--r--sound/soc/codecs/adau1977.c1018
-rw-r--r--sound/soc/codecs/adau1977.h37
-rw-r--r--sound/soc/codecs/adav801.c53
-rw-r--r--sound/soc/codecs/adav803.c50
-rw-r--r--sound/soc/codecs/adav80x.c152
-rw-r--r--sound/soc/codecs/adav80x.h7
-rw-r--r--sound/soc/codecs/ak4104.c2
-rw-r--r--sound/soc/codecs/ak4641.c16
-rw-r--r--sound/soc/codecs/ak4671.c240
-rw-r--r--sound/soc/codecs/ak4671.h2
-rw-r--r--sound/soc/codecs/alc5623.c117
-rw-r--r--sound/soc/codecs/alc5632.c40
-rw-r--r--sound/soc/codecs/arizona.c325
-rw-r--r--sound/soc/codecs/cs4271.c63
-rw-r--r--sound/soc/codecs/cs42l51.c71
-rw-r--r--sound/soc/codecs/cs42l52.c92
-rw-r--r--sound/soc/codecs/cs42l73.c55
-rw-r--r--sound/soc/codecs/da7210.c20
-rw-r--r--sound/soc/codecs/da7213.c151
-rw-r--r--sound/soc/codecs/da732x.c179
-rw-r--r--sound/soc/codecs/da732x.h3
-rw-r--r--sound/soc/codecs/da9055.c103
-rw-r--r--sound/soc/codecs/isabelle.c52
-rw-r--r--sound/soc/codecs/lm49453.c16
-rw-r--r--sound/soc/codecs/max98088.c2
-rw-r--r--sound/soc/codecs/max98090.c193
-rw-r--r--sound/soc/codecs/max98095.c4
-rw-r--r--sound/soc/codecs/mc13783.c20
-rw-r--r--sound/soc/codecs/ml26124.c12
-rw-r--r--sound/soc/codecs/pcm1681.c15
-rw-r--r--sound/soc/codecs/pcm1792a.c33
-rw-r--r--sound/soc/codecs/pcm512x-i2c.c71
-rw-r--r--sound/soc/codecs/pcm512x-spi.c69
-rw-r--r--sound/soc/codecs/pcm512x.c589
-rw-r--r--sound/soc/codecs/pcm512x.h171
-rw-r--r--sound/soc/codecs/rt5631.c75
-rw-r--r--sound/soc/codecs/rt5640.c76
-rw-r--r--sound/soc/codecs/si476x.c2
-rw-r--r--sound/soc/codecs/ssm2518.c14
-rw-r--r--sound/soc/codecs/sta32x.c76
-rw-r--r--sound/soc/codecs/sta529.c2
-rw-r--r--sound/soc/codecs/tlv320aic23-i2c.c59
-rw-r--r--sound/soc/codecs/tlv320aic23-spi.c57
-rw-r--r--sound/soc/codecs/tlv320aic23.c69
-rw-r--r--sound/soc/codecs/tlv320aic23.h6
-rw-r--r--sound/soc/codecs/tlv320dac33.c2
-rw-r--r--sound/soc/codecs/twl4030.c17
-rw-r--r--sound/soc/codecs/uda1380.c2
-rw-r--r--sound/soc/codecs/wl1273.c2
-rw-r--r--sound/soc/codecs/wm5100.c12
-rw-r--r--sound/soc/codecs/wm5102.c28
-rw-r--r--sound/soc/codecs/wm5110.c19
-rw-r--r--sound/soc/codecs/wm8400.c34
-rw-r--r--sound/soc/codecs/wm8711.c2
-rw-r--r--sound/soc/codecs/wm8753.c4
-rw-r--r--sound/soc/codecs/wm8770.c4
-rw-r--r--sound/soc/codecs/wm8804.c2
-rw-r--r--sound/soc/codecs/wm8900.c44
-rw-r--r--sound/soc/codecs/wm8904.c4
-rw-r--r--sound/soc/codecs/wm8958-dsp2.c10
-rw-r--r--sound/soc/codecs/wm8962.c13
-rw-r--r--sound/soc/codecs/wm8978.c30
-rw-r--r--sound/soc/codecs/wm8983.c39
-rw-r--r--sound/soc/codecs/wm8985.c39
-rw-r--r--sound/soc/codecs/wm8993.c1
-rw-r--r--sound/soc/codecs/wm8994.c183
-rw-r--r--sound/soc/codecs/wm8995.c43
-rw-r--r--sound/soc/codecs/wm8996.c11
-rw-r--r--sound/soc/codecs/wm8997.c25
-rw-r--r--sound/soc/codecs/wm_adsp.c50
-rw-r--r--sound/soc/davinci/davinci-evm.c59
-rw-r--r--sound/soc/davinci/davinci-mcasp.c277
-rw-r--r--sound/soc/fsl/Kconfig12
-rw-r--r--sound/soc/fsl/eukrea-tlv320.c108
-rw-r--r--sound/soc/fsl/fsl_esai.c36
-rw-r--r--sound/soc/fsl/fsl_esai.h2
-rw-r--r--sound/soc/fsl/fsl_sai.c332
-rw-r--r--sound/soc/fsl/fsl_sai.h48
-rw-r--r--sound/soc/fsl/fsl_spdif.c9
-rw-r--r--sound/soc/fsl/imx-mc13783.c1
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c7
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c10
-rw-r--r--sound/soc/fsl/imx-wm8962.c11
-rw-r--r--sound/soc/fsl/wm1133-ev1.c11
-rw-r--r--sound/soc/intel/Kconfig42
-rw-r--r--sound/soc/intel/Makefile27
-rw-r--r--sound/soc/intel/byt-rt5640.c187
-rw-r--r--sound/soc/intel/haswell.c235
-rw-r--r--sound/soc/intel/mfld_machine.c65
-rw-r--r--sound/soc/intel/sst-acpi.c284
-rw-r--r--sound/soc/intel/sst-baytrail-dsp.c372
-rw-r--r--sound/soc/intel/sst-baytrail-ipc.c867
-rw-r--r--sound/soc/intel/sst-baytrail-ipc.h69
-rw-r--r--sound/soc/intel/sst-baytrail-pcm.c422
-rw-r--r--sound/soc/intel/sst-dsp-priv.h309
-rw-r--r--sound/soc/intel/sst-dsp.c385
-rw-r--r--sound/soc/intel/sst-dsp.h233
-rw-r--r--sound/soc/intel/sst-firmware.c587
-rw-r--r--sound/soc/intel/sst-haswell-dsp.c517
-rw-r--r--sound/soc/intel/sst-haswell-ipc.c1785
-rw-r--r--sound/soc/intel/sst-haswell-ipc.h488
-rw-r--r--sound/soc/intel/sst-haswell-pcm.c872
-rw-r--r--sound/soc/intel/sst-mfld-dsp.h (renamed from sound/soc/intel/sst_dsp.h)8
-rw-r--r--sound/soc/intel/sst-mfld-platform.c (renamed from sound/soc/intel/sst_platform.c)8
-rw-r--r--sound/soc/intel/sst-mfld-platform.h (renamed from sound/soc/intel/sst_platform.h)4
-rw-r--r--sound/soc/omap/Kconfig4
-rw-r--r--sound/soc/omap/ams-delta.c55
-rw-r--r--sound/soc/omap/n810.c26
-rw-r--r--sound/soc/omap/rx51.c22
-rw-r--r--sound/soc/pxa/corgi.c42
-rw-r--r--sound/soc/pxa/magician.c22
-rw-r--r--sound/soc/pxa/spitz.c51
-rw-r--r--sound/soc/pxa/tosa.c28
-rw-r--r--sound/soc/samsung/Kconfig8
-rw-r--r--sound/soc/sh/rcar/Makefile2
-rw-r--r--sound/soc/sh/rcar/adg.c228
-rw-r--r--sound/soc/sh/rcar/core.c306
-rw-r--r--sound/soc/sh/rcar/gen.c98
-rw-r--r--sound/soc/sh/rcar/rsnd.h195
-rw-r--r--sound/soc/sh/rcar/scu.c384
-rw-r--r--sound/soc/sh/rcar/src.c687
-rw-r--r--sound/soc/sh/rcar/ssi.c332
-rw-r--r--sound/soc/soc-cache.c13
-rw-r--r--sound/soc/soc-compress.c65
-rw-r--r--sound/soc/soc-core.c582
-rw-r--r--sound/soc/soc-dapm.c604
-rw-r--r--sound/soc/soc-pcm.c112
-rw-r--r--sound/soc/spear/spdif_out.c10
-rw-r--r--sound/soc/tegra/Kconfig2
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c8
-rw-r--r--sound/usb/Kconfig1
-rw-r--r--sound/usb/mixer.c1
-rw-r--r--sound/usb/mixer_maps.c9
161 files changed, 14937 insertions, 3824 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a2104671f51d..5dcf88bed9b7 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1242,6 +1242,7 @@ int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_par
1242 return -EINVAL; 1242 return -EINVAL;
1243 return 0; 1243 return 0;
1244} 1244}
1245EXPORT_SYMBOL(snd_pcm_hw_constraint_mask64);
1245 1246
1246/** 1247/**
1247 * snd_pcm_hw_constraint_integer - apply an integer constraint to an interval 1248 * snd_pcm_hw_constraint_integer - apply an integer constraint to an interval
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index ec4536c8d8d4..dafcf82139e2 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -932,7 +932,7 @@ int snd_hda_bus_new(struct snd_card *card,
932} 932}
933EXPORT_SYMBOL_GPL(snd_hda_bus_new); 933EXPORT_SYMBOL_GPL(snd_hda_bus_new);
934 934
935#ifdef CONFIG_SND_HDA_GENERIC 935#if IS_ENABLED(CONFIG_SND_HDA_GENERIC)
936#define is_generic_config(codec) \ 936#define is_generic_config(codec) \
937 (codec->modelname && !strcmp(codec->modelname, "generic")) 937 (codec->modelname && !strcmp(codec->modelname, "generic"))
938#else 938#else
@@ -1339,23 +1339,15 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
1339/* 1339/*
1340 * Dynamic symbol binding for the codec parsers 1340 * Dynamic symbol binding for the codec parsers
1341 */ 1341 */
1342#ifdef MODULE
1343#define load_parser_sym(sym) ((int (*)(struct hda_codec *))symbol_request(sym))
1344#define unload_parser_addr(addr) symbol_put_addr(addr)
1345#else
1346#define load_parser_sym(sym) (sym)
1347#define unload_parser_addr(addr) do {} while (0)
1348#endif
1349 1342
1350#define load_parser(codec, sym) \ 1343#define load_parser(codec, sym) \
1351 ((codec)->parser = load_parser_sym(sym)) 1344 ((codec)->parser = (int (*)(struct hda_codec *))symbol_request(sym))
1352 1345
1353static void unload_parser(struct hda_codec *codec) 1346static void unload_parser(struct hda_codec *codec)
1354{ 1347{
1355 if (codec->parser) { 1348 if (codec->parser)
1356 unload_parser_addr(codec->parser); 1349 symbol_put_addr(codec->parser);
1357 codec->parser = NULL; 1350 codec->parser = NULL;
1358 }
1359} 1351}
1360 1352
1361/* 1353/*
@@ -1570,7 +1562,7 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec)
1570EXPORT_SYMBOL_GPL(snd_hda_codec_update_widgets); 1562EXPORT_SYMBOL_GPL(snd_hda_codec_update_widgets);
1571 1563
1572 1564
1573#ifdef CONFIG_SND_HDA_CODEC_HDMI 1565#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)
1574/* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */ 1566/* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */
1575static bool is_likely_hdmi_codec(struct hda_codec *codec) 1567static bool is_likely_hdmi_codec(struct hda_codec *codec)
1576{ 1568{
@@ -1620,12 +1612,20 @@ int snd_hda_codec_configure(struct hda_codec *codec)
1620 patch = codec->preset->patch; 1612 patch = codec->preset->patch;
1621 if (!patch) { 1613 if (!patch) {
1622 unload_parser(codec); /* to be sure */ 1614 unload_parser(codec); /* to be sure */
1623 if (is_likely_hdmi_codec(codec)) 1615 if (is_likely_hdmi_codec(codec)) {
1616#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
1624 patch = load_parser(codec, snd_hda_parse_hdmi_codec); 1617 patch = load_parser(codec, snd_hda_parse_hdmi_codec);
1625#ifdef CONFIG_SND_HDA_GENERIC 1618#elif IS_BUILTIN(CONFIG_SND_HDA_CODEC_HDMI)
1626 if (!patch) 1619 patch = snd_hda_parse_hdmi_codec;
1620#endif
1621 }
1622 if (!patch) {
1623#if IS_MODULE(CONFIG_SND_HDA_GENERIC)
1627 patch = load_parser(codec, snd_hda_parse_generic_codec); 1624 patch = load_parser(codec, snd_hda_parse_generic_codec);
1625#elif IS_BUILTIN(CONFIG_SND_HDA_GENERIC)
1626 patch = snd_hda_parse_generic_codec;
1628#endif 1627#endif
1628 }
1629 if (!patch) { 1629 if (!patch) {
1630 printk(KERN_ERR "hda-codec: No codec parser is available\n"); 1630 printk(KERN_ERR "hda-codec: No codec parser is available\n");
1631 return -ENODEV; 1631 return -ENODEV;
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 8321a97d5c05..d9a09bdd09db 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -3269,7 +3269,7 @@ static int cap_put_caller(struct snd_kcontrol *kcontrol,
3269 mutex_unlock(&codec->control_mutex); 3269 mutex_unlock(&codec->control_mutex);
3270 snd_hda_codec_flush_cache(codec); /* flush the updates */ 3270 snd_hda_codec_flush_cache(codec); /* flush the updates */
3271 if (err >= 0 && spec->cap_sync_hook) 3271 if (err >= 0 && spec->cap_sync_hook)
3272 spec->cap_sync_hook(codec, ucontrol); 3272 spec->cap_sync_hook(codec, kcontrol, ucontrol);
3273 return err; 3273 return err;
3274} 3274}
3275 3275
@@ -3390,7 +3390,7 @@ static int cap_single_sw_put(struct snd_kcontrol *kcontrol,
3390 return ret; 3390 return ret;
3391 3391
3392 if (spec->cap_sync_hook) 3392 if (spec->cap_sync_hook)
3393 spec->cap_sync_hook(codec, ucontrol); 3393 spec->cap_sync_hook(codec, kcontrol, ucontrol);
3394 3394
3395 return ret; 3395 return ret;
3396} 3396}
@@ -3795,7 +3795,7 @@ static int mux_select(struct hda_codec *codec, unsigned int adc_idx,
3795 return 0; 3795 return 0;
3796 snd_hda_activate_path(codec, path, true, false); 3796 snd_hda_activate_path(codec, path, true, false);
3797 if (spec->cap_sync_hook) 3797 if (spec->cap_sync_hook)
3798 spec->cap_sync_hook(codec, NULL); 3798 spec->cap_sync_hook(codec, NULL, NULL);
3799 path_power_down_sync(codec, old_path); 3799 path_power_down_sync(codec, old_path);
3800 return 1; 3800 return 1;
3801} 3801}
@@ -5270,7 +5270,7 @@ static void init_input_src(struct hda_codec *codec)
5270 } 5270 }
5271 5271
5272 if (spec->cap_sync_hook) 5272 if (spec->cap_sync_hook)
5273 spec->cap_sync_hook(codec, NULL); 5273 spec->cap_sync_hook(codec, NULL, NULL);
5274} 5274}
5275 5275
5276/* set right pin controls for digital I/O */ 5276/* set right pin controls for digital I/O */
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 07f767231c9f..c908afbe4d94 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -274,6 +274,7 @@ struct hda_gen_spec {
274 void (*init_hook)(struct hda_codec *codec); 274 void (*init_hook)(struct hda_codec *codec);
275 void (*automute_hook)(struct hda_codec *codec); 275 void (*automute_hook)(struct hda_codec *codec);
276 void (*cap_sync_hook)(struct hda_codec *codec, 276 void (*cap_sync_hook)(struct hda_codec *codec,
277 struct snd_kcontrol *kcontrol,
277 struct snd_ctl_elem_value *ucontrol); 278 struct snd_ctl_elem_value *ucontrol);
278 279
279 /* PCM hooks */ 280 /* PCM hooks */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index fa2879a21a50..e354ab1ec20f 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -198,7 +198,7 @@ MODULE_DESCRIPTION("Intel HDA driver");
198#endif 198#endif
199 199
200#if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO) 200#if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO)
201#ifdef CONFIG_SND_HDA_CODEC_HDMI 201#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)
202#define SUPPORT_VGA_SWITCHEROO 202#define SUPPORT_VGA_SWITCHEROO
203#endif 203#endif
204#endif 204#endif
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 7a426ed491f2..8ed0bcc01386 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -244,6 +244,19 @@ static void ad_fixup_inv_jack_detect(struct hda_codec *codec,
244 } 244 }
245} 245}
246 246
247/* Toshiba Satellite L40 implements EAPD in a standard way unlike others */
248static void ad1986a_fixup_eapd(struct hda_codec *codec,
249 const struct hda_fixup *fix, int action)
250{
251 struct ad198x_spec *spec = codec->spec;
252
253 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
254 codec->inv_eapd = 0;
255 spec->gen.keep_eapd_on = 1;
256 spec->eapd_nid = 0x1b;
257 }
258}
259
247enum { 260enum {
248 AD1986A_FIXUP_INV_JACK_DETECT, 261 AD1986A_FIXUP_INV_JACK_DETECT,
249 AD1986A_FIXUP_ULTRA, 262 AD1986A_FIXUP_ULTRA,
@@ -251,6 +264,7 @@ enum {
251 AD1986A_FIXUP_3STACK, 264 AD1986A_FIXUP_3STACK,
252 AD1986A_FIXUP_LAPTOP, 265 AD1986A_FIXUP_LAPTOP,
253 AD1986A_FIXUP_LAPTOP_IMIC, 266 AD1986A_FIXUP_LAPTOP_IMIC,
267 AD1986A_FIXUP_EAPD,
254}; 268};
255 269
256static const struct hda_fixup ad1986a_fixups[] = { 270static const struct hda_fixup ad1986a_fixups[] = {
@@ -311,6 +325,10 @@ static const struct hda_fixup ad1986a_fixups[] = {
311 .chained_before = 1, 325 .chained_before = 1,
312 .chain_id = AD1986A_FIXUP_LAPTOP, 326 .chain_id = AD1986A_FIXUP_LAPTOP,
313 }, 327 },
328 [AD1986A_FIXUP_EAPD] = {
329 .type = HDA_FIXUP_FUNC,
330 .v.func = ad1986a_fixup_eapd,
331 },
314}; 332};
315 333
316static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { 334static const struct snd_pci_quirk ad1986a_fixup_tbl[] = {
@@ -318,6 +336,7 @@ static const struct snd_pci_quirk ad1986a_fixup_tbl[] = {
318 SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK), 336 SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK),
319 SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK), 337 SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK),
320 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK), 338 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK),
339 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40", AD1986A_FIXUP_EAPD),
321 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP), 340 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP),
322 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG), 341 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG),
323 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA), 342 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA),
@@ -472,6 +491,8 @@ static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec)
472static int patch_ad1983(struct hda_codec *codec) 491static int patch_ad1983(struct hda_codec *codec)
473{ 492{
474 struct ad198x_spec *spec; 493 struct ad198x_spec *spec;
494 static hda_nid_t conn_0c[] = { 0x08 };
495 static hda_nid_t conn_0d[] = { 0x09 };
475 int err; 496 int err;
476 497
477 err = alloc_ad_spec(codec); 498 err = alloc_ad_spec(codec);
@@ -479,8 +500,14 @@ static int patch_ad1983(struct hda_codec *codec)
479 return err; 500 return err;
480 spec = codec->spec; 501 spec = codec->spec;
481 502
503 spec->gen.mixer_nid = 0x0e;
482 spec->gen.beep_nid = 0x10; 504 spec->gen.beep_nid = 0x10;
483 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 505 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
506
507 /* limit the loopback routes not to confuse the parser */
508 snd_hda_override_conn_list(codec, 0x0c, ARRAY_SIZE(conn_0c), conn_0c);
509 snd_hda_override_conn_list(codec, 0x0d, ARRAY_SIZE(conn_0d), conn_0d);
510
484 err = ad198x_parse_auto_config(codec, false); 511 err = ad198x_parse_auto_config(codec, false);
485 if (err < 0) 512 if (err < 0)
486 goto error; 513 goto error;
@@ -999,6 +1026,9 @@ static void ad1884_fixup_thinkpad(struct hda_codec *codec,
999 spec->gen.keep_eapd_on = 1; 1026 spec->gen.keep_eapd_on = 1;
1000 spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; 1027 spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook;
1001 spec->eapd_nid = 0x12; 1028 spec->eapd_nid = 0x12;
1029 /* Analog PC Beeper - allow firmware/ACPI beeps */
1030 spec->beep_amp = HDA_COMPOSE_AMP_VAL(0x20, 3, 3, HDA_INPUT);
1031 spec->gen.beep_nid = 0; /* no digital beep */
1002 } 1032 }
1003} 1033}
1004 1034
@@ -1065,6 +1095,7 @@ static int patch_ad1884(struct hda_codec *codec)
1065 spec = codec->spec; 1095 spec = codec->spec;
1066 1096
1067 spec->gen.mixer_nid = 0x20; 1097 spec->gen.mixer_nid = 0x20;
1098 spec->gen.mixer_merge_nid = 0x21;
1068 spec->gen.beep_nid = 0x10; 1099 spec->gen.beep_nid = 0x10;
1069 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 1100 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1070 1101
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 54d14793725a..46ecdbb9053f 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -2662,60 +2662,6 @@ static bool dspload_wait_loaded(struct hda_codec *codec)
2662} 2662}
2663 2663
2664/* 2664/*
2665 * PCM stuffs
2666 */
2667static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid,
2668 u32 stream_tag,
2669 int channel_id, int format)
2670{
2671 unsigned int oldval, newval;
2672
2673 if (!nid)
2674 return;
2675
2676 snd_printdd(
2677 "ca0132_setup_stream: NID=0x%x, stream=0x%x, "
2678 "channel=%d, format=0x%x\n",
2679 nid, stream_tag, channel_id, format);
2680
2681 /* update the format-id if changed */
2682 oldval = snd_hda_codec_read(codec, nid, 0,
2683 AC_VERB_GET_STREAM_FORMAT,
2684 0);
2685 if (oldval != format) {
2686 msleep(20);
2687 snd_hda_codec_write(codec, nid, 0,
2688 AC_VERB_SET_STREAM_FORMAT,
2689 format);
2690 }
2691
2692 oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
2693 newval = (stream_tag << 4) | channel_id;
2694 if (oldval != newval) {
2695 snd_hda_codec_write(codec, nid, 0,
2696 AC_VERB_SET_CHANNEL_STREAMID,
2697 newval);
2698 }
2699}
2700
2701static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
2702{
2703 unsigned int val;
2704
2705 if (!nid)
2706 return;
2707
2708 snd_printdd(KERN_INFO "ca0132_cleanup_stream: NID=0x%x\n", nid);
2709
2710 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
2711 if (!val)
2712 return;
2713
2714 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
2715 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
2716}
2717
2718/*
2719 * PCM callbacks 2665 * PCM callbacks
2720 */ 2666 */
2721static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2667static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
@@ -2726,7 +2672,7 @@ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2726{ 2672{
2727 struct ca0132_spec *spec = codec->spec; 2673 struct ca0132_spec *spec = codec->spec;
2728 2674
2729 ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); 2675 snd_hda_codec_setup_stream(codec, spec->dacs[0], stream_tag, 0, format);
2730 2676
2731 return 0; 2677 return 0;
2732} 2678}
@@ -2745,7 +2691,7 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2745 if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) 2691 if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID])
2746 msleep(50); 2692 msleep(50);
2747 2693
2748 ca0132_cleanup_stream(codec, spec->dacs[0]); 2694 snd_hda_codec_cleanup_stream(codec, spec->dacs[0]);
2749 2695
2750 return 0; 2696 return 0;
2751} 2697}
@@ -2822,10 +2768,8 @@ static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2822 unsigned int format, 2768 unsigned int format,
2823 struct snd_pcm_substream *substream) 2769 struct snd_pcm_substream *substream)
2824{ 2770{
2825 struct ca0132_spec *spec = codec->spec; 2771 snd_hda_codec_setup_stream(codec, hinfo->nid,
2826 2772 stream_tag, 0, format);
2827 ca0132_setup_stream(codec, spec->adcs[substream->number],
2828 stream_tag, 0, format);
2829 2773
2830 return 0; 2774 return 0;
2831} 2775}
@@ -2839,7 +2783,7 @@ static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2839 if (spec->dsp_state == DSP_DOWNLOADING) 2783 if (spec->dsp_state == DSP_DOWNLOADING)
2840 return 0; 2784 return 0;
2841 2785
2842 ca0132_cleanup_stream(codec, hinfo->nid); 2786 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
2843 return 0; 2787 return 0;
2844} 2788}
2845 2789
@@ -4742,6 +4686,8 @@ static int patch_ca0132(struct hda_codec *codec)
4742 return err; 4686 return err;
4743 4687
4744 codec->patch_ops = ca0132_patch_ops; 4688 codec->patch_ops = ca0132_patch_ops;
4689 codec->pcm_format_first = 1;
4690 codec->no_sticky_stream = 1;
4745 4691
4746 return 0; 4692 return 0;
4747} 4693}
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 4e0ec146553d..bcf91bea3317 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3291,7 +3291,8 @@ static void cxt_update_headset_mode(struct hda_codec *codec)
3291} 3291}
3292 3292
3293static void cxt_update_headset_mode_hook(struct hda_codec *codec, 3293static void cxt_update_headset_mode_hook(struct hda_codec *codec,
3294 struct snd_ctl_elem_value *ucontrol) 3294 struct snd_kcontrol *kcontrol,
3295 struct snd_ctl_elem_value *ucontrol)
3295{ 3296{
3296 cxt_update_headset_mode(codec); 3297 cxt_update_headset_mode(codec);
3297} 3298}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 56a8f1876603..850296a1e0ff 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -708,7 +708,8 @@ static void alc_inv_dmic_sync(struct hda_codec *codec, bool force)
708} 708}
709 709
710static void alc_inv_dmic_hook(struct hda_codec *codec, 710static void alc_inv_dmic_hook(struct hda_codec *codec,
711 struct snd_ctl_elem_value *ucontrol) 711 struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
712{ 713{
713 alc_inv_dmic_sync(codec, false); 714 alc_inv_dmic_sync(codec, false);
714} 715}
@@ -1821,6 +1822,7 @@ enum {
1821 ALC889_FIXUP_IMAC91_VREF, 1822 ALC889_FIXUP_IMAC91_VREF,
1822 ALC889_FIXUP_MBA11_VREF, 1823 ALC889_FIXUP_MBA11_VREF,
1823 ALC889_FIXUP_MBA21_VREF, 1824 ALC889_FIXUP_MBA21_VREF,
1825 ALC889_FIXUP_MP11_VREF,
1824 ALC882_FIXUP_INV_DMIC, 1826 ALC882_FIXUP_INV_DMIC,
1825 ALC882_FIXUP_NO_PRIMARY_HP, 1827 ALC882_FIXUP_NO_PRIMARY_HP,
1826 ALC887_FIXUP_ASUS_BASS, 1828 ALC887_FIXUP_ASUS_BASS,
@@ -2190,6 +2192,12 @@ static const struct hda_fixup alc882_fixups[] = {
2190 .chained = true, 2192 .chained = true,
2191 .chain_id = ALC889_FIXUP_MBP_VREF, 2193 .chain_id = ALC889_FIXUP_MBP_VREF,
2192 }, 2194 },
2195 [ALC889_FIXUP_MP11_VREF] = {
2196 .type = HDA_FIXUP_FUNC,
2197 .v.func = alc889_fixup_mba11_vref,
2198 .chained = true,
2199 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2200 },
2193 [ALC882_FIXUP_INV_DMIC] = { 2201 [ALC882_FIXUP_INV_DMIC] = {
2194 .type = HDA_FIXUP_FUNC, 2202 .type = HDA_FIXUP_FUNC,
2195 .v.func = alc_fixup_inv_dmic_0x12, 2203 .v.func = alc_fixup_inv_dmic_0x12,
@@ -2253,7 +2261,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2253 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), 2261 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2254 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), 2262 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2255 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), 2263 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2256 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), 2264 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
2257 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), 2265 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2258 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), 2266 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
2259 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), 2267 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
@@ -3211,7 +3219,8 @@ static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled)
3211 3219
3212/* turn on/off mic-mute LED per capture hook */ 3220/* turn on/off mic-mute LED per capture hook */
3213static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, 3221static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec,
3214 struct snd_ctl_elem_value *ucontrol) 3222 struct snd_kcontrol *kcontrol,
3223 struct snd_ctl_elem_value *ucontrol)
3215{ 3224{
3216 struct alc_spec *spec = codec->spec; 3225 struct alc_spec *spec = codec->spec;
3217 unsigned int oldval = spec->gpio_led; 3226 unsigned int oldval = spec->gpio_led;
@@ -3521,7 +3530,8 @@ static void alc_update_headset_mode(struct hda_codec *codec)
3521} 3530}
3522 3531
3523static void alc_update_headset_mode_hook(struct hda_codec *codec, 3532static void alc_update_headset_mode_hook(struct hda_codec *codec,
3524 struct snd_ctl_elem_value *ucontrol) 3533 struct snd_kcontrol *kcontrol,
3534 struct snd_ctl_elem_value *ucontrol)
3525{ 3535{
3526 alc_update_headset_mode(codec); 3536 alc_update_headset_mode(codec);
3527} 3537}
@@ -4243,6 +4253,7 @@ static const struct hda_fixup alc269_fixups[] = {
4243}; 4253};
4244 4254
4245static const struct snd_pci_quirk alc269_fixup_tbl[] = { 4255static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4256 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
4246 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), 4257 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
4247 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), 4258 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
4248 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), 4259 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
@@ -4298,7 +4309,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4298 SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), 4309 SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4299 SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), 4310 SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4300 SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), 4311 SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4312 SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4301 SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 4313 SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4314 SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4302 SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), 4315 SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4303 SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 4316 SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4304 SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 4317 SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
@@ -4307,6 +4320,54 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4307 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 4320 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4308 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 4321 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4309 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), 4322 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
4323 /* ALC282 */
4324 SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4325 SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4326 SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4327 SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4328 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4329 SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4330 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4331 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4332 SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4333 SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4334 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4335 SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4336 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4337 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4338 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4339 SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4340 SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4341 SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4342 SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4343 SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4344 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4345 SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4346 /* ALC290 */
4347 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4348 SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4349 SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4350 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4351 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4352 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4353 SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4354 SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4355 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4356 SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4357 SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4358 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4359 SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4360 SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4361 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4362 SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4363 SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4364 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4365 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4366 SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4367 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4368 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4369 SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4370 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4310 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), 4371 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
4311 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), 4372 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
4312 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 4373 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -4322,6 +4383,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4322 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), 4383 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
4323 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), 4384 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
4324 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), 4385 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
4386 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
4325 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), 4387 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
4326 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), 4388 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
4327 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 4389 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
@@ -5096,12 +5158,13 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
5096 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 5158 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
5097 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 5159 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5098 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 5160 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5161 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5099 SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), 5162 SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE),
5100 SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), 5163 SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE),
5101 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 5164 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5102 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 5165 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5103 SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), 5166 SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE),
5104 SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 5167 SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE),
5105 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 5168 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
5106 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP), 5169 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP),
5107 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP), 5170 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP),
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 6998cf29b9bc..3bc29c9b2529 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -83,6 +83,7 @@ enum {
83 STAC_DELL_M6_BOTH, 83 STAC_DELL_M6_BOTH,
84 STAC_DELL_EQ, 84 STAC_DELL_EQ,
85 STAC_ALIENWARE_M17X, 85 STAC_ALIENWARE_M17X,
86 STAC_92HD89XX_HP_FRONT_JACK,
86 STAC_92HD73XX_MODELS 87 STAC_92HD73XX_MODELS
87}; 88};
88 89
@@ -97,6 +98,7 @@ enum {
97 STAC_92HD83XXX_HP_LED, 98 STAC_92HD83XXX_HP_LED,
98 STAC_92HD83XXX_HP_INV_LED, 99 STAC_92HD83XXX_HP_INV_LED,
99 STAC_92HD83XXX_HP_MIC_LED, 100 STAC_92HD83XXX_HP_MIC_LED,
101 STAC_HP_LED_GPIO10,
100 STAC_92HD83XXX_HEADSET_JACK, 102 STAC_92HD83XXX_HEADSET_JACK,
101 STAC_92HD83XXX_HP, 103 STAC_92HD83XXX_HP,
102 STAC_HP_ENVY_BASS, 104 STAC_HP_ENVY_BASS,
@@ -194,7 +196,7 @@ struct sigmatel_spec {
194 int default_polarity; 196 int default_polarity;
195 197
196 unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */ 198 unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */
197 bool mic_mute_led_on; /* current mic mute state */ 199 unsigned int mic_enabled; /* current mic mute state (bitmask) */
198 200
199 /* stream */ 201 /* stream */
200 unsigned int stream_delay; 202 unsigned int stream_delay;
@@ -324,19 +326,26 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
324 326
325/* hook for controlling mic-mute LED GPIO */ 327/* hook for controlling mic-mute LED GPIO */
326static void stac_capture_led_hook(struct hda_codec *codec, 328static void stac_capture_led_hook(struct hda_codec *codec,
327 struct snd_ctl_elem_value *ucontrol) 329 struct snd_kcontrol *kcontrol,
330 struct snd_ctl_elem_value *ucontrol)
328{ 331{
329 struct sigmatel_spec *spec = codec->spec; 332 struct sigmatel_spec *spec = codec->spec;
330 bool mute; 333 unsigned int mask;
334 bool cur_mute, prev_mute;
331 335
332 if (!ucontrol) 336 if (!kcontrol || !ucontrol)
333 return; 337 return;
334 338
335 mute = !(ucontrol->value.integer.value[0] || 339 mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
336 ucontrol->value.integer.value[1]); 340 prev_mute = !spec->mic_enabled;
337 if (spec->mic_mute_led_on != mute) { 341 if (ucontrol->value.integer.value[0] ||
338 spec->mic_mute_led_on = mute; 342 ucontrol->value.integer.value[1])
339 if (mute) 343 spec->mic_enabled |= mask;
344 else
345 spec->mic_enabled &= ~mask;
346 cur_mute = !spec->mic_enabled;
347 if (cur_mute != prev_mute) {
348 if (cur_mute)
340 spec->gpio_data |= spec->mic_mute_led_gpio; 349 spec->gpio_data |= spec->mic_mute_led_gpio;
341 else 350 else
342 spec->gpio_data &= ~spec->mic_mute_led_gpio; 351 spec->gpio_data &= ~spec->mic_mute_led_gpio;
@@ -1788,6 +1797,12 @@ static const struct hda_pintbl intel_dg45id_pin_configs[] = {
1788 {} 1797 {}
1789}; 1798};
1790 1799
1800static const struct hda_pintbl stac92hd89xx_hp_front_jack_pin_configs[] = {
1801 { 0x0a, 0x02214030 },
1802 { 0x0b, 0x02A19010 },
1803 {}
1804};
1805
1791static void stac92hd73xx_fixup_ref(struct hda_codec *codec, 1806static void stac92hd73xx_fixup_ref(struct hda_codec *codec,
1792 const struct hda_fixup *fix, int action) 1807 const struct hda_fixup *fix, int action)
1793{ 1808{
@@ -1906,6 +1921,10 @@ static const struct hda_fixup stac92hd73xx_fixups[] = {
1906 [STAC_92HD73XX_NO_JD] = { 1921 [STAC_92HD73XX_NO_JD] = {
1907 .type = HDA_FIXUP_FUNC, 1922 .type = HDA_FIXUP_FUNC,
1908 .v.func = stac92hd73xx_fixup_no_jd, 1923 .v.func = stac92hd73xx_fixup_no_jd,
1924 },
1925 [STAC_92HD89XX_HP_FRONT_JACK] = {
1926 .type = HDA_FIXUP_PINS,
1927 .v.pins = stac92hd89xx_hp_front_jack_pin_configs,
1909 } 1928 }
1910}; 1929};
1911 1930
@@ -1966,6 +1985,8 @@ static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
1966 "Alienware M17x", STAC_ALIENWARE_M17X), 1985 "Alienware M17x", STAC_ALIENWARE_M17X),
1967 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, 1986 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
1968 "Alienware M17x R3", STAC_DELL_EQ), 1987 "Alienware M17x R3", STAC_DELL_EQ),
1988 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17,
1989 "unknown HP", STAC_92HD89XX_HP_FRONT_JACK),
1969 {} /* terminator */ 1990 {} /* terminator */
1970}; 1991};
1971 1992
@@ -2110,6 +2131,17 @@ static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec,
2110 } 2131 }
2111} 2132}
2112 2133
2134static void stac92hd83xxx_fixup_hp_led_gpio10(struct hda_codec *codec,
2135 const struct hda_fixup *fix, int action)
2136{
2137 struct sigmatel_spec *spec = codec->spec;
2138
2139 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2140 spec->gpio_led = 0x10; /* GPIO4 */
2141 spec->default_polarity = 0;
2142 }
2143}
2144
2113static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec, 2145static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec,
2114 const struct hda_fixup *fix, int action) 2146 const struct hda_fixup *fix, int action)
2115{ 2147{
@@ -2604,6 +2636,12 @@ static const struct hda_fixup stac92hd83xxx_fixups[] = {
2604 .chained = true, 2636 .chained = true,
2605 .chain_id = STAC_92HD83XXX_HP, 2637 .chain_id = STAC_92HD83XXX_HP,
2606 }, 2638 },
2639 [STAC_HP_LED_GPIO10] = {
2640 .type = HDA_FIXUP_FUNC,
2641 .v.func = stac92hd83xxx_fixup_hp_led_gpio10,
2642 .chained = true,
2643 .chain_id = STAC_92HD83XXX_HP,
2644 },
2607 [STAC_92HD83XXX_HEADSET_JACK] = { 2645 [STAC_92HD83XXX_HEADSET_JACK] = {
2608 .type = HDA_FIXUP_FUNC, 2646 .type = HDA_FIXUP_FUNC,
2609 .v.func = stac92hd83xxx_fixup_headset_jack, 2647 .v.func = stac92hd83xxx_fixup_headset_jack,
@@ -2682,6 +2720,8 @@ static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = {
2682 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2720 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2683 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888, 2721 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888,
2684 "HP Envy Spectre", STAC_HP_ENVY_BASS), 2722 "HP Envy Spectre", STAC_HP_ENVY_BASS),
2723 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1899,
2724 "HP Folio 13", STAC_HP_LED_GPIO10),
2685 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df, 2725 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df,
2686 "HP Folio", STAC_HP_BNB13_EQ), 2726 "HP Folio", STAC_HP_BNB13_EQ),
2687 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8, 2727 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8,
@@ -4462,7 +4502,7 @@ static void stac_setup_gpio(struct hda_codec *codec)
4462 if (spec->mic_mute_led_gpio) { 4502 if (spec->mic_mute_led_gpio) {
4463 spec->gpio_mask |= spec->mic_mute_led_gpio; 4503 spec->gpio_mask |= spec->mic_mute_led_gpio;
4464 spec->gpio_dir |= spec->mic_mute_led_gpio; 4504 spec->gpio_dir |= spec->mic_mute_led_gpio;
4465 spec->mic_mute_led_on = true; 4505 spec->mic_enabled = 0;
4466 spec->gpio_data |= spec->mic_mute_led_gpio; 4506 spec->gpio_data |= spec->mic_mute_led_gpio;
4467 4507
4468 spec->gen.cap_sync_hook = stac_capture_led_hook; 4508 spec->gen.cap_sync_hook = stac_capture_led_hook;
diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c
index 5799fbc24c28..8fe3b8c18ed4 100644
--- a/sound/pci/hda/thinkpad_helper.c
+++ b/sound/pci/hda/thinkpad_helper.c
@@ -39,6 +39,7 @@ static void update_tpacpi_mute_led(void *private_data, int enabled)
39} 39}
40 40
41static void update_tpacpi_micmute_led(struct hda_codec *codec, 41static void update_tpacpi_micmute_led(struct hda_codec *codec,
42 struct snd_kcontrol *kcontrol,
42 struct snd_ctl_elem_value *ucontrol) 43 struct snd_ctl_elem_value *ucontrol)
43{ 44{
44 if (!ucontrol || !led_set_func) 45 if (!ucontrol || !led_set_func)
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index e634eb78ed03..4789619a52d8 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -58,6 +58,6 @@ config SND_AT91_SOC_AFEB9260
58 depends on ARCH_AT91 && ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC 58 depends on ARCH_AT91 && ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
59 select SND_ATMEL_SOC_PDC 59 select SND_ATMEL_SOC_PDC
60 select SND_ATMEL_SOC_SSC 60 select SND_ATMEL_SOC_SSC
61 select SND_SOC_TLV320AIC23 61 select SND_SOC_TLV320AIC23_I2C
62 help 62 help
63 Say Y here to support sound on AFEB9260 board. 63 Say Y here to support sound on AFEB9260 board.
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 1ead3c977a51..de433cfd044c 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -341,6 +341,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
341{ 341{
342 int id = dai->id; 342 int id = dai->id;
343 struct atmel_ssc_info *ssc_p = &ssc_info[id]; 343 struct atmel_ssc_info *ssc_p = &ssc_info[id];
344 struct ssc_device *ssc = ssc_p->ssc;
344 struct atmel_pcm_dma_params *dma_params; 345 struct atmel_pcm_dma_params *dma_params;
345 int dir, channels, bits; 346 int dir, channels, bits;
346 u32 tfmr, rfmr, tcmr, rcmr; 347 u32 tfmr, rfmr, tcmr, rcmr;
@@ -466,7 +467,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
466 | SSC_BF(RCMR_START, start_event) 467 | SSC_BF(RCMR_START, start_event)
467 | SSC_BF(RCMR_CKI, SSC_CKI_RISING) 468 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
468 | SSC_BF(RCMR_CKO, SSC_CKO_NONE) 469 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
469 | SSC_BF(RCMR_CKS, SSC_CKS_CLOCK); 470 | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
471 SSC_CKS_PIN : SSC_CKS_CLOCK);
470 472
471 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) 473 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
472 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) 474 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
@@ -481,7 +483,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
481 | SSC_BF(TCMR_START, start_event) 483 | SSC_BF(TCMR_START, start_event)
482 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) 484 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
483 | SSC_BF(TCMR_CKO, SSC_CKO_NONE) 485 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
484 | SSC_BF(TCMR_CKS, SSC_CKS_PIN); 486 | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
487 SSC_CKS_CLOCK : SSC_CKS_PIN);
485 488
486 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) 489 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
487 | SSC_BF(TFMR_FSDEN, 0) 490 | SSC_BF(TFMR_FSDEN, 0)
@@ -550,7 +553,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
550 | SSC_BF(RCMR_START, SSC_START_RISING_RF) 553 | SSC_BF(RCMR_START, SSC_START_RISING_RF)
551 | SSC_BF(RCMR_CKI, SSC_CKI_RISING) 554 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
552 | SSC_BF(RCMR_CKO, SSC_CKO_NONE) 555 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
553 | SSC_BF(RCMR_CKS, SSC_CKS_PIN); 556 | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
557 SSC_CKS_PIN : SSC_CKS_CLOCK);
554 558
555 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) 559 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
556 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) 560 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
@@ -565,7 +569,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
565 | SSC_BF(TCMR_START, SSC_START_RISING_RF) 569 | SSC_BF(TCMR_START, SSC_START_RISING_RF)
566 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) 570 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
567 | SSC_BF(TCMR_CKO, SSC_CKO_NONE) 571 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
568 | SSC_BF(TCMR_CKS, SSC_CKS_PIN); 572 | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
573 SSC_CKS_CLOCK : SSC_CKS_PIN);
569 574
570 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) 575 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
571 | SSC_BF(TFMR_FSDEN, 0) 576 | SSC_BF(TFMR_FSDEN, 0)
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index f15bff1548f8..174bd546c08b 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -155,25 +155,14 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
155 return ret; 155 return ret;
156 } 156 }
157 157
158 /* Add specific widgets */
159 snd_soc_dapm_new_controls(dapm, at91sam9g20ek_dapm_widgets,
160 ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
161 /* Set up specific audio path interconnects */
162 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
163
164 /* not connected */ 158 /* not connected */
165 snd_soc_dapm_nc_pin(dapm, "RLINEIN"); 159 snd_soc_dapm_nc_pin(dapm, "RLINEIN");
166 snd_soc_dapm_nc_pin(dapm, "LLINEIN"); 160 snd_soc_dapm_nc_pin(dapm, "LLINEIN");
167 161
168#ifdef ENABLE_MIC_INPUT 162#ifndef ENABLE_MIC_INPUT
169 snd_soc_dapm_enable_pin(dapm, "Int Mic"); 163 snd_soc_dapm_nc_pin(&rtd->card->dapm, "Int Mic");
170#else
171 snd_soc_dapm_nc_pin(dapm, "Int Mic");
172#endif 164#endif
173 165
174 /* always connected */
175 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
176
177 return 0; 166 return 0;
178} 167}
179 168
@@ -194,6 +183,11 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = {
194 .dai_link = &at91sam9g20ek_dai, 183 .dai_link = &at91sam9g20ek_dai,
195 .num_links = 1, 184 .num_links = 1,
196 .set_bias_level = at91sam9g20ek_set_bias_level, 185 .set_bias_level = at91sam9g20ek_set_bias_level,
186
187 .dapm_widgets = at91sam9g20ek_dapm_widgets,
188 .num_dapm_widgets = ARRAY_SIZE(at91sam9g20ek_dapm_widgets),
189 .dapm_routes = intercon,
190 .num_dapm_routes = ARRAY_SIZE(intercon),
197}; 191};
198 192
199static int at91sam9g20ek_audio_probe(struct platform_device *pdev) 193static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 54f74f8cbb75..b2107918f0ad 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -11,7 +11,7 @@ config SND_BF5XX_I2S
11 11
12config SND_BF5XX_SOC_SSM2602 12config SND_BF5XX_SOC_SSM2602
13 tristate "SoC SSM2602 Audio Codec Add-On Card support" 13 tristate "SoC SSM2602 Audio Codec Add-On Card support"
14 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) 14 depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
15 select SND_BF5XX_SOC_I2S if !BF60x 15 select SND_BF5XX_SOC_I2S if !BF60x
16 select SND_BF6XX_SOC_I2S if BF60x 16 select SND_BF6XX_SOC_I2S if BF60x
17 select SND_SOC_SSM2602 17 select SND_SOC_SSM2602
@@ -21,10 +21,9 @@ config SND_BF5XX_SOC_SSM2602
21 21
22config SND_SOC_BFIN_EVAL_ADAU1701 22config SND_SOC_BFIN_EVAL_ADAU1701
23 tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards" 23 tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards"
24 depends on SND_BF5XX_I2S 24 depends on SND_BF5XX_I2S && I2C
25 select SND_BF5XX_SOC_I2S 25 select SND_BF5XX_SOC_I2S
26 select SND_SOC_ADAU1701 26 select SND_SOC_ADAU1701
27 select I2C
28 help 27 help
29 Say Y if you want to add support for the Analog Devices EVAL-ADAU1701MINIZ 28 Say Y if you want to add support for the Analog Devices EVAL-ADAU1701MINIZ
30 board connected to one of the Blackfin evaluation boards like the 29 board connected to one of the Blackfin evaluation boards like the
@@ -45,9 +44,10 @@ config SND_SOC_BFIN_EVAL_ADAU1373
45 44
46config SND_SOC_BFIN_EVAL_ADAV80X 45config SND_SOC_BFIN_EVAL_ADAV80X
47 tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards" 46 tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards"
48 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) 47 depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
49 select SND_BF5XX_SOC_I2S 48 select SND_BF5XX_SOC_I2S
50 select SND_SOC_ADAV80X 49 select SND_SOC_ADAV801 if SPI_MASTER
50 select SND_SOC_ADAV803 if I2C
51 help 51 help
52 Say Y if you want to add support for the Analog Devices EVAL-ADAV801 or 52 Say Y if you want to add support for the Analog Devices EVAL-ADAV801 or
53 EVAL-ADAV803 board connected to one of the Blackfin evaluation boards 53 EVAL-ADAV803 board connected to one of the Blackfin evaluation boards
@@ -58,7 +58,7 @@ config SND_SOC_BFIN_EVAL_ADAV80X
58 58
59config SND_BF5XX_SOC_AD1836 59config SND_BF5XX_SOC_AD1836
60 tristate "SoC AD1836 Audio support for BF5xx" 60 tristate "SoC AD1836 Audio support for BF5xx"
61 depends on SND_BF5XX_I2S 61 depends on SND_BF5XX_I2S && SPI_MASTER
62 select SND_BF5XX_SOC_I2S 62 select SND_BF5XX_SOC_I2S
63 select SND_SOC_AD1836 63 select SND_SOC_AD1836
64 help 64 help
@@ -66,9 +66,10 @@ config SND_BF5XX_SOC_AD1836
66 66
67config SND_BF5XX_SOC_AD193X 67config SND_BF5XX_SOC_AD193X
68 tristate "SoC AD193X Audio support for Blackfin" 68 tristate "SoC AD193X Audio support for Blackfin"
69 depends on SND_BF5XX_I2S 69 depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
70 select SND_BF5XX_SOC_I2S 70 select SND_BF5XX_SOC_I2S
71 select SND_SOC_AD193X 71 select SND_SOC_AD193X_I2C if I2C
72 select SND_SOC_AD193X_SPI if SPI_MASTER
72 help 73 help
73 Say Y if you want to add support for AD193X codec on Blackfin. 74 Say Y if you want to add support for AD193X codec on Blackfin.
74 This driver supports AD1936, AD1937, AD1938 and AD1939. 75 This driver supports AD1936, AD1937, AD1938 and AD1939.
diff --git a/sound/soc/cirrus/Kconfig b/sound/soc/cirrus/Kconfig
index 06f938deda15..5477c5475923 100644
--- a/sound/soc/cirrus/Kconfig
+++ b/sound/soc/cirrus/Kconfig
@@ -1,6 +1,6 @@
1config SND_EP93XX_SOC 1config SND_EP93XX_SOC
2 tristate "SoC Audio support for the Cirrus Logic EP93xx series" 2 tristate "SoC Audio support for the Cirrus Logic EP93xx series"
3 depends on (ARCH_EP93XX || COMPILE_TEST) && SND_SOC 3 depends on ARCH_EP93XX || COMPILE_TEST
4 select SND_SOC_GENERIC_DMAENGINE_PCM 4 select SND_SOC_GENERIC_DMAENGINE_PCM
5 help 5 help
6 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
@@ -18,7 +18,7 @@ config SND_EP93XX_SOC_SNAPPERCL15
18 tristate "SoC Audio support for Bluewater Systems Snapper CL15 module" 18 tristate "SoC Audio support for Bluewater Systems Snapper CL15 module"
19 depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15 19 depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15
20 select SND_EP93XX_SOC_I2S 20 select SND_EP93XX_SOC_I2S
21 select SND_SOC_TLV320AIC23 21 select SND_SOC_TLV320AIC23_I2C
22 help 22 help
23 Say Y or M here if you want to add support for I2S audio on the 23 Say Y or M here if you want to add support for I2S audio on the
24 Bluewater Systems Snapper CL15 module. 24 Bluewater Systems Snapper CL15 module.
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 75d0ad5d2dcb..8703244ee9fb 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -448,38 +448,38 @@ static const char *pm860x_opamp_texts[] = {"-50%", "-25%", "0%", "75%"};
448 448
449static const char *pm860x_pa_texts[] = {"-33%", "0%", "33%", "66%"}; 449static const char *pm860x_pa_texts[] = {"-33%", "0%", "33%", "66%"};
450 450
451static const struct soc_enum pm860x_hs1_opamp_enum = 451static SOC_ENUM_SINGLE_DECL(pm860x_hs1_opamp_enum,
452 SOC_ENUM_SINGLE(PM860X_HS1_CTRL, 5, 4, pm860x_opamp_texts); 452 PM860X_HS1_CTRL, 5, pm860x_opamp_texts);
453 453
454static const struct soc_enum pm860x_hs2_opamp_enum = 454static SOC_ENUM_SINGLE_DECL(pm860x_hs2_opamp_enum,
455 SOC_ENUM_SINGLE(PM860X_HS2_CTRL, 5, 4, pm860x_opamp_texts); 455 PM860X_HS2_CTRL, 5, pm860x_opamp_texts);
456 456
457static const struct soc_enum pm860x_hs1_pa_enum = 457static SOC_ENUM_SINGLE_DECL(pm860x_hs1_pa_enum,
458 SOC_ENUM_SINGLE(PM860X_HS1_CTRL, 3, 4, pm860x_pa_texts); 458 PM860X_HS1_CTRL, 3, pm860x_pa_texts);
459 459
460static const struct soc_enum pm860x_hs2_pa_enum = 460static SOC_ENUM_SINGLE_DECL(pm860x_hs2_pa_enum,
461 SOC_ENUM_SINGLE(PM860X_HS2_CTRL, 3, 4, pm860x_pa_texts); 461 PM860X_HS2_CTRL, 3, pm860x_pa_texts);
462 462
463static const struct soc_enum pm860x_lo1_opamp_enum = 463static SOC_ENUM_SINGLE_DECL(pm860x_lo1_opamp_enum,
464 SOC_ENUM_SINGLE(PM860X_LO1_CTRL, 5, 4, pm860x_opamp_texts); 464 PM860X_LO1_CTRL, 5, pm860x_opamp_texts);
465 465
466static const struct soc_enum pm860x_lo2_opamp_enum = 466static SOC_ENUM_SINGLE_DECL(pm860x_lo2_opamp_enum,
467 SOC_ENUM_SINGLE(PM860X_LO2_CTRL, 5, 4, pm860x_opamp_texts); 467 PM860X_LO2_CTRL, 5, pm860x_opamp_texts);
468 468
469static const struct soc_enum pm860x_lo1_pa_enum = 469static SOC_ENUM_SINGLE_DECL(pm860x_lo1_pa_enum,
470 SOC_ENUM_SINGLE(PM860X_LO1_CTRL, 3, 4, pm860x_pa_texts); 470 PM860X_LO1_CTRL, 3, pm860x_pa_texts);
471 471
472static const struct soc_enum pm860x_lo2_pa_enum = 472static SOC_ENUM_SINGLE_DECL(pm860x_lo2_pa_enum,
473 SOC_ENUM_SINGLE(PM860X_LO2_CTRL, 3, 4, pm860x_pa_texts); 473 PM860X_LO2_CTRL, 3, pm860x_pa_texts);
474 474
475static const struct soc_enum pm860x_spk_pa_enum = 475static SOC_ENUM_SINGLE_DECL(pm860x_spk_pa_enum,
476 SOC_ENUM_SINGLE(PM860X_EAR_CTRL_1, 5, 4, pm860x_pa_texts); 476 PM860X_EAR_CTRL_1, 5, pm860x_pa_texts);
477 477
478static const struct soc_enum pm860x_ear_pa_enum = 478static SOC_ENUM_SINGLE_DECL(pm860x_ear_pa_enum,
479 SOC_ENUM_SINGLE(PM860X_EAR_CTRL_2, 0, 4, pm860x_pa_texts); 479 PM860X_EAR_CTRL_2, 0, pm860x_pa_texts);
480 480
481static const struct soc_enum pm860x_spk_ear_opamp_enum = 481static SOC_ENUM_SINGLE_DECL(pm860x_spk_ear_opamp_enum,
482 SOC_ENUM_SINGLE(PM860X_EAR_CTRL_1, 3, 4, pm860x_opamp_texts); 482 PM860X_EAR_CTRL_1, 3, pm860x_opamp_texts);
483 483
484static const struct snd_kcontrol_new pm860x_snd_controls[] = { 484static const struct snd_kcontrol_new pm860x_snd_controls[] = {
485 SOC_DOUBLE_R_TLV("ADC Capture Volume", PM860X_ADC_ANA_2, 485 SOC_DOUBLE_R_TLV("ADC Capture Volume", PM860X_ADC_ANA_2,
@@ -561,8 +561,8 @@ static const char *aif1_text[] = {
561 "PCM L", "PCM R", 561 "PCM L", "PCM R",
562}; 562};
563 563
564static const struct soc_enum aif1_enum = 564static SOC_ENUM_SINGLE_DECL(aif1_enum,
565 SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 6, 2, aif1_text); 565 PM860X_PCM_IFACE_3, 6, aif1_text);
566 566
567static const struct snd_kcontrol_new aif1_mux = 567static const struct snd_kcontrol_new aif1_mux =
568 SOC_DAPM_ENUM("PCM Mux", aif1_enum); 568 SOC_DAPM_ENUM("PCM Mux", aif1_enum);
@@ -572,8 +572,8 @@ static const char *i2s_din_text[] = {
572 "DIN", "DIN1", 572 "DIN", "DIN1",
573}; 573};
574 574
575static const struct soc_enum i2s_din_enum = 575static SOC_ENUM_SINGLE_DECL(i2s_din_enum,
576 SOC_ENUM_SINGLE(PM860X_I2S_IFACE_3, 1, 2, i2s_din_text); 576 PM860X_I2S_IFACE_3, 1, i2s_din_text);
577 577
578static const struct snd_kcontrol_new i2s_din_mux = 578static const struct snd_kcontrol_new i2s_din_mux =
579 SOC_DAPM_ENUM("I2S DIN Mux", i2s_din_enum); 579 SOC_DAPM_ENUM("I2S DIN Mux", i2s_din_enum);
@@ -583,8 +583,8 @@ static const char *i2s_mic_text[] = {
583 "Ex PA", "ADC", 583 "Ex PA", "ADC",
584}; 584};
585 585
586static const struct soc_enum i2s_mic_enum = 586static SOC_ENUM_SINGLE_DECL(i2s_mic_enum,
587 SOC_ENUM_SINGLE(PM860X_I2S_IFACE_3, 4, 2, i2s_mic_text); 587 PM860X_I2S_IFACE_3, 4, i2s_mic_text);
588 588
589static const struct snd_kcontrol_new i2s_mic_mux = 589static const struct snd_kcontrol_new i2s_mic_mux =
590 SOC_DAPM_ENUM("I2S Mic Mux", i2s_mic_enum); 590 SOC_DAPM_ENUM("I2S Mic Mux", i2s_mic_enum);
@@ -594,8 +594,8 @@ static const char *adcl_text[] = {
594 "ADCR", "ADCL", 594 "ADCR", "ADCL",
595}; 595};
596 596
597static const struct soc_enum adcl_enum = 597static SOC_ENUM_SINGLE_DECL(adcl_enum,
598 SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 4, 2, adcl_text); 598 PM860X_PCM_IFACE_3, 4, adcl_text);
599 599
600static const struct snd_kcontrol_new adcl_mux = 600static const struct snd_kcontrol_new adcl_mux =
601 SOC_DAPM_ENUM("ADC Left Mux", adcl_enum); 601 SOC_DAPM_ENUM("ADC Left Mux", adcl_enum);
@@ -605,8 +605,8 @@ static const char *adcr_text[] = {
605 "ADCL", "ADCR", 605 "ADCL", "ADCR",
606}; 606};
607 607
608static const struct soc_enum adcr_enum = 608static SOC_ENUM_SINGLE_DECL(adcr_enum,
609 SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 2, 2, adcr_text); 609 PM860X_PCM_IFACE_3, 2, adcr_text);
610 610
611static const struct snd_kcontrol_new adcr_mux = 611static const struct snd_kcontrol_new adcr_mux =
612 SOC_DAPM_ENUM("ADC Right Mux", adcr_enum); 612 SOC_DAPM_ENUM("ADC Right Mux", adcr_enum);
@@ -616,8 +616,8 @@ static const char *adcr_ec_text[] = {
616 "ADCR", "EC", 616 "ADCR", "EC",
617}; 617};
618 618
619static const struct soc_enum adcr_ec_enum = 619static SOC_ENUM_SINGLE_DECL(adcr_ec_enum,
620 SOC_ENUM_SINGLE(PM860X_ADC_EN_2, 3, 2, adcr_ec_text); 620 PM860X_ADC_EN_2, 3, adcr_ec_text);
621 621
622static const struct snd_kcontrol_new adcr_ec_mux = 622static const struct snd_kcontrol_new adcr_ec_mux =
623 SOC_DAPM_ENUM("ADCR EC Mux", adcr_ec_enum); 623 SOC_DAPM_ENUM("ADCR EC Mux", adcr_ec_enum);
@@ -627,8 +627,8 @@ static const char *ec_text[] = {
627 "Left", "Right", "Left + Right", 627 "Left", "Right", "Left + Right",
628}; 628};
629 629
630static const struct soc_enum ec_enum = 630static SOC_ENUM_SINGLE_DECL(ec_enum,
631 SOC_ENUM_SINGLE(PM860X_EC_PATH, 1, 3, ec_text); 631 PM860X_EC_PATH, 1, ec_text);
632 632
633static const struct snd_kcontrol_new ec_mux = 633static const struct snd_kcontrol_new ec_mux =
634 SOC_DAPM_ENUM("EC Mux", ec_enum); 634 SOC_DAPM_ENUM("EC Mux", ec_enum);
@@ -638,36 +638,36 @@ static const char *dac_text[] = {
638}; 638};
639 639
640/* DAC Headset 1 Mux / Mux10 */ 640/* DAC Headset 1 Mux / Mux10 */
641static const struct soc_enum dac_hs1_enum = 641static SOC_ENUM_SINGLE_DECL(dac_hs1_enum,
642 SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 0, 4, dac_text); 642 PM860X_ANA_INPUT_SEL_1, 0, dac_text);
643 643
644static const struct snd_kcontrol_new dac_hs1_mux = 644static const struct snd_kcontrol_new dac_hs1_mux =
645 SOC_DAPM_ENUM("DAC HS1 Mux", dac_hs1_enum); 645 SOC_DAPM_ENUM("DAC HS1 Mux", dac_hs1_enum);
646 646
647/* DAC Headset 2 Mux / Mux11 */ 647/* DAC Headset 2 Mux / Mux11 */
648static const struct soc_enum dac_hs2_enum = 648static SOC_ENUM_SINGLE_DECL(dac_hs2_enum,
649 SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 2, 4, dac_text); 649 PM860X_ANA_INPUT_SEL_1, 2, dac_text);
650 650
651static const struct snd_kcontrol_new dac_hs2_mux = 651static const struct snd_kcontrol_new dac_hs2_mux =
652 SOC_DAPM_ENUM("DAC HS2 Mux", dac_hs2_enum); 652 SOC_DAPM_ENUM("DAC HS2 Mux", dac_hs2_enum);
653 653
654/* DAC Lineout 1 Mux / Mux12 */ 654/* DAC Lineout 1 Mux / Mux12 */
655static const struct soc_enum dac_lo1_enum = 655static SOC_ENUM_SINGLE_DECL(dac_lo1_enum,
656 SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 4, 4, dac_text); 656 PM860X_ANA_INPUT_SEL_1, 4, dac_text);
657 657
658static const struct snd_kcontrol_new dac_lo1_mux = 658static const struct snd_kcontrol_new dac_lo1_mux =
659 SOC_DAPM_ENUM("DAC LO1 Mux", dac_lo1_enum); 659 SOC_DAPM_ENUM("DAC LO1 Mux", dac_lo1_enum);
660 660
661/* DAC Lineout 2 Mux / Mux13 */ 661/* DAC Lineout 2 Mux / Mux13 */
662static const struct soc_enum dac_lo2_enum = 662static SOC_ENUM_SINGLE_DECL(dac_lo2_enum,
663 SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 6, 4, dac_text); 663 PM860X_ANA_INPUT_SEL_1, 6, dac_text);
664 664
665static const struct snd_kcontrol_new dac_lo2_mux = 665static const struct snd_kcontrol_new dac_lo2_mux =
666 SOC_DAPM_ENUM("DAC LO2 Mux", dac_lo2_enum); 666 SOC_DAPM_ENUM("DAC LO2 Mux", dac_lo2_enum);
667 667
668/* DAC Spearker Earphone Mux / Mux14 */ 668/* DAC Spearker Earphone Mux / Mux14 */
669static const struct soc_enum dac_spk_ear_enum = 669static SOC_ENUM_SINGLE_DECL(dac_spk_ear_enum,
670 SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_2, 0, 4, dac_text); 670 PM860X_ANA_INPUT_SEL_2, 0, dac_text);
671 671
672static const struct snd_kcontrol_new dac_spk_ear_mux = 672static const struct snd_kcontrol_new dac_spk_ear_mux =
673 SOC_DAPM_ENUM("DAC SP Mux", dac_spk_ear_enum); 673 SOC_DAPM_ENUM("DAC SP Mux", dac_spk_ear_enum);
@@ -677,29 +677,29 @@ static const char *in_text[] = {
677 "Digital", "Analog", 677 "Digital", "Analog",
678}; 678};
679 679
680static const struct soc_enum hs1_enum = 680static SOC_ENUM_SINGLE_DECL(hs1_enum,
681 SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 0, 2, in_text); 681 PM860X_ANA_TO_ANA, 0, in_text);
682 682
683static const struct snd_kcontrol_new hs1_mux = 683static const struct snd_kcontrol_new hs1_mux =
684 SOC_DAPM_ENUM("Headset1 Mux", hs1_enum); 684 SOC_DAPM_ENUM("Headset1 Mux", hs1_enum);
685 685
686/* Headset 2 Mux / Mux16 */ 686/* Headset 2 Mux / Mux16 */
687static const struct soc_enum hs2_enum = 687static SOC_ENUM_SINGLE_DECL(hs2_enum,
688 SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 1, 2, in_text); 688 PM860X_ANA_TO_ANA, 1, in_text);
689 689
690static const struct snd_kcontrol_new hs2_mux = 690static const struct snd_kcontrol_new hs2_mux =
691 SOC_DAPM_ENUM("Headset2 Mux", hs2_enum); 691 SOC_DAPM_ENUM("Headset2 Mux", hs2_enum);
692 692
693/* Lineout 1 Mux / Mux17 */ 693/* Lineout 1 Mux / Mux17 */
694static const struct soc_enum lo1_enum = 694static SOC_ENUM_SINGLE_DECL(lo1_enum,
695 SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 2, 2, in_text); 695 PM860X_ANA_TO_ANA, 2, in_text);
696 696
697static const struct snd_kcontrol_new lo1_mux = 697static const struct snd_kcontrol_new lo1_mux =
698 SOC_DAPM_ENUM("Lineout1 Mux", lo1_enum); 698 SOC_DAPM_ENUM("Lineout1 Mux", lo1_enum);
699 699
700/* Lineout 2 Mux / Mux18 */ 700/* Lineout 2 Mux / Mux18 */
701static const struct soc_enum lo2_enum = 701static SOC_ENUM_SINGLE_DECL(lo2_enum,
702 SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 3, 2, in_text); 702 PM860X_ANA_TO_ANA, 3, in_text);
703 703
704static const struct snd_kcontrol_new lo2_mux = 704static const struct snd_kcontrol_new lo2_mux =
705 SOC_DAPM_ENUM("Lineout2 Mux", lo2_enum); 705 SOC_DAPM_ENUM("Lineout2 Mux", lo2_enum);
@@ -709,8 +709,8 @@ static const char *spk_text[] = {
709 "Earpiece", "Speaker", 709 "Earpiece", "Speaker",
710}; 710};
711 711
712static const struct soc_enum spk_enum = 712static SOC_ENUM_SINGLE_DECL(spk_enum,
713 SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 6, 2, spk_text); 713 PM860X_ANA_TO_ANA, 6, spk_text);
714 714
715static const struct snd_kcontrol_new spk_demux = 715static const struct snd_kcontrol_new spk_demux =
716 SOC_DAPM_ENUM("Speaker Earpiece Demux", spk_enum); 716 SOC_DAPM_ENUM("Speaker Earpiece Demux", spk_enum);
@@ -720,8 +720,8 @@ static const char *mic_text[] = {
720 "Mic 1", "Mic 2", 720 "Mic 1", "Mic 2",
721}; 721};
722 722
723static const struct soc_enum mic_enum = 723static SOC_ENUM_SINGLE_DECL(mic_enum,
724 SOC_ENUM_SINGLE(PM860X_ADC_ANA_4, 4, 2, mic_text); 724 PM860X_ADC_ANA_4, 4, mic_text);
725 725
726static const struct snd_kcontrol_new mic_mux = 726static const struct snd_kcontrol_new mic_mux =
727 SOC_DAPM_ENUM("MIC Mux", mic_enum); 727 SOC_DAPM_ENUM("MIC Mux", mic_enum);
@@ -1328,6 +1328,9 @@ static int pm860x_probe(struct snd_soc_codec *codec)
1328 pm860x->codec = codec; 1328 pm860x->codec = codec;
1329 1329
1330 codec->control_data = pm860x->regmap; 1330 codec->control_data = pm860x->regmap;
1331 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
1332 if (ret)
1333 return ret;
1331 1334
1332 for (i = 0; i < 4; i++) { 1335 for (i = 0; i < 4; i++) {
1333 ret = request_threaded_irq(pm860x->irq[i], NULL, 1336 ret = request_threaded_irq(pm860x->irq[i], NULL,
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 983d087aa92a..cf7f169adb12 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -8,6 +8,8 @@ config SND_SOC_I2C_AND_SPI
8 default y if I2C=y 8 default y if I2C=y
9 default y if SPI_MASTER=y 9 default y if SPI_MASTER=y
10 10
11menu "CODEC drivers"
12
11config SND_SOC_ALL_CODECS 13config SND_SOC_ALL_CODECS
12 tristate "Build all ASoC CODEC drivers" 14 tristate "Build all ASoC CODEC drivers"
13 depends on COMPILE_TEST 15 depends on COMPILE_TEST
@@ -16,15 +18,20 @@ config SND_SOC_ALL_CODECS
16 select SND_SOC_AB8500_CODEC if ABX500_CORE 18 select SND_SOC_AB8500_CODEC if ABX500_CORE
17 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS 19 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
18 select SND_SOC_AD1836 if SPI_MASTER 20 select SND_SOC_AD1836 if SPI_MASTER
19 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 21 select SND_SOC_AD193X_SPI if SPI_MASTER
22 select SND_SOC_AD193X_I2C if I2C
20 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 23 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
21 select SND_SOC_AD73311 24 select SND_SOC_AD73311
22 select SND_SOC_ADAU1373 if I2C 25 select SND_SOC_ADAU1373 if I2C
23 select SND_SOC_ADAV80X if SND_SOC_I2C_AND_SPI 26 select SND_SOC_ADAV801 if SPI_MASTER
27 select SND_SOC_ADAV803 if I2C
28 select SND_SOC_ADAU1977_SPI if SPI_MASTER
29 select SND_SOC_ADAU1977_I2C if I2C
24 select SND_SOC_ADAU1701 if I2C 30 select SND_SOC_ADAU1701 if I2C
25 select SND_SOC_ADS117X 31 select SND_SOC_ADS117X
26 select SND_SOC_AK4104 if SPI_MASTER 32 select SND_SOC_AK4104 if SPI_MASTER
27 select SND_SOC_AK4535 if I2C 33 select SND_SOC_AK4535 if I2C
34 select SND_SOC_AK4554
28 select SND_SOC_AK4641 if I2C 35 select SND_SOC_AK4641 if I2C
29 select SND_SOC_AK4642 if I2C 36 select SND_SOC_AK4642 if I2C
30 select SND_SOC_AK4671 if I2C 37 select SND_SOC_AK4671 if I2C
@@ -59,6 +66,8 @@ config SND_SOC_ALL_CODECS
59 select SND_SOC_PCM1681 if I2C 66 select SND_SOC_PCM1681 if I2C
60 select SND_SOC_PCM1792A if SPI_MASTER 67 select SND_SOC_PCM1792A if SPI_MASTER
61 select SND_SOC_PCM3008 68 select SND_SOC_PCM3008
69 select SND_SOC_PCM512x_I2C if I2C
70 select SND_SOC_PCM512x_SPI if SPI_MASTER
62 select SND_SOC_RT5631 if I2C 71 select SND_SOC_RT5631 if I2C
63 select SND_SOC_RT5640 if I2C 72 select SND_SOC_RT5640 if I2C
64 select SND_SOC_SGTL5000 if I2C 73 select SND_SOC_SGTL5000 if I2C
@@ -71,7 +80,8 @@ config SND_SOC_ALL_CODECS
71 select SND_SOC_STA529 if I2C 80 select SND_SOC_STA529 if I2C
72 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 81 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
73 select SND_SOC_TAS5086 if I2C 82 select SND_SOC_TAS5086 if I2C
74 select SND_SOC_TLV320AIC23 if I2C 83 select SND_SOC_TLV320AIC23_I2C if I2C
84 select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
75 select SND_SOC_TLV320AIC26 if SPI_MASTER 85 select SND_SOC_TLV320AIC26 if SPI_MASTER
76 select SND_SOC_TLV320AIC32X4 if I2C 86 select SND_SOC_TLV320AIC32X4 if I2C
77 select SND_SOC_TLV320AIC3X if I2C 87 select SND_SOC_TLV320AIC3X if I2C
@@ -182,6 +192,14 @@ config SND_SOC_AD1836
182config SND_SOC_AD193X 192config SND_SOC_AD193X
183 tristate 193 tristate
184 194
195config SND_SOC_AD193X_SPI
196 tristate
197 select SND_SOC_AD193X
198
199config SND_SOC_AD193X_I2C
200 tristate
201 select SND_SOC_AD193X
202
185config SND_SOC_AD1980 203config SND_SOC_AD1980
186 tristate 204 tristate
187 205
@@ -189,41 +207,66 @@ config SND_SOC_AD73311
189 tristate 207 tristate
190 208
191config SND_SOC_ADAU1701 209config SND_SOC_ADAU1701
210 tristate "Analog Devices ADAU1701 CODEC"
211 depends on I2C
192 select SND_SOC_SIGMADSP 212 select SND_SOC_SIGMADSP
193 tristate
194 213
195config SND_SOC_ADAU1373 214config SND_SOC_ADAU1373
196 tristate 215 tristate
197 216
217config SND_SOC_ADAU1977
218 tristate
219
220config SND_SOC_ADAU1977_SPI
221 tristate
222 select SND_SOC_ADAU1977
223 select REGMAP_SPI
224
225config SND_SOC_ADAU1977_I2C
226 tristate
227 select SND_SOC_ADAU1977
228 select REGMAP_I2C
229
198config SND_SOC_ADAV80X 230config SND_SOC_ADAV80X
199 tristate 231 tristate
200 232
233config SND_SOC_ADAV801
234 tristate
235 select SND_SOC_ADAV80X
236
237config SND_SOC_ADAV803
238 tristate
239 select SND_SOC_ADAV80X
240
201config SND_SOC_ADS117X 241config SND_SOC_ADS117X
202 tristate 242 tristate
203 243
204config SND_SOC_AK4104 244config SND_SOC_AK4104
205 tristate 245 tristate "AKM AK4104 CODEC"
246 depends on SPI_MASTER
206 247
207config SND_SOC_AK4535 248config SND_SOC_AK4535
208 tristate 249 tristate
209 250
210config SND_SOC_AK4554 251config SND_SOC_AK4554
211 tristate 252 tristate "AKM AK4554 CODEC"
212 253
213config SND_SOC_AK4641 254config SND_SOC_AK4641
214 tristate 255 tristate
215 256
216config SND_SOC_AK4642 257config SND_SOC_AK4642
217 tristate 258 tristate "AKM AK4642 CODEC"
259 depends on I2C
218 260
219config SND_SOC_AK4671 261config SND_SOC_AK4671
220 tristate 262 tristate
221 263
222config SND_SOC_AK5386 264config SND_SOC_AK5386
223 tristate 265 tristate "AKM AK5638 CODEC"
224 266
225config SND_SOC_ALC5623 267config SND_SOC_ALC5623
226 tristate 268 tristate
269
227config SND_SOC_ALC5632 270config SND_SOC_ALC5632
228 tristate 271 tristate
229 272
@@ -234,14 +277,17 @@ config SND_SOC_CS42L51
234 tristate 277 tristate
235 278
236config SND_SOC_CS42L52 279config SND_SOC_CS42L52
237 tristate 280 tristate "Cirrus Logic CS42L52 CODEC"
281 depends on I2C
238 282
239config SND_SOC_CS42L73 283config SND_SOC_CS42L73
240 tristate 284 tristate "Cirrus Logic CS42L73 CODEC"
285 depends on I2C
241 286
242# Cirrus Logic CS4270 Codec 287# Cirrus Logic CS4270 Codec
243config SND_SOC_CS4270 288config SND_SOC_CS4270
244 tristate 289 tristate "Cirrus Logic CS4270 CODEC"
290 depends on I2C
245 291
246# Cirrus Logic CS4270 Codec VD = 3.3V Errata 292# Cirrus Logic CS4270 Codec VD = 3.3V Errata
247# Select if you are affected by the errata where the part will not function 293# Select if you are affected by the errata where the part will not function
@@ -252,7 +298,8 @@ config SND_SOC_CS4270_VD33_ERRATA
252 depends on SND_SOC_CS4270 298 depends on SND_SOC_CS4270
253 299
254config SND_SOC_CS4271 300config SND_SOC_CS4271
255 tristate 301 tristate "Cirrus Logic CS4271 CODEC"
302 depends on SND_SOC_I2C_AND_SPI
256 303
257config SND_SOC_CX20442 304config SND_SOC_CX20442
258 tristate 305 tristate
@@ -283,6 +330,9 @@ config SND_SOC_BT_SCO
283config SND_SOC_DMIC 330config SND_SOC_DMIC
284 tristate 331 tristate
285 332
333config SND_SOC_HDMI_CODEC
334 tristate "HDMI stub CODEC"
335
286config SND_SOC_ISABELLE 336config SND_SOC_ISABELLE
287 tristate 337 tristate
288 338
@@ -301,18 +351,32 @@ config SND_SOC_MAX98095
301config SND_SOC_MAX9850 351config SND_SOC_MAX9850
302 tristate 352 tristate
303 353
304config SND_SOC_HDMI_CODEC
305 tristate
306
307config SND_SOC_PCM1681 354config SND_SOC_PCM1681
308 tristate 355 tristate "Texas Instruments PCM1681 CODEC"
356 depends on I2C
309 357
310config SND_SOC_PCM1792A 358config SND_SOC_PCM1792A
311 tristate 359 tristate "Texas Instruments PCM1792A CODEC"
360 depends on SPI_MASTER
312 361
313config SND_SOC_PCM3008 362config SND_SOC_PCM3008
314 tristate 363 tristate
315 364
365config SND_SOC_PCM512x
366 tristate
367
368config SND_SOC_PCM512x_I2C
369 tristate "Texas Instruments PCM512x CODECs - I2C"
370 depends on I2C
371 select SND_SOC_PCM512x
372 select REGMAP_I2C
373
374config SND_SOC_PCM512x_SPI
375 tristate "Texas Instruments PCM512x CODECs - SPI"
376 depends on SPI_MASTER
377 select SND_SOC_PCM512x
378 select REGMAP_SPI
379
316config SND_SOC_RT5631 380config SND_SOC_RT5631
317 tristate 381 tristate
318 382
@@ -321,7 +385,8 @@ config SND_SOC_RT5640
321 385
322#Freescale sgtl5000 codec 386#Freescale sgtl5000 codec
323config SND_SOC_SGTL5000 387config SND_SOC_SGTL5000
324 tristate 388 tristate "Freescale SGTL5000 CODEC"
389 depends on I2C
325 390
326config SND_SOC_SI476X 391config SND_SOC_SI476X
327 tristate 392 tristate
@@ -334,7 +399,7 @@ config SND_SOC_SN95031
334 tristate 399 tristate
335 400
336config SND_SOC_SPDIF 401config SND_SOC_SPDIF
337 tristate 402 tristate "S/PDIF CODEC"
338 403
339config SND_SOC_SSM2518 404config SND_SOC_SSM2518
340 tristate 405 tristate
@@ -352,11 +417,20 @@ config SND_SOC_STAC9766
352 tristate 417 tristate
353 418
354config SND_SOC_TAS5086 419config SND_SOC_TAS5086
355 tristate 420 tristate "Texas Instruments TAS5086 speaker amplifier"
421 depends on I2C
356 422
357config SND_SOC_TLV320AIC23 423config SND_SOC_TLV320AIC23
358 tristate 424 tristate
359 425
426config SND_SOC_TLV320AIC23_I2C
427 tristate
428 select SND_SOC_TLV320AIC23
429
430config SND_SOC_TLV320AIC23_SPI
431 tristate
432 select SND_SOC_TLV320AIC23
433
360config SND_SOC_TLV320AIC26 434config SND_SOC_TLV320AIC26
361 tristate 435 tristate
362 depends on SPI 436 depends on SPI
@@ -365,7 +439,8 @@ config SND_SOC_TLV320AIC32X4
365 tristate 439 tristate
366 440
367config SND_SOC_TLV320AIC3X 441config SND_SOC_TLV320AIC3X
368 tristate 442 tristate "Texas Instruments TLV320AIC3x CODECs"
443 depends on I2C
369 444
370config SND_SOC_TLV320DAC33 445config SND_SOC_TLV320DAC33
371 tristate 446 tristate
@@ -414,55 +489,69 @@ config SND_SOC_WM8400
414 tristate 489 tristate
415 490
416config SND_SOC_WM8510 491config SND_SOC_WM8510
417 tristate 492 tristate "Wolfson Microelectronics WM8510 CODEC"
493 depends on SND_SOC_I2C_AND_SPI
418 494
419config SND_SOC_WM8523 495config SND_SOC_WM8523
420 tristate 496 tristate "Wolfson Microelectronics WM8523 DAC"
497 depends on I2C
421 498
422config SND_SOC_WM8580 499config SND_SOC_WM8580
423 tristate 500 tristate "Wolfson Microelectronics WM8523 CODEC"
501 depends on I2C
424 502
425config SND_SOC_WM8711 503config SND_SOC_WM8711
426 tristate 504 tristate "Wolfson Microelectronics WM8711 CODEC"
505 depends on SND_SOC_I2C_AND_SPI
427 506
428config SND_SOC_WM8727 507config SND_SOC_WM8727
429 tristate 508 tristate
430 509
431config SND_SOC_WM8728 510config SND_SOC_WM8728
432 tristate 511 tristate "Wolfson Microelectronics WM8728 DAC"
512 depends on SND_SOC_I2C_AND_SPI
433 513
434config SND_SOC_WM8731 514config SND_SOC_WM8731
435 tristate 515 tristate "Wolfson Microelectronics WM8731 CODEC"
516 depends on SND_SOC_I2C_AND_SPI
436 517
437config SND_SOC_WM8737 518config SND_SOC_WM8737
438 tristate 519 tristate "Wolfson Microelectronics WM8737 ADC"
520 depends on SND_SOC_I2C_AND_SPI
439 521
440config SND_SOC_WM8741 522config SND_SOC_WM8741
441 tristate 523 tristate "Wolfson Microelectronics WM8737 DAC"
524 depends on SND_SOC_I2C_AND_SPI
442 525
443config SND_SOC_WM8750 526config SND_SOC_WM8750
444 tristate 527 tristate "Wolfson Microelectronics WM8750 CODEC"
528 depends on SND_SOC_I2C_AND_SPI
445 529
446config SND_SOC_WM8753 530config SND_SOC_WM8753
447 tristate 531 tristate "Wolfson Microelectronics WM8753 CODEC"
532 depends on SND_SOC_I2C_AND_SPI
448 533
449config SND_SOC_WM8770 534config SND_SOC_WM8770
450 tristate 535 tristate "Wolfson Microelectronics WM8770 CODEC"
536 depends on SPI_MASTER
451 537
452config SND_SOC_WM8776 538config SND_SOC_WM8776
453 tristate 539 tristate "Wolfson Microelectronics WM8776 CODEC"
540 depends on SND_SOC_I2C_AND_SPI
454 541
455config SND_SOC_WM8782 542config SND_SOC_WM8782
456 tristate 543 tristate
457 544
458config SND_SOC_WM8804 545config SND_SOC_WM8804
459 tristate 546 tristate "Wolfson Microelectronics WM8804 S/PDIF transceiver"
547 depends on SND_SOC_I2C_AND_SPI
460 548
461config SND_SOC_WM8900 549config SND_SOC_WM8900
462 tristate 550 tristate
463 551
464config SND_SOC_WM8903 552config SND_SOC_WM8903
465 tristate 553 tristate "Wolfson Microelectronics WM8903 CODEC"
554 depends on I2C
466 555
467config SND_SOC_WM8904 556config SND_SOC_WM8904
468 tristate 557 tristate
@@ -480,7 +569,8 @@ config SND_SOC_WM8961
480 tristate 569 tristate
481 570
482config SND_SOC_WM8962 571config SND_SOC_WM8962
483 tristate 572 tristate "Wolfson Microelectronics WM8962 CODEC"
573 depends on I2C
484 574
485config SND_SOC_WM8971 575config SND_SOC_WM8971
486 tristate 576 tristate
@@ -553,4 +643,7 @@ config SND_SOC_ML26124
553 tristate 643 tristate
554 644
555config SND_SOC_TPA6130A2 645config SND_SOC_TPA6130A2
556 tristate 646 tristate "Texas Instruments TPA6130A2 headphone amplifier"
647 depends on I2C
648
649endmenu
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index bc126764a44d..08540dae0090 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -3,11 +3,18 @@ snd-soc-ab8500-codec-objs := ab8500-codec.o
3snd-soc-ac97-objs := ac97.o 3snd-soc-ac97-objs := ac97.o
4snd-soc-ad1836-objs := ad1836.o 4snd-soc-ad1836-objs := ad1836.o
5snd-soc-ad193x-objs := ad193x.o 5snd-soc-ad193x-objs := ad193x.o
6snd-soc-ad193x-spi-objs := ad193x-spi.o
7snd-soc-ad193x-i2c-objs := ad193x-i2c.o
6snd-soc-ad1980-objs := ad1980.o 8snd-soc-ad1980-objs := ad1980.o
7snd-soc-ad73311-objs := ad73311.o 9snd-soc-ad73311-objs := ad73311.o
8snd-soc-adau1701-objs := adau1701.o 10snd-soc-adau1701-objs := adau1701.o
9snd-soc-adau1373-objs := adau1373.o 11snd-soc-adau1373-objs := adau1373.o
12snd-soc-adau1977-objs := adau1977.o
13snd-soc-adau1977-spi-objs := adau1977-spi.o
14snd-soc-adau1977-i2c-objs := adau1977-i2c.o
10snd-soc-adav80x-objs := adav80x.o 15snd-soc-adav80x-objs := adav80x.o
16snd-soc-adav801-objs := adav801.o
17snd-soc-adav803-objs := adav803.o
11snd-soc-ads117x-objs := ads117x.o 18snd-soc-ads117x-objs := ads117x.o
12snd-soc-ak4104-objs := ak4104.o 19snd-soc-ak4104-objs := ak4104.o
13snd-soc-ak4535-objs := ak4535.o 20snd-soc-ak4535-objs := ak4535.o
@@ -46,6 +53,9 @@ snd-soc-hdmi-codec-objs := hdmi.o
46snd-soc-pcm1681-objs := pcm1681.o 53snd-soc-pcm1681-objs := pcm1681.o
47snd-soc-pcm1792a-codec-objs := pcm1792a.o 54snd-soc-pcm1792a-codec-objs := pcm1792a.o
48snd-soc-pcm3008-objs := pcm3008.o 55snd-soc-pcm3008-objs := pcm3008.o
56snd-soc-pcm512x-objs := pcm512x.o
57snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
58snd-soc-pcm512x-spi-objs := pcm512x-spi.o
49snd-soc-rt5631-objs := rt5631.o 59snd-soc-rt5631-objs := rt5631.o
50snd-soc-rt5640-objs := rt5640.o 60snd-soc-rt5640-objs := rt5640.o
51snd-soc-sgtl5000-objs := sgtl5000.o 61snd-soc-sgtl5000-objs := sgtl5000.o
@@ -63,6 +73,8 @@ snd-soc-sta529-objs := sta529.o
63snd-soc-stac9766-objs := stac9766.o 73snd-soc-stac9766-objs := stac9766.o
64snd-soc-tas5086-objs := tas5086.o 74snd-soc-tas5086-objs := tas5086.o
65snd-soc-tlv320aic23-objs := tlv320aic23.o 75snd-soc-tlv320aic23-objs := tlv320aic23.o
76snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
77snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o
66snd-soc-tlv320aic26-objs := tlv320aic26.o 78snd-soc-tlv320aic26-objs := tlv320aic26.o
67snd-soc-tlv320aic3x-objs := tlv320aic3x.o 79snd-soc-tlv320aic3x-objs := tlv320aic3x.o
68snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o 80snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
@@ -134,11 +146,18 @@ obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o
134obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 146obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
135obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 147obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
136obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o 148obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
149obj-$(CONFIG_SND_SOC_AD193X_SPI) += snd-soc-ad193x-spi.o
150obj-$(CONFIG_SND_SOC_AD193X_I2C) += snd-soc-ad193x-i2c.o
137obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 151obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
138obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 152obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
139obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o 153obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o
154obj-$(CONFIG_SND_SOC_ADAU1977) += snd-soc-adau1977.o
155obj-$(CONFIG_SND_SOC_ADAU1977_SPI) += snd-soc-adau1977-spi.o
156obj-$(CONFIG_SND_SOC_ADAU1977_I2C) += snd-soc-adau1977-i2c.o
140obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o 157obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o
141obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o 158obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o
159obj-$(CONFIG_SND_SOC_ADAV801) += snd-soc-adav801.o
160obj-$(CONFIG_SND_SOC_ADAV803) += snd-soc-adav803.o
142obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 161obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
143obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 162obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
144obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 163obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
@@ -179,6 +198,9 @@ obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
179obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o 198obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
180obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o 199obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o
181obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 200obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
201obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o
202obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
203obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
182obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 204obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
183obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o 205obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
184obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 206obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
@@ -193,6 +215,8 @@ obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
193obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 215obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
194obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o 216obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
195obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 217obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
218obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
219obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
196obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 220obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
197obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 221obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
198obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o 222obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 77f459868579..685998dd086e 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -40,8 +40,8 @@ struct ad1836_priv {
40 */ 40 */
41static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"}; 41static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"};
42 42
43static const struct soc_enum ad1836_deemp_enum = 43static SOC_ENUM_SINGLE_DECL(ad1836_deemp_enum,
44 SOC_ENUM_SINGLE(AD1836_DAC_CTRL1, 8, 4, ad1836_deemp); 44 AD1836_DAC_CTRL1, 8, ad1836_deemp);
45 45
46#define AD1836_DAC_VOLUME(x) \ 46#define AD1836_DAC_VOLUME(x) \
47 SOC_DOUBLE_R("DAC" #x " Playback Volume", AD1836_DAC_L_VOL(x), \ 47 SOC_DOUBLE_R("DAC" #x " Playback Volume", AD1836_DAC_L_VOL(x), \
diff --git a/sound/soc/codecs/ad193x-i2c.c b/sound/soc/codecs/ad193x-i2c.c
new file mode 100644
index 000000000000..df3a1a415825
--- /dev/null
+++ b/sound/soc/codecs/ad193x-i2c.c
@@ -0,0 +1,54 @@
1/*
2 * AD1936/AD1937 audio driver
3 *
4 * Copyright 2014 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/module.h>
10#include <linux/i2c.h>
11#include <linux/regmap.h>
12
13#include <sound/soc.h>
14
15#include "ad193x.h"
16
17static const struct i2c_device_id ad193x_id[] = {
18 { "ad1936", 0 },
19 { "ad1937", 0 },
20 { }
21};
22MODULE_DEVICE_TABLE(i2c, ad193x_id);
23
24static int ad193x_i2c_probe(struct i2c_client *client,
25 const struct i2c_device_id *id)
26{
27 struct regmap_config config;
28
29 config = ad193x_regmap_config;
30 config.val_bits = 8;
31 config.reg_bits = 8;
32
33 return ad193x_probe(&client->dev, devm_regmap_init_i2c(client, &config));
34}
35
36static int ad193x_i2c_remove(struct i2c_client *client)
37{
38 snd_soc_unregister_codec(&client->dev);
39 return 0;
40}
41
42static struct i2c_driver ad193x_i2c_driver = {
43 .driver = {
44 .name = "ad193x",
45 },
46 .probe = ad193x_i2c_probe,
47 .remove = ad193x_i2c_remove,
48 .id_table = ad193x_id,
49};
50module_i2c_driver(ad193x_i2c_driver);
51
52MODULE_DESCRIPTION("ASoC AD1936/AD1937 audio CODEC driver");
53MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
54MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad193x-spi.c b/sound/soc/codecs/ad193x-spi.c
new file mode 100644
index 000000000000..390cef9b9dc2
--- /dev/null
+++ b/sound/soc/codecs/ad193x-spi.c
@@ -0,0 +1,48 @@
1/*
2 * AD1938/AD1939 audio driver
3 *
4 * Copyright 2014 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/module.h>
10#include <linux/spi/spi.h>
11#include <linux/regmap.h>
12
13#include <sound/soc.h>
14
15#include "ad193x.h"
16
17static int ad193x_spi_probe(struct spi_device *spi)
18{
19 struct regmap_config config;
20
21 config = ad193x_regmap_config;
22 config.val_bits = 8;
23 config.reg_bits = 16;
24 config.read_flag_mask = 0x09;
25 config.write_flag_mask = 0x08;
26
27 return ad193x_probe(&spi->dev, devm_regmap_init_spi(spi, &config));
28}
29
30static int ad193x_spi_remove(struct spi_device *spi)
31{
32 snd_soc_unregister_codec(&spi->dev);
33 return 0;
34}
35
36static struct spi_driver ad193x_spi_driver = {
37 .driver = {
38 .name = "ad193x",
39 .owner = THIS_MODULE,
40 },
41 .probe = ad193x_spi_probe,
42 .remove = ad193x_spi_remove,
43};
44module_spi_driver(ad193x_spi_driver);
45
46MODULE_DESCRIPTION("ASoC AD1938/AD1939 audio CODEC driver");
47MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
48MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 5a42dca535b7..9381a767e75f 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -6,12 +6,10 @@
6 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
7 */ 7 */
8 8
9#include <linux/init.h>
10#include <linux/module.h> 9#include <linux/module.h>
11#include <linux/kernel.h> 10#include <linux/kernel.h>
12#include <linux/device.h> 11#include <linux/device.h>
13#include <linux/i2c.h> 12#include <linux/regmap.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h> 13#include <linux/slab.h>
16#include <sound/core.h> 14#include <sound/core.h>
17#include <sound/pcm.h> 15#include <sound/pcm.h>
@@ -19,6 +17,7 @@
19#include <sound/initval.h> 17#include <sound/initval.h>
20#include <sound/soc.h> 18#include <sound/soc.h>
21#include <sound/tlv.h> 19#include <sound/tlv.h>
20
22#include "ad193x.h" 21#include "ad193x.h"
23 22
24/* codec private data */ 23/* codec private data */
@@ -32,8 +31,8 @@ struct ad193x_priv {
32 */ 31 */
33static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; 32static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
34 33
35static const struct soc_enum ad193x_deemp_enum = 34static SOC_ENUM_SINGLE_DECL(ad193x_deemp_enum, AD193X_DAC_CTRL2, 1,
36 SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp); 35 ad193x_deemp);
37 36
38static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0); 37static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
39 38
@@ -320,7 +319,7 @@ static struct snd_soc_dai_driver ad193x_dai = {
320 .ops = &ad193x_dai_ops, 319 .ops = &ad193x_dai_ops,
321}; 320};
322 321
323static int ad193x_probe(struct snd_soc_codec *codec) 322static int ad193x_codec_probe(struct snd_soc_codec *codec)
324{ 323{
325 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 324 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
326 int ret; 325 int ret;
@@ -352,7 +351,7 @@ static int ad193x_probe(struct snd_soc_codec *codec)
352} 351}
353 352
354static struct snd_soc_codec_driver soc_codec_dev_ad193x = { 353static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
355 .probe = ad193x_probe, 354 .probe = ad193x_codec_probe,
356 .controls = ad193x_snd_controls, 355 .controls = ad193x_snd_controls,
357 .num_controls = ARRAY_SIZE(ad193x_snd_controls), 356 .num_controls = ARRAY_SIZE(ad193x_snd_controls),
358 .dapm_widgets = ad193x_dapm_widgets, 357 .dapm_widgets = ad193x_dapm_widgets,
@@ -366,140 +365,31 @@ static bool adau193x_reg_volatile(struct device *dev, unsigned int reg)
366 return false; 365 return false;
367} 366}
368 367
369#if defined(CONFIG_SPI_MASTER) 368const struct regmap_config ad193x_regmap_config = {
370
371static const struct regmap_config ad193x_spi_regmap_config = {
372 .val_bits = 8,
373 .reg_bits = 16,
374 .read_flag_mask = 0x09,
375 .write_flag_mask = 0x08,
376
377 .max_register = AD193X_NUM_REGS - 1, 369 .max_register = AD193X_NUM_REGS - 1,
378 .volatile_reg = adau193x_reg_volatile, 370 .volatile_reg = adau193x_reg_volatile,
379}; 371};
372EXPORT_SYMBOL_GPL(ad193x_regmap_config);
380 373
381static int ad193x_spi_probe(struct spi_device *spi) 374int ad193x_probe(struct device *dev, struct regmap *regmap)
382{ 375{
383 struct ad193x_priv *ad193x; 376 struct ad193x_priv *ad193x;
384 377
385 ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv), 378 if (IS_ERR(regmap))
386 GFP_KERNEL); 379 return PTR_ERR(regmap);
387 if (ad193x == NULL)
388 return -ENOMEM;
389
390 ad193x->regmap = devm_regmap_init_spi(spi, &ad193x_spi_regmap_config);
391 if (IS_ERR(ad193x->regmap))
392 return PTR_ERR(ad193x->regmap);
393
394 spi_set_drvdata(spi, ad193x);
395
396 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_ad193x,
397 &ad193x_dai, 1);
398}
399
400static int ad193x_spi_remove(struct spi_device *spi)
401{
402 snd_soc_unregister_codec(&spi->dev);
403 return 0;
404}
405
406static struct spi_driver ad193x_spi_driver = {
407 .driver = {
408 .name = "ad193x",
409 .owner = THIS_MODULE,
410 },
411 .probe = ad193x_spi_probe,
412 .remove = ad193x_spi_remove,
413};
414#endif
415
416#if IS_ENABLED(CONFIG_I2C)
417
418static const struct regmap_config ad193x_i2c_regmap_config = {
419 .val_bits = 8,
420 .reg_bits = 8,
421
422 .max_register = AD193X_NUM_REGS - 1,
423 .volatile_reg = adau193x_reg_volatile,
424};
425
426static const struct i2c_device_id ad193x_id[] = {
427 { "ad1936", 0 },
428 { "ad1937", 0 },
429 { }
430};
431MODULE_DEVICE_TABLE(i2c, ad193x_id);
432 380
433static int ad193x_i2c_probe(struct i2c_client *client, 381 ad193x = devm_kzalloc(dev, sizeof(*ad193x), GFP_KERNEL);
434 const struct i2c_device_id *id)
435{
436 struct ad193x_priv *ad193x;
437
438 ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv),
439 GFP_KERNEL);
440 if (ad193x == NULL) 382 if (ad193x == NULL)
441 return -ENOMEM; 383 return -ENOMEM;
442 384
443 ad193x->regmap = devm_regmap_init_i2c(client, &ad193x_i2c_regmap_config); 385 ad193x->regmap = regmap;
444 if (IS_ERR(ad193x->regmap))
445 return PTR_ERR(ad193x->regmap);
446
447 i2c_set_clientdata(client, ad193x);
448
449 return snd_soc_register_codec(&client->dev, &soc_codec_dev_ad193x,
450 &ad193x_dai, 1);
451}
452
453static int ad193x_i2c_remove(struct i2c_client *client)
454{
455 snd_soc_unregister_codec(&client->dev);
456 return 0;
457}
458 386
459static struct i2c_driver ad193x_i2c_driver = { 387 dev_set_drvdata(dev, ad193x);
460 .driver = {
461 .name = "ad193x",
462 },
463 .probe = ad193x_i2c_probe,
464 .remove = ad193x_i2c_remove,
465 .id_table = ad193x_id,
466};
467#endif
468
469static int __init ad193x_modinit(void)
470{
471 int ret;
472
473#if IS_ENABLED(CONFIG_I2C)
474 ret = i2c_add_driver(&ad193x_i2c_driver);
475 if (ret != 0) {
476 printk(KERN_ERR "Failed to register AD193X I2C driver: %d\n",
477 ret);
478 }
479#endif
480
481#if defined(CONFIG_SPI_MASTER)
482 ret = spi_register_driver(&ad193x_spi_driver);
483 if (ret != 0) {
484 printk(KERN_ERR "Failed to register AD193X SPI driver: %d\n",
485 ret);
486 }
487#endif
488 return ret;
489}
490module_init(ad193x_modinit);
491
492static void __exit ad193x_modexit(void)
493{
494#if defined(CONFIG_SPI_MASTER)
495 spi_unregister_driver(&ad193x_spi_driver);
496#endif
497 388
498#if IS_ENABLED(CONFIG_I2C) 389 return snd_soc_register_codec(dev, &soc_codec_dev_ad193x,
499 i2c_del_driver(&ad193x_i2c_driver); 390 &ad193x_dai, 1);
500#endif
501} 391}
502module_exit(ad193x_modexit); 392EXPORT_SYMBOL_GPL(ad193x_probe);
503 393
504MODULE_DESCRIPTION("ASoC ad193x driver"); 394MODULE_DESCRIPTION("ASoC ad193x driver");
505MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 395MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index 473388049992..ab9a998f15be 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -9,6 +9,13 @@
9#ifndef __AD193X_H__ 9#ifndef __AD193X_H__
10#define __AD193X_H__ 10#define __AD193X_H__
11 11
12#include <linux/regmap.h>
13
14struct device;
15
16extern const struct regmap_config ad193x_regmap_config;
17int ad193x_probe(struct device *dev, struct regmap *regmap);
18
12#define AD193X_PLL_CLK_CTRL0 0x00 19#define AD193X_PLL_CLK_CTRL0 0x00
13#define AD193X_PLL_POWERDOWN 0x01 20#define AD193X_PLL_POWERDOWN 0x01
14#define AD193X_PLL_INPUT_MASK 0x6 21#define AD193X_PLL_INPUT_MASK 0x6
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 7257a8885f42..34d965a4a040 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -57,8 +57,8 @@ static const u16 ad1980_reg[] = {
57static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line", 57static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line",
58 "Stereo Mix", "Mono Mix", "Phone"}; 58 "Stereo Mix", "Mono Mix", "Phone"};
59 59
60static const struct soc_enum ad1980_cap_src = 60static SOC_ENUM_DOUBLE_DECL(ad1980_cap_src,
61 SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 7, ad1980_rec_sel); 61 AC97_REC_SEL, 8, 0, ad1980_rec_sel);
62 62
63static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = { 63static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = {
64SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1), 64SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1),
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index eb836ed5271f..5223800775ad 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -345,15 +345,15 @@ static const char *adau1373_fdsp_sel_text[] = {
345 "Channel 5", 345 "Channel 5",
346}; 346};
347 347
348static const SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum, 348static SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum,
349 ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text); 349 ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text);
350static const SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum, 350static SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum,
351 ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text); 351 ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text);
352static const SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum, 352static SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum,
353 ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text); 353 ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text);
354static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum, 354static SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum,
355 ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text); 355 ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text);
356static const SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum, 356static SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum,
357 ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text); 357 ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text);
358 358
359static const char *adau1373_hpf_cutoff_text[] = { 359static const char *adau1373_hpf_cutoff_text[] = {
@@ -362,7 +362,7 @@ static const char *adau1373_hpf_cutoff_text[] = {
362 "800Hz", 362 "800Hz",
363}; 363};
364 364
365static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum, 365static SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum,
366 ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text); 366 ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text);
367 367
368static const char *adau1373_bass_lpf_cutoff_text[] = { 368static const char *adau1373_bass_lpf_cutoff_text[] = {
@@ -388,14 +388,14 @@ static const unsigned int adau1373_bass_tlv[] = {
388 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0), 388 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0),
389}; 389};
390 390
391static const SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum, 391static SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum,
392 ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text); 392 ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text);
393 393
394static const SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum, 394static SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum,
395 ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text, 395 ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text,
396 adau1373_bass_clip_level_values); 396 adau1373_bass_clip_level_values);
397 397
398static const SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum, 398static SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum,
399 ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text); 399 ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text);
400 400
401static const char *adau1373_3d_level_text[] = { 401static const char *adau1373_3d_level_text[] = {
@@ -409,9 +409,9 @@ static const char *adau1373_3d_cutoff_text[] = {
409 "0.16875 fs", "0.27083 fs" 409 "0.16875 fs", "0.27083 fs"
410}; 410};
411 411
412static const SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum, 412static SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum,
413 ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text); 413 ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text);
414static const SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum, 414static SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum,
415 ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text); 415 ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text);
416 416
417static const unsigned int adau1373_3d_tlv[] = { 417static const unsigned int adau1373_3d_tlv[] = {
@@ -427,11 +427,11 @@ static const char *adau1373_lr_mux_text[] = {
427 "Stereo", 427 "Stereo",
428}; 428};
429 429
430static const SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum, 430static SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum,
431 ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text); 431 ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text);
432static const SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum, 432static SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum,
433 ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text); 433 ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text);
434static const SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum, 434static SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum,
435 ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text); 435 ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text);
436 436
437static const struct snd_kcontrol_new adau1373_controls[] = { 437static const struct snd_kcontrol_new adau1373_controls[] = {
@@ -576,8 +576,8 @@ static const char *adau1373_decimator_text[] = {
576 "DMIC1", 576 "DMIC1",
577}; 577};
578 578
579static const struct soc_enum adau1373_decimator_enum = 579static SOC_ENUM_SINGLE_VIRT_DECL(adau1373_decimator_enum,
580 SOC_ENUM_SINGLE(0, 0, 2, adau1373_decimator_text); 580 adau1373_decimator_text);
581 581
582static const struct snd_kcontrol_new adau1373_decimator_mux = 582static const struct snd_kcontrol_new adau1373_decimator_mux =
583 SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum); 583 SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum);
diff --git a/sound/soc/codecs/adau1977-i2c.c b/sound/soc/codecs/adau1977-i2c.c
new file mode 100644
index 000000000000..9700e8c838c9
--- /dev/null
+++ b/sound/soc/codecs/adau1977-i2c.c
@@ -0,0 +1,59 @@
1/*
2 * ADAU1977/ADAU1978/ADAU1979 driver
3 *
4 * Copyright 2014 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2.
8 */
9
10#include <linux/i2c.h>
11#include <linux/mod_devicetable.h>
12#include <linux/module.h>
13#include <linux/regmap.h>
14#include <sound/soc.h>
15
16#include "adau1977.h"
17
18static int adau1977_i2c_probe(struct i2c_client *client,
19 const struct i2c_device_id *id)
20{
21 struct regmap_config config;
22
23 config = adau1977_regmap_config;
24 config.val_bits = 8;
25 config.reg_bits = 8;
26
27 return adau1977_probe(&client->dev,
28 devm_regmap_init_i2c(client, &config),
29 id->driver_data, NULL);
30}
31
32static int adau1977_i2c_remove(struct i2c_client *client)
33{
34 snd_soc_unregister_codec(&client->dev);
35 return 0;
36}
37
38static const struct i2c_device_id adau1977_i2c_ids[] = {
39 { "adau1977", ADAU1977 },
40 { "adau1978", ADAU1978 },
41 { "adau1979", ADAU1978 },
42 { }
43};
44MODULE_DEVICE_TABLE(i2c, adau1977_i2c_ids);
45
46static struct i2c_driver adau1977_i2c_driver = {
47 .driver = {
48 .name = "adau1977",
49 .owner = THIS_MODULE,
50 },
51 .probe = adau1977_i2c_probe,
52 .remove = adau1977_i2c_remove,
53 .id_table = adau1977_i2c_ids,
54};
55module_i2c_driver(adau1977_i2c_driver);
56
57MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver");
58MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
59MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adau1977-spi.c b/sound/soc/codecs/adau1977-spi.c
new file mode 100644
index 000000000000..b05cf5da3a94
--- /dev/null
+++ b/sound/soc/codecs/adau1977-spi.c
@@ -0,0 +1,76 @@
1/*
2 * ADAU1977/ADAU1978/ADAU1979 driver
3 *
4 * Copyright 2014 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2.
8 */
9
10#include <linux/mod_devicetable.h>
11#include <linux/module.h>
12#include <linux/regmap.h>
13#include <linux/spi/spi.h>
14#include <sound/soc.h>
15
16#include "adau1977.h"
17
18static void adau1977_spi_switch_mode(struct device *dev)
19{
20 struct spi_device *spi = to_spi_device(dev);
21
22 /*
23 * To get the device into SPI mode CLATCH has to be pulled low three
24 * times. Do this by issuing three dummy reads.
25 */
26 spi_w8r8(spi, 0x00);
27 spi_w8r8(spi, 0x00);
28 spi_w8r8(spi, 0x00);
29}
30
31static int adau1977_spi_probe(struct spi_device *spi)
32{
33 const struct spi_device_id *id = spi_get_device_id(spi);
34 struct regmap_config config;
35
36 if (!id)
37 return -EINVAL;
38
39 config = adau1977_regmap_config;
40 config.val_bits = 8;
41 config.reg_bits = 16;
42 config.read_flag_mask = 0x1;
43
44 return adau1977_probe(&spi->dev,
45 devm_regmap_init_spi(spi, &config),
46 id->driver_data, adau1977_spi_switch_mode);
47}
48
49static int adau1977_spi_remove(struct spi_device *spi)
50{
51 snd_soc_unregister_codec(&spi->dev);
52 return 0;
53}
54
55static const struct spi_device_id adau1977_spi_ids[] = {
56 { "adau1977", ADAU1977 },
57 { "adau1978", ADAU1978 },
58 { "adau1979", ADAU1978 },
59 { }
60};
61MODULE_DEVICE_TABLE(spi, adau1977_spi_ids);
62
63static struct spi_driver adau1977_spi_driver = {
64 .driver = {
65 .name = "adau1977",
66 .owner = THIS_MODULE,
67 },
68 .probe = adau1977_spi_probe,
69 .remove = adau1977_spi_remove,
70 .id_table = adau1977_spi_ids,
71};
72module_spi_driver(adau1977_spi_driver);
73
74MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver");
75MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
76MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c
new file mode 100644
index 000000000000..fd55da7cb9d4
--- /dev/null
+++ b/sound/soc/codecs/adau1977.c
@@ -0,0 +1,1018 @@
1/*
2 * ADAU1977/ADAU1978/ADAU1979 driver
3 *
4 * Copyright 2014 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2.
8 */
9
10#include <linux/delay.h>
11#include <linux/device.h>
12#include <linux/gpio/consumer.h>
13#include <linux/i2c.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/platform_data/adau1977.h>
17#include <linux/regmap.h>
18#include <linux/regulator/consumer.h>
19#include <linux/slab.h>
20
21#include <sound/core.h>
22#include <sound/initval.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/tlv.h>
27
28#include "adau1977.h"
29
30#define ADAU1977_REG_POWER 0x00
31#define ADAU1977_REG_PLL 0x01
32#define ADAU1977_REG_BOOST 0x02
33#define ADAU1977_REG_MICBIAS 0x03
34#define ADAU1977_REG_BLOCK_POWER_SAI 0x04
35#define ADAU1977_REG_SAI_CTRL0 0x05
36#define ADAU1977_REG_SAI_CTRL1 0x06
37#define ADAU1977_REG_CMAP12 0x07
38#define ADAU1977_REG_CMAP34 0x08
39#define ADAU1977_REG_SAI_OVERTEMP 0x09
40#define ADAU1977_REG_POST_ADC_GAIN(x) (0x0a + (x))
41#define ADAU1977_REG_MISC_CONTROL 0x0e
42#define ADAU1977_REG_DIAG_CONTROL 0x10
43#define ADAU1977_REG_STATUS(x) (0x11 + (x))
44#define ADAU1977_REG_DIAG_IRQ1 0x15
45#define ADAU1977_REG_DIAG_IRQ2 0x16
46#define ADAU1977_REG_ADJUST1 0x17
47#define ADAU1977_REG_ADJUST2 0x18
48#define ADAU1977_REG_ADC_CLIP 0x19
49#define ADAU1977_REG_DC_HPF_CAL 0x1a
50
51#define ADAU1977_POWER_RESET BIT(7)
52#define ADAU1977_POWER_PWUP BIT(0)
53
54#define ADAU1977_PLL_CLK_S BIT(4)
55#define ADAU1977_PLL_MCS_MASK 0x7
56
57#define ADAU1977_MICBIAS_MB_VOLTS_MASK 0xf0
58#define ADAU1977_MICBIAS_MB_VOLTS_OFFSET 4
59
60#define ADAU1977_BLOCK_POWER_SAI_LR_POL BIT(7)
61#define ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE BIT(6)
62#define ADAU1977_BLOCK_POWER_SAI_LDO_EN BIT(5)
63
64#define ADAU1977_SAI_CTRL0_FMT_MASK (0x3 << 6)
65#define ADAU1977_SAI_CTRL0_FMT_I2S (0x0 << 6)
66#define ADAU1977_SAI_CTRL0_FMT_LJ (0x1 << 6)
67#define ADAU1977_SAI_CTRL0_FMT_RJ_24BIT (0x2 << 6)
68#define ADAU1977_SAI_CTRL0_FMT_RJ_16BIT (0x3 << 6)
69
70#define ADAU1977_SAI_CTRL0_SAI_MASK (0x7 << 3)
71#define ADAU1977_SAI_CTRL0_SAI_I2S (0x0 << 3)
72#define ADAU1977_SAI_CTRL0_SAI_TDM_2 (0x1 << 3)
73#define ADAU1977_SAI_CTRL0_SAI_TDM_4 (0x2 << 3)
74#define ADAU1977_SAI_CTRL0_SAI_TDM_8 (0x3 << 3)
75#define ADAU1977_SAI_CTRL0_SAI_TDM_16 (0x4 << 3)
76
77#define ADAU1977_SAI_CTRL0_FS_MASK (0x7)
78#define ADAU1977_SAI_CTRL0_FS_8000_12000 (0x0)
79#define ADAU1977_SAI_CTRL0_FS_16000_24000 (0x1)
80#define ADAU1977_SAI_CTRL0_FS_32000_48000 (0x2)
81#define ADAU1977_SAI_CTRL0_FS_64000_96000 (0x3)
82#define ADAU1977_SAI_CTRL0_FS_128000_192000 (0x4)
83
84#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK (0x3 << 5)
85#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_32 (0x0 << 5)
86#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_24 (0x1 << 5)
87#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_16 (0x2 << 5)
88#define ADAU1977_SAI_CTRL1_DATA_WIDTH_MASK (0x1 << 4)
89#define ADAU1977_SAI_CTRL1_DATA_WIDTH_16BIT (0x1 << 4)
90#define ADAU1977_SAI_CTRL1_DATA_WIDTH_24BIT (0x0 << 4)
91#define ADAU1977_SAI_CTRL1_LRCLK_PULSE BIT(3)
92#define ADAU1977_SAI_CTRL1_MSB BIT(2)
93#define ADAU1977_SAI_CTRL1_BCLKRATE_16 (0x1 << 1)
94#define ADAU1977_SAI_CTRL1_BCLKRATE_32 (0x0 << 1)
95#define ADAU1977_SAI_CTRL1_BCLKRATE_MASK (0x1 << 1)
96#define ADAU1977_SAI_CTRL1_MASTER BIT(0)
97
98#define ADAU1977_SAI_OVERTEMP_DRV_C(x) BIT(4 + (x))
99#define ADAU1977_SAI_OVERTEMP_DRV_HIZ BIT(3)
100
101#define ADAU1977_MISC_CONTROL_SUM_MODE_MASK (0x3 << 6)
102#define ADAU1977_MISC_CONTROL_SUM_MODE_1CH (0x2 << 6)
103#define ADAU1977_MISC_CONTROL_SUM_MODE_2CH (0x1 << 6)
104#define ADAU1977_MISC_CONTROL_SUM_MODE_4CH (0x0 << 6)
105#define ADAU1977_MISC_CONTROL_MMUTE BIT(4)
106#define ADAU1977_MISC_CONTROL_DC_CAL BIT(0)
107
108#define ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET 4
109#define ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET 0
110
111struct adau1977 {
112 struct regmap *regmap;
113 bool right_j;
114 unsigned int sysclk;
115 enum adau1977_sysclk_src sysclk_src;
116 struct gpio_desc *reset_gpio;
117 enum adau1977_type type;
118
119 struct regulator *avdd_reg;
120 struct regulator *dvdd_reg;
121
122 struct snd_pcm_hw_constraint_list constraints;
123
124 struct device *dev;
125 void (*switch_mode)(struct device *dev);
126
127 unsigned int max_master_fs;
128 unsigned int slot_width;
129 bool enabled;
130 bool master;
131};
132
133static const struct reg_default adau1977_reg_defaults[] = {
134 { 0x00, 0x00 },
135 { 0x01, 0x41 },
136 { 0x02, 0x4a },
137 { 0x03, 0x7d },
138 { 0x04, 0x3d },
139 { 0x05, 0x02 },
140 { 0x06, 0x00 },
141 { 0x07, 0x10 },
142 { 0x08, 0x32 },
143 { 0x09, 0xf0 },
144 { 0x0a, 0xa0 },
145 { 0x0b, 0xa0 },
146 { 0x0c, 0xa0 },
147 { 0x0d, 0xa0 },
148 { 0x0e, 0x02 },
149 { 0x10, 0x0f },
150 { 0x15, 0x20 },
151 { 0x16, 0x00 },
152 { 0x17, 0x00 },
153 { 0x18, 0x00 },
154 { 0x1a, 0x00 },
155};
156
157static const DECLARE_TLV_DB_MINMAX_MUTE(adau1977_adc_gain, -3562, 6000);
158
159static const struct snd_soc_dapm_widget adau1977_micbias_dapm_widgets[] = {
160 SND_SOC_DAPM_SUPPLY("MICBIAS", ADAU1977_REG_MICBIAS,
161 3, 0, NULL, 0)
162};
163
164static const struct snd_soc_dapm_widget adau1977_dapm_widgets[] = {
165 SND_SOC_DAPM_SUPPLY("Vref", ADAU1977_REG_BLOCK_POWER_SAI,
166 4, 0, NULL, 0),
167
168 SND_SOC_DAPM_ADC("ADC1", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 0, 0),
169 SND_SOC_DAPM_ADC("ADC2", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 1, 0),
170 SND_SOC_DAPM_ADC("ADC3", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 2, 0),
171 SND_SOC_DAPM_ADC("ADC4", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 3, 0),
172
173 SND_SOC_DAPM_INPUT("AIN1"),
174 SND_SOC_DAPM_INPUT("AIN2"),
175 SND_SOC_DAPM_INPUT("AIN3"),
176 SND_SOC_DAPM_INPUT("AIN4"),
177
178 SND_SOC_DAPM_OUTPUT("VREF"),
179};
180
181static const struct snd_soc_dapm_route adau1977_dapm_routes[] = {
182 { "ADC1", NULL, "AIN1" },
183 { "ADC2", NULL, "AIN2" },
184 { "ADC3", NULL, "AIN3" },
185 { "ADC4", NULL, "AIN4" },
186
187 { "ADC1", NULL, "Vref" },
188 { "ADC2", NULL, "Vref" },
189 { "ADC3", NULL, "Vref" },
190 { "ADC4", NULL, "Vref" },
191
192 { "VREF", NULL, "Vref" },
193};
194
195#define ADAU1977_VOLUME(x) \
196 SOC_SINGLE_TLV("ADC" #x " Capture Volume", \
197 ADAU1977_REG_POST_ADC_GAIN((x) - 1), \
198 0, 255, 1, adau1977_adc_gain)
199
200#define ADAU1977_HPF_SWITCH(x) \
201 SOC_SINGLE("ADC" #x " Highpass-Filter Capture Switch", \
202 ADAU1977_REG_DC_HPF_CAL, (x) - 1, 1, 0)
203
204#define ADAU1977_DC_SUB_SWITCH(x) \
205 SOC_SINGLE("ADC" #x " DC Substraction Capture Switch", \
206 ADAU1977_REG_DC_HPF_CAL, (x) + 3, 1, 0)
207
208static const struct snd_kcontrol_new adau1977_snd_controls[] = {
209 ADAU1977_VOLUME(1),
210 ADAU1977_VOLUME(2),
211 ADAU1977_VOLUME(3),
212 ADAU1977_VOLUME(4),
213
214 ADAU1977_HPF_SWITCH(1),
215 ADAU1977_HPF_SWITCH(2),
216 ADAU1977_HPF_SWITCH(3),
217 ADAU1977_HPF_SWITCH(4),
218
219 ADAU1977_DC_SUB_SWITCH(1),
220 ADAU1977_DC_SUB_SWITCH(2),
221 ADAU1977_DC_SUB_SWITCH(3),
222 ADAU1977_DC_SUB_SWITCH(4),
223};
224
225static int adau1977_reset(struct adau1977 *adau1977)
226{
227 int ret;
228
229 /*
230 * The reset bit is obviously volatile, but we need to be able to cache
231 * the other bits in the register, so we can't just mark the whole
232 * register as volatile. Since this is the only place where we'll ever
233 * touch the reset bit just bypass the cache for this operation.
234 */
235 regcache_cache_bypass(adau1977->regmap, true);
236 ret = regmap_write(adau1977->regmap, ADAU1977_REG_POWER,
237 ADAU1977_POWER_RESET);
238 regcache_cache_bypass(adau1977->regmap, false);
239 if (ret)
240 return ret;
241
242 return ret;
243}
244
245/*
246 * Returns the appropriate setting for ths FS field in the CTRL0 register
247 * depending on the rate.
248 */
249static int adau1977_lookup_fs(unsigned int rate)
250{
251 if (rate >= 8000 && rate <= 12000)
252 return ADAU1977_SAI_CTRL0_FS_8000_12000;
253 else if (rate >= 16000 && rate <= 24000)
254 return ADAU1977_SAI_CTRL0_FS_16000_24000;
255 else if (rate >= 32000 && rate <= 48000)
256 return ADAU1977_SAI_CTRL0_FS_32000_48000;
257 else if (rate >= 64000 && rate <= 96000)
258 return ADAU1977_SAI_CTRL0_FS_64000_96000;
259 else if (rate >= 128000 && rate <= 192000)
260 return ADAU1977_SAI_CTRL0_FS_128000_192000;
261 else
262 return -EINVAL;
263}
264
265static int adau1977_lookup_mcs(struct adau1977 *adau1977, unsigned int rate,
266 unsigned int fs)
267{
268 unsigned int mcs;
269
270 /*
271 * rate = sysclk / (512 * mcs_lut[mcs]) * 2**fs
272 * => mcs_lut[mcs] = sysclk / (512 * rate) * 2**fs
273 * => mcs_lut[mcs] = sysclk / ((512 / 2**fs) * rate)
274 */
275
276 rate *= 512 >> fs;
277
278 if (adau1977->sysclk % rate != 0)
279 return -EINVAL;
280
281 mcs = adau1977->sysclk / rate;
282
283 /* The factors configured by MCS are 1, 2, 3, 4, 6 */
284 if (mcs < 1 || mcs > 6 || mcs == 5)
285 return -EINVAL;
286
287 mcs = mcs - 1;
288 if (mcs == 5)
289 mcs = 4;
290
291 return mcs;
292}
293
294static int adau1977_hw_params(struct snd_pcm_substream *substream,
295 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
296{
297 struct snd_soc_codec *codec = dai->codec;
298 struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
299 unsigned int rate = params_rate(params);
300 unsigned int slot_width;
301 unsigned int ctrl0, ctrl0_mask;
302 unsigned int ctrl1;
303 int mcs, fs;
304 int ret;
305
306 fs = adau1977_lookup_fs(rate);
307 if (fs < 0)
308 return fs;
309
310 if (adau1977->sysclk_src == ADAU1977_SYSCLK_SRC_MCLK) {
311 mcs = adau1977_lookup_mcs(adau1977, rate, fs);
312 if (mcs < 0)
313 return mcs;
314 } else {
315 mcs = 0;
316 }
317
318 ctrl0_mask = ADAU1977_SAI_CTRL0_FS_MASK;
319 ctrl0 = fs;
320
321 if (adau1977->right_j) {
322 switch (params_width(params)) {
323 case 16:
324 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_16BIT;
325 break;
326 case 24:
327 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT;
328 break;
329 default:
330 return -EINVAL;
331 }
332 ctrl0_mask |= ADAU1977_SAI_CTRL0_FMT_MASK;
333 }
334
335 if (adau1977->master) {
336 switch (params_width(params)) {
337 case 16:
338 ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_16BIT;
339 slot_width = 16;
340 break;
341 case 24:
342 case 32:
343 ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_24BIT;
344 slot_width = 32;
345 break;
346 default:
347 return -EINVAL;
348 }
349
350 /* In TDM mode there is a fixed slot width */
351 if (adau1977->slot_width)
352 slot_width = adau1977->slot_width;
353
354 if (slot_width == 16)
355 ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_16;
356 else
357 ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_32;
358
359 ret = regmap_update_bits(adau1977->regmap,
360 ADAU1977_REG_SAI_CTRL1,
361 ADAU1977_SAI_CTRL1_DATA_WIDTH_MASK |
362 ADAU1977_SAI_CTRL1_BCLKRATE_MASK,
363 ctrl1);
364 if (ret < 0)
365 return ret;
366 }
367
368 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,
369 ctrl0_mask, ctrl0);
370 if (ret < 0)
371 return ret;
372
373 return regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL,
374 ADAU1977_PLL_MCS_MASK, mcs);
375}
376
377static int adau1977_power_disable(struct adau1977 *adau1977)
378{
379 int ret = 0;
380
381 if (!adau1977->enabled)
382 return 0;
383
384 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER,
385 ADAU1977_POWER_PWUP, 0);
386 if (ret)
387 return ret;
388
389 regcache_mark_dirty(adau1977->regmap);
390
391 if (adau1977->reset_gpio)
392 gpiod_set_value_cansleep(adau1977->reset_gpio, 0);
393
394 regcache_cache_only(adau1977->regmap, true);
395
396 regulator_disable(adau1977->avdd_reg);
397 if (adau1977->dvdd_reg)
398 regulator_disable(adau1977->dvdd_reg);
399
400 adau1977->enabled = false;
401
402 return 0;
403}
404
405static int adau1977_power_enable(struct adau1977 *adau1977)
406{
407 unsigned int val;
408 int ret = 0;
409
410 if (adau1977->enabled)
411 return 0;
412
413 ret = regulator_enable(adau1977->avdd_reg);
414 if (ret)
415 return ret;
416
417 if (adau1977->dvdd_reg) {
418 ret = regulator_enable(adau1977->dvdd_reg);
419 if (ret)
420 goto err_disable_avdd;
421 }
422
423 if (adau1977->reset_gpio)
424 gpiod_set_value_cansleep(adau1977->reset_gpio, 1);
425
426 regcache_cache_only(adau1977->regmap, false);
427
428 if (adau1977->switch_mode)
429 adau1977->switch_mode(adau1977->dev);
430
431 ret = adau1977_reset(adau1977);
432 if (ret)
433 goto err_disable_dvdd;
434
435 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER,
436 ADAU1977_POWER_PWUP, ADAU1977_POWER_PWUP);
437 if (ret)
438 goto err_disable_dvdd;
439
440 ret = regcache_sync(adau1977->regmap);
441 if (ret)
442 goto err_disable_dvdd;
443
444 /*
445 * The PLL register is not affected by the software reset. It is
446 * possible that the value of the register was changed to the
447 * default value while we were in cache only mode. In this case
448 * regcache_sync will skip over it and we have to manually sync
449 * it.
450 */
451 ret = regmap_read(adau1977->regmap, ADAU1977_REG_PLL, &val);
452 if (ret)
453 goto err_disable_dvdd;
454
455 if (val == 0x41) {
456 regcache_cache_bypass(adau1977->regmap, true);
457 ret = regmap_write(adau1977->regmap, ADAU1977_REG_PLL,
458 0x41);
459 if (ret)
460 goto err_disable_dvdd;
461 regcache_cache_bypass(adau1977->regmap, false);
462 }
463
464 adau1977->enabled = true;
465
466 return ret;
467
468err_disable_dvdd:
469 if (adau1977->dvdd_reg)
470 regulator_disable(adau1977->dvdd_reg);
471err_disable_avdd:
472 regulator_disable(adau1977->avdd_reg);
473 return ret;
474}
475
476static int adau1977_set_bias_level(struct snd_soc_codec *codec,
477 enum snd_soc_bias_level level)
478{
479 struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
480 int ret = 0;
481
482 switch (level) {
483 case SND_SOC_BIAS_ON:
484 break;
485 case SND_SOC_BIAS_PREPARE:
486 break;
487 case SND_SOC_BIAS_STANDBY:
488 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
489 ret = adau1977_power_enable(adau1977);
490 break;
491 case SND_SOC_BIAS_OFF:
492 ret = adau1977_power_disable(adau1977);
493 break;
494 }
495
496 if (ret)
497 return ret;
498
499 codec->dapm.bias_level = level;
500
501 return 0;
502}
503
504static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
505 unsigned int rx_mask, int slots, int width)
506{
507 struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
508 unsigned int ctrl0, ctrl1, drv;
509 unsigned int slot[4];
510 unsigned int i;
511 int ret;
512
513 if (slots == 0) {
514 /* 0 = No fixed slot width */
515 adau1977->slot_width = 0;
516 adau1977->max_master_fs = 192000;
517 return regmap_update_bits(adau1977->regmap,
518 ADAU1977_REG_SAI_CTRL0, ADAU1977_SAI_CTRL0_SAI_MASK,
519 ADAU1977_SAI_CTRL0_SAI_I2S);
520 }
521
522 if (rx_mask == 0 || tx_mask != 0)
523 return -EINVAL;
524
525 drv = 0;
526 for (i = 0; i < 4; i++) {
527 slot[i] = __ffs(rx_mask);
528 drv |= ADAU1977_SAI_OVERTEMP_DRV_C(i);
529 rx_mask &= ~(1 << slot[i]);
530 if (slot[i] >= slots)
531 return -EINVAL;
532 if (rx_mask == 0)
533 break;
534 }
535
536 if (rx_mask != 0)
537 return -EINVAL;
538
539 switch (width) {
540 case 16:
541 ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_16;
542 break;
543 case 24:
544 /* We can only generate 16 bit or 32 bit wide slots */
545 if (adau1977->master)
546 return -EINVAL;
547 ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_24;
548 break;
549 case 32:
550 ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_32;
551 break;
552 default:
553 return -EINVAL;
554 }
555
556 switch (slots) {
557 case 2:
558 ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_2;
559 break;
560 case 4:
561 ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_4;
562 break;
563 case 8:
564 ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_8;
565 break;
566 case 16:
567 ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_16;
568 break;
569 default:
570 return -EINVAL;
571 }
572
573 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP,
574 ADAU1977_SAI_OVERTEMP_DRV_C(0) |
575 ADAU1977_SAI_OVERTEMP_DRV_C(1) |
576 ADAU1977_SAI_OVERTEMP_DRV_C(2) |
577 ADAU1977_SAI_OVERTEMP_DRV_C(3), drv);
578 if (ret)
579 return ret;
580
581 ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP12,
582 (slot[1] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) |
583 (slot[0] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET));
584 if (ret)
585 return ret;
586
587 ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP34,
588 (slot[3] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) |
589 (slot[2] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET));
590 if (ret)
591 return ret;
592
593 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,
594 ADAU1977_SAI_CTRL0_SAI_MASK, ctrl0);
595 if (ret)
596 return ret;
597
598 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1,
599 ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK, ctrl1);
600 if (ret)
601 return ret;
602
603 adau1977->slot_width = width;
604
605 /* In master mode the maximum bitclock is 24.576 MHz */
606 adau1977->max_master_fs = min(192000, 24576000 / width / slots);
607
608 return 0;
609}
610
611static int adau1977_mute(struct snd_soc_dai *dai, int mute, int stream)
612{
613 struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
614 unsigned int val;
615
616 if (mute)
617 val = ADAU1977_MISC_CONTROL_MMUTE;
618 else
619 val = 0;
620
621 return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MISC_CONTROL,
622 ADAU1977_MISC_CONTROL_MMUTE, val);
623}
624
625static int adau1977_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
626{
627 struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
628 unsigned int ctrl0 = 0, ctrl1 = 0, block_power = 0;
629 bool invert_lrclk;
630 int ret;
631
632 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
633 case SND_SOC_DAIFMT_CBS_CFS:
634 adau1977->master = false;
635 break;
636 case SND_SOC_DAIFMT_CBM_CFM:
637 ctrl1 |= ADAU1977_SAI_CTRL1_MASTER;
638 adau1977->master = true;
639 break;
640 default:
641 return -EINVAL;
642 }
643
644 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
645 case SND_SOC_DAIFMT_NB_NF:
646 invert_lrclk = false;
647 break;
648 case SND_SOC_DAIFMT_IB_NF:
649 block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE;
650 invert_lrclk = false;
651 break;
652 case SND_SOC_DAIFMT_NB_IF:
653 invert_lrclk = true;
654 break;
655 case SND_SOC_DAIFMT_IB_IF:
656 block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE;
657 invert_lrclk = true;
658 break;
659 default:
660 return -EINVAL;
661 }
662
663 adau1977->right_j = false;
664 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
665 case SND_SOC_DAIFMT_I2S:
666 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S;
667 break;
668 case SND_SOC_DAIFMT_LEFT_J:
669 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ;
670 invert_lrclk = !invert_lrclk;
671 break;
672 case SND_SOC_DAIFMT_RIGHT_J:
673 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT;
674 adau1977->right_j = true;
675 invert_lrclk = !invert_lrclk;
676 break;
677 case SND_SOC_DAIFMT_DSP_A:
678 ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE;
679 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S;
680 invert_lrclk = false;
681 break;
682 case SND_SOC_DAIFMT_DSP_B:
683 ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE;
684 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ;
685 invert_lrclk = false;
686 break;
687 default:
688 return -EINVAL;
689 }
690
691 if (invert_lrclk)
692 block_power |= ADAU1977_BLOCK_POWER_SAI_LR_POL;
693
694 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,
695 ADAU1977_BLOCK_POWER_SAI_LR_POL |
696 ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE, block_power);
697 if (ret)
698 return ret;
699
700 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,
701 ADAU1977_SAI_CTRL0_FMT_MASK,
702 ctrl0);
703 if (ret)
704 return ret;
705
706 return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1,
707 ADAU1977_SAI_CTRL1_MASTER | ADAU1977_SAI_CTRL1_LRCLK_PULSE,
708 ctrl1);
709}
710
711static int adau1977_startup(struct snd_pcm_substream *substream,
712 struct snd_soc_dai *dai)
713{
714 struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
715 u64 formats = 0;
716
717 if (adau1977->slot_width == 16)
718 formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE;
719 else if (adau1977->right_j || adau1977->slot_width == 24)
720 formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
721 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE;
722
723 snd_pcm_hw_constraint_list(substream->runtime, 0,
724 SNDRV_PCM_HW_PARAM_RATE, &adau1977->constraints);
725
726 if (adau1977->master)
727 snd_pcm_hw_constraint_minmax(substream->runtime,
728 SNDRV_PCM_HW_PARAM_RATE, 8000, adau1977->max_master_fs);
729
730 if (formats != 0)
731 snd_pcm_hw_constraint_mask64(substream->runtime,
732 SNDRV_PCM_HW_PARAM_FORMAT, formats);
733
734 return 0;
735}
736
737static int adau1977_set_tristate(struct snd_soc_dai *dai, int tristate)
738{
739 struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
740 unsigned int val;
741
742 if (tristate)
743 val = ADAU1977_SAI_OVERTEMP_DRV_HIZ;
744 else
745 val = 0;
746
747 return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP,
748 ADAU1977_SAI_OVERTEMP_DRV_HIZ, val);
749}
750
751static const struct snd_soc_dai_ops adau1977_dai_ops = {
752 .startup = adau1977_startup,
753 .hw_params = adau1977_hw_params,
754 .mute_stream = adau1977_mute,
755 .set_fmt = adau1977_set_dai_fmt,
756 .set_tdm_slot = adau1977_set_tdm_slot,
757 .set_tristate = adau1977_set_tristate,
758};
759
760static struct snd_soc_dai_driver adau1977_dai = {
761 .name = "adau1977-hifi",
762 .capture = {
763 .stream_name = "Capture",
764 .channels_min = 1,
765 .channels_max = 4,
766 .rates = SNDRV_PCM_RATE_KNOT,
767 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
768 SNDRV_PCM_FMTBIT_S32_LE,
769 .sig_bits = 24,
770 },
771 .ops = &adau1977_dai_ops,
772};
773
774static const unsigned int adau1977_rates[] = {
775 8000, 16000, 32000, 64000, 128000,
776 11025, 22050, 44100, 88200, 172400,
777 12000, 24000, 48000, 96000, 192000,
778};
779
780#define ADAU1977_RATE_CONSTRAINT_MASK_32000 0x001f
781#define ADAU1977_RATE_CONSTRAINT_MASK_44100 0x03e0
782#define ADAU1977_RATE_CONSTRAINT_MASK_48000 0x7c00
783/* All rates >= 32000 */
784#define ADAU1977_RATE_CONSTRAINT_MASK_LRCLK 0x739c
785
786static bool adau1977_check_sysclk(unsigned int mclk, unsigned int base_freq)
787{
788 unsigned int mcs;
789
790 if (mclk % (base_freq * 128) != 0)
791 return false;
792
793 mcs = mclk / (128 * base_freq);
794 if (mcs < 1 || mcs > 6 || mcs == 5)
795 return false;
796
797 return true;
798}
799
800static int adau1977_set_sysclk(struct snd_soc_codec *codec,
801 int clk_id, int source, unsigned int freq, int dir)
802{
803 struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
804 unsigned int mask = 0;
805 unsigned int clk_src;
806 unsigned int ret;
807
808 if (dir != SND_SOC_CLOCK_IN)
809 return -EINVAL;
810
811 if (clk_id != ADAU1977_SYSCLK)
812 return -EINVAL;
813
814 switch (source) {
815 case ADAU1977_SYSCLK_SRC_MCLK:
816 clk_src = 0;
817 break;
818 case ADAU1977_SYSCLK_SRC_LRCLK:
819 clk_src = ADAU1977_PLL_CLK_S;
820 break;
821 default:
822 return -EINVAL;
823 }
824
825 if (freq != 0 && source == ADAU1977_SYSCLK_SRC_MCLK) {
826 if (freq < 4000000 || freq > 36864000)
827 return -EINVAL;
828
829 if (adau1977_check_sysclk(freq, 32000))
830 mask |= ADAU1977_RATE_CONSTRAINT_MASK_32000;
831 if (adau1977_check_sysclk(freq, 44100))
832 mask |= ADAU1977_RATE_CONSTRAINT_MASK_44100;
833 if (adau1977_check_sysclk(freq, 48000))
834 mask |= ADAU1977_RATE_CONSTRAINT_MASK_48000;
835
836 if (mask == 0)
837 return -EINVAL;
838 } else if (source == ADAU1977_SYSCLK_SRC_LRCLK) {
839 mask = ADAU1977_RATE_CONSTRAINT_MASK_LRCLK;
840 }
841
842 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL,
843 ADAU1977_PLL_CLK_S, clk_src);
844 if (ret)
845 return ret;
846
847 adau1977->constraints.mask = mask;
848 adau1977->sysclk_src = source;
849 adau1977->sysclk = freq;
850
851 return 0;
852}
853
854static int adau1977_codec_probe(struct snd_soc_codec *codec)
855{
856 struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
857 int ret;
858
859 switch (adau1977->type) {
860 case ADAU1977:
861 ret = snd_soc_dapm_new_controls(&codec->dapm,
862 adau1977_micbias_dapm_widgets,
863 ARRAY_SIZE(adau1977_micbias_dapm_widgets));
864 if (ret < 0)
865 return ret;
866 break;
867 default:
868 break;
869 }
870
871 return 0;
872}
873
874static struct snd_soc_codec_driver adau1977_codec_driver = {
875 .probe = adau1977_codec_probe,
876 .set_bias_level = adau1977_set_bias_level,
877 .set_sysclk = adau1977_set_sysclk,
878 .idle_bias_off = true,
879
880 .controls = adau1977_snd_controls,
881 .num_controls = ARRAY_SIZE(adau1977_snd_controls),
882 .dapm_widgets = adau1977_dapm_widgets,
883 .num_dapm_widgets = ARRAY_SIZE(adau1977_dapm_widgets),
884 .dapm_routes = adau1977_dapm_routes,
885 .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes),
886};
887
888static int adau1977_setup_micbias(struct adau1977 *adau1977)
889{
890 struct adau1977_platform_data *pdata = adau1977->dev->platform_data;
891 unsigned int micbias;
892
893 if (pdata) {
894 micbias = pdata->micbias;
895 if (micbias > ADAU1977_MICBIAS_9V0)
896 return -EINVAL;
897
898 } else {
899 micbias = ADAU1977_MICBIAS_8V5;
900 }
901
902 return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MICBIAS,
903 ADAU1977_MICBIAS_MB_VOLTS_MASK,
904 micbias << ADAU1977_MICBIAS_MB_VOLTS_OFFSET);
905}
906
907int adau1977_probe(struct device *dev, struct regmap *regmap,
908 enum adau1977_type type, void (*switch_mode)(struct device *dev))
909{
910 unsigned int power_off_mask;
911 struct adau1977 *adau1977;
912 int ret;
913
914 if (IS_ERR(regmap))
915 return PTR_ERR(regmap);
916
917 adau1977 = devm_kzalloc(dev, sizeof(*adau1977), GFP_KERNEL);
918 if (adau1977 == NULL)
919 return -ENOMEM;
920
921 adau1977->dev = dev;
922 adau1977->type = type;
923 adau1977->regmap = regmap;
924 adau1977->switch_mode = switch_mode;
925 adau1977->max_master_fs = 192000;
926
927 adau1977->constraints.list = adau1977_rates;
928 adau1977->constraints.count = ARRAY_SIZE(adau1977_rates);
929
930 adau1977->avdd_reg = devm_regulator_get(dev, "AVDD");
931 if (IS_ERR(adau1977->avdd_reg))
932 return PTR_ERR(adau1977->avdd_reg);
933
934 adau1977->dvdd_reg = devm_regulator_get_optional(dev, "DVDD");
935 if (IS_ERR(adau1977->dvdd_reg)) {
936 if (PTR_ERR(adau1977->dvdd_reg) != -ENODEV)
937 return PTR_ERR(adau1977->dvdd_reg);
938 adau1977->dvdd_reg = NULL;
939 }
940
941 adau1977->reset_gpio = devm_gpiod_get(dev, "reset");
942 if (IS_ERR(adau1977->reset_gpio)) {
943 ret = PTR_ERR(adau1977->reset_gpio);
944 if (ret != -ENOENT && ret != -ENOSYS)
945 return PTR_ERR(adau1977->reset_gpio);
946 adau1977->reset_gpio = NULL;
947 }
948
949 dev_set_drvdata(dev, adau1977);
950
951 if (adau1977->reset_gpio) {
952 ret = gpiod_direction_output(adau1977->reset_gpio, 0);
953 if (ret)
954 return ret;
955 ndelay(100);
956 }
957
958 ret = adau1977_power_enable(adau1977);
959 if (ret)
960 return ret;
961
962 if (type == ADAU1977) {
963 ret = adau1977_setup_micbias(adau1977);
964 if (ret)
965 goto err_poweroff;
966 }
967
968 if (adau1977->dvdd_reg)
969 power_off_mask = ~0;
970 else
971 power_off_mask = ~ADAU1977_BLOCK_POWER_SAI_LDO_EN;
972
973 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,
974 power_off_mask, 0x00);
975 if (ret)
976 goto err_poweroff;
977
978 ret = adau1977_power_disable(adau1977);
979 if (ret)
980 return ret;
981
982 return snd_soc_register_codec(dev, &adau1977_codec_driver,
983 &adau1977_dai, 1);
984
985err_poweroff:
986 adau1977_power_disable(adau1977);
987 return ret;
988
989}
990EXPORT_SYMBOL_GPL(adau1977_probe);
991
992static bool adau1977_register_volatile(struct device *dev, unsigned int reg)
993{
994 switch (reg) {
995 case ADAU1977_REG_STATUS(0):
996 case ADAU1977_REG_STATUS(1):
997 case ADAU1977_REG_STATUS(2):
998 case ADAU1977_REG_STATUS(3):
999 case ADAU1977_REG_ADC_CLIP:
1000 return true;
1001 }
1002
1003 return false;
1004}
1005
1006const struct regmap_config adau1977_regmap_config = {
1007 .max_register = ADAU1977_REG_DC_HPF_CAL,
1008 .volatile_reg = adau1977_register_volatile,
1009
1010 .cache_type = REGCACHE_RBTREE,
1011 .reg_defaults = adau1977_reg_defaults,
1012 .num_reg_defaults = ARRAY_SIZE(adau1977_reg_defaults),
1013};
1014EXPORT_SYMBOL_GPL(adau1977_regmap_config);
1015
1016MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver");
1017MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
1018MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adau1977.h b/sound/soc/codecs/adau1977.h
new file mode 100644
index 000000000000..95e714345a86
--- /dev/null
+++ b/sound/soc/codecs/adau1977.h
@@ -0,0 +1,37 @@
1/*
2 * ADAU1977/ADAU1978/ADAU1979 driver
3 *
4 * Copyright 2014 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2.
8 */
9
10#ifndef __SOUND_SOC_CODECS_ADAU1977_H__
11#define __SOUND_SOC_CODECS_ADAU1977_H__
12
13#include <linux/regmap.h>
14
15struct device;
16
17enum adau1977_type {
18 ADAU1977,
19 ADAU1978,
20 ADAU1979,
21};
22
23int adau1977_probe(struct device *dev, struct regmap *regmap,
24 enum adau1977_type type, void (*switch_mode)(struct device *dev));
25
26extern const struct regmap_config adau1977_regmap_config;
27
28enum adau1977_clk_id {
29 ADAU1977_SYSCLK,
30};
31
32enum adau1977_sysclk_src {
33 ADAU1977_SYSCLK_SRC_MCLK,
34 ADAU1977_SYSCLK_SRC_LRCLK,
35};
36
37#endif
diff --git a/sound/soc/codecs/adav801.c b/sound/soc/codecs/adav801.c
new file mode 100644
index 000000000000..790fce33ab10
--- /dev/null
+++ b/sound/soc/codecs/adav801.c
@@ -0,0 +1,53 @@
1/*
2 * ADAV801 audio driver
3 *
4 * Copyright 2014 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/module.h>
10#include <linux/spi/spi.h>
11#include <linux/regmap.h>
12
13#include <sound/soc.h>
14
15#include "adav80x.h"
16
17static const struct spi_device_id adav80x_spi_id[] = {
18 { "adav801", 0 },
19 { }
20};
21MODULE_DEVICE_TABLE(spi, adav80x_spi_id);
22
23static int adav80x_spi_probe(struct spi_device *spi)
24{
25 struct regmap_config config;
26
27 config = adav80x_regmap_config;
28 config.read_flag_mask = 0x01;
29
30 return adav80x_bus_probe(&spi->dev, devm_regmap_init_spi(spi, &config));
31}
32
33static int adav80x_spi_remove(struct spi_device *spi)
34{
35 snd_soc_unregister_codec(&spi->dev);
36 return 0;
37}
38
39static struct spi_driver adav80x_spi_driver = {
40 .driver = {
41 .name = "adav801",
42 .owner = THIS_MODULE,
43 },
44 .probe = adav80x_spi_probe,
45 .remove = adav80x_spi_remove,
46 .id_table = adav80x_spi_id,
47};
48module_spi_driver(adav80x_spi_driver);
49
50MODULE_DESCRIPTION("ASoC ADAV801 driver");
51MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
52MODULE_AUTHOR("Yi Li <yi.li@analog.com>>");
53MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adav803.c b/sound/soc/codecs/adav803.c
new file mode 100644
index 000000000000..66d9fce34e62
--- /dev/null
+++ b/sound/soc/codecs/adav803.c
@@ -0,0 +1,50 @@
1/*
2 * ADAV803 audio driver
3 *
4 * Copyright 2014 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/module.h>
10#include <linux/i2c.h>
11#include <linux/regmap.h>
12
13#include <sound/soc.h>
14
15#include "adav80x.h"
16
17static const struct i2c_device_id adav803_id[] = {
18 { "adav803", 0 },
19 { }
20};
21MODULE_DEVICE_TABLE(i2c, adav803_id);
22
23static int adav803_probe(struct i2c_client *client,
24 const struct i2c_device_id *id)
25{
26 return adav80x_bus_probe(&client->dev,
27 devm_regmap_init_i2c(client, &adav80x_regmap_config));
28}
29
30static int adav803_remove(struct i2c_client *client)
31{
32 snd_soc_unregister_codec(&client->dev);
33 return 0;
34}
35
36static struct i2c_driver adav803_driver = {
37 .driver = {
38 .name = "adav803",
39 .owner = THIS_MODULE,
40 },
41 .probe = adav803_probe,
42 .remove = adav803_remove,
43 .id_table = adav803_id,
44};
45module_i2c_driver(adav803_driver);
46
47MODULE_DESCRIPTION("ASoC ADAV803 driver");
48MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
49MODULE_AUTHOR("Yi Li <yi.li@analog.com>>");
50MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index f78b27a7c461..7470831ba756 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -8,17 +8,15 @@
8 * Licensed under the GPL-2 or later. 8 * Licensed under the GPL-2 or later.
9 */ 9 */
10 10
11#include <linux/init.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/kernel.h> 12#include <linux/kernel.h>
14#include <linux/i2c.h> 13#include <linux/regmap.h>
15#include <linux/spi/spi.h>
16#include <linux/slab.h> 14#include <linux/slab.h>
17#include <sound/core.h> 15
18#include <sound/pcm.h> 16#include <sound/pcm.h>
19#include <sound/pcm_params.h> 17#include <sound/pcm_params.h>
20#include <sound/tlv.h>
21#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/tlv.h>
22 20
23#include "adav80x.h" 21#include "adav80x.h"
24 22
@@ -541,6 +539,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
541 unsigned int freq, int dir) 539 unsigned int freq, int dir)
542{ 540{
543 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 541 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
542 struct snd_soc_dapm_context *dapm = &codec->dapm;
544 543
545 if (dir == SND_SOC_CLOCK_IN) { 544 if (dir == SND_SOC_CLOCK_IN) {
546 switch (clk_id) { 545 switch (clk_id) {
@@ -573,7 +572,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
573 regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2, 572 regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2,
574 iclk_ctrl2); 573 iclk_ctrl2);
575 574
576 snd_soc_dapm_sync(&codec->dapm); 575 snd_soc_dapm_sync(dapm);
577 } 576 }
578 } else { 577 } else {
579 unsigned int mask; 578 unsigned int mask;
@@ -600,17 +599,21 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
600 adav80x->sysclk_pd[clk_id] = false; 599 adav80x->sysclk_pd[clk_id] = false;
601 } 600 }
602 601
602 snd_soc_dapm_mutex_lock(dapm);
603
603 if (adav80x->sysclk_pd[0]) 604 if (adav80x->sysclk_pd[0])
604 snd_soc_dapm_disable_pin(&codec->dapm, "PLL1"); 605 snd_soc_dapm_disable_pin_unlocked(dapm, "PLL1");
605 else 606 else
606 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); 607 snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL1");
607 608
608 if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2]) 609 if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2])
609 snd_soc_dapm_disable_pin(&codec->dapm, "PLL2"); 610 snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2");
610 else 611 else
611 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2"); 612 snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2");
612 613
613 snd_soc_dapm_sync(&codec->dapm); 614 snd_soc_dapm_sync_unlocked(dapm);
615
616 snd_soc_dapm_mutex_unlock(dapm);
614 } 617 }
615 618
616 return 0; 619 return 0;
@@ -722,7 +725,7 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream,
722 struct snd_soc_codec *codec = dai->codec; 725 struct snd_soc_codec *codec = dai->codec;
723 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 726 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
724 727
725 if (!codec->active || !adav80x->rate) 728 if (!snd_soc_codec_is_active(codec) || !adav80x->rate)
726 return 0; 729 return 0;
727 730
728 return snd_pcm_hw_constraint_minmax(substream->runtime, 731 return snd_pcm_hw_constraint_minmax(substream->runtime,
@@ -735,7 +738,7 @@ static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
735 struct snd_soc_codec *codec = dai->codec; 738 struct snd_soc_codec *codec = dai->codec;
736 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 739 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
737 740
738 if (!codec->active) 741 if (!snd_soc_codec_is_active(codec))
739 adav80x->rate = 0; 742 adav80x->rate = 0;
740} 743}
741 744
@@ -864,39 +867,26 @@ static struct snd_soc_codec_driver adav80x_codec_driver = {
864 .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), 867 .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes),
865}; 868};
866 869
867static int adav80x_bus_probe(struct device *dev, struct regmap *regmap) 870int adav80x_bus_probe(struct device *dev, struct regmap *regmap)
868{ 871{
869 struct adav80x *adav80x; 872 struct adav80x *adav80x;
870 int ret;
871 873
872 if (IS_ERR(regmap)) 874 if (IS_ERR(regmap))
873 return PTR_ERR(regmap); 875 return PTR_ERR(regmap);
874 876
875 adav80x = kzalloc(sizeof(*adav80x), GFP_KERNEL); 877 adav80x = devm_kzalloc(dev, sizeof(*adav80x), GFP_KERNEL);
876 if (!adav80x) 878 if (!adav80x)
877 return -ENOMEM; 879 return -ENOMEM;
878 880
879
880 dev_set_drvdata(dev, adav80x); 881 dev_set_drvdata(dev, adav80x);
881 adav80x->regmap = regmap; 882 adav80x->regmap = regmap;
882 883
883 ret = snd_soc_register_codec(dev, &adav80x_codec_driver, 884 return snd_soc_register_codec(dev, &adav80x_codec_driver,
884 adav80x_dais, ARRAY_SIZE(adav80x_dais)); 885 adav80x_dais, ARRAY_SIZE(adav80x_dais));
885 if (ret)
886 kfree(adav80x);
887
888 return ret;
889} 886}
887EXPORT_SYMBOL_GPL(adav80x_bus_probe);
890 888
891static int adav80x_bus_remove(struct device *dev) 889const struct regmap_config adav80x_regmap_config = {
892{
893 snd_soc_unregister_codec(dev);
894 kfree(dev_get_drvdata(dev));
895 return 0;
896}
897
898#if defined(CONFIG_SPI_MASTER)
899static const struct regmap_config adav80x_spi_regmap_config = {
900 .val_bits = 8, 890 .val_bits = 8,
901 .pad_bits = 1, 891 .pad_bits = 1,
902 .reg_bits = 7, 892 .reg_bits = 7,
@@ -908,105 +898,7 @@ static const struct regmap_config adav80x_spi_regmap_config = {
908 .reg_defaults = adav80x_reg_defaults, 898 .reg_defaults = adav80x_reg_defaults,
909 .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults), 899 .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults),
910}; 900};
911 901EXPORT_SYMBOL_GPL(adav80x_regmap_config);
912static const struct spi_device_id adav80x_spi_id[] = {
913 { "adav801", 0 },
914 { }
915};
916MODULE_DEVICE_TABLE(spi, adav80x_spi_id);
917
918static int adav80x_spi_probe(struct spi_device *spi)
919{
920 return adav80x_bus_probe(&spi->dev,
921 devm_regmap_init_spi(spi, &adav80x_spi_regmap_config));
922}
923
924static int adav80x_spi_remove(struct spi_device *spi)
925{
926 return adav80x_bus_remove(&spi->dev);
927}
928
929static struct spi_driver adav80x_spi_driver = {
930 .driver = {
931 .name = "adav801",
932 .owner = THIS_MODULE,
933 },
934 .probe = adav80x_spi_probe,
935 .remove = adav80x_spi_remove,
936 .id_table = adav80x_spi_id,
937};
938#endif
939
940#if IS_ENABLED(CONFIG_I2C)
941static const struct regmap_config adav80x_i2c_regmap_config = {
942 .val_bits = 8,
943 .pad_bits = 1,
944 .reg_bits = 7,
945
946 .max_register = ADAV80X_PLL_OUTE,
947
948 .cache_type = REGCACHE_RBTREE,
949 .reg_defaults = adav80x_reg_defaults,
950 .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults),
951};
952
953static const struct i2c_device_id adav80x_i2c_id[] = {
954 { "adav803", 0 },
955 { }
956};
957MODULE_DEVICE_TABLE(i2c, adav80x_i2c_id);
958
959static int adav80x_i2c_probe(struct i2c_client *client,
960 const struct i2c_device_id *id)
961{
962 return adav80x_bus_probe(&client->dev,
963 devm_regmap_init_i2c(client, &adav80x_i2c_regmap_config));
964}
965
966static int adav80x_i2c_remove(struct i2c_client *client)
967{
968 return adav80x_bus_remove(&client->dev);
969}
970
971static struct i2c_driver adav80x_i2c_driver = {
972 .driver = {
973 .name = "adav803",
974 .owner = THIS_MODULE,
975 },
976 .probe = adav80x_i2c_probe,
977 .remove = adav80x_i2c_remove,
978 .id_table = adav80x_i2c_id,
979};
980#endif
981
982static int __init adav80x_init(void)
983{
984 int ret = 0;
985
986#if IS_ENABLED(CONFIG_I2C)
987 ret = i2c_add_driver(&adav80x_i2c_driver);
988 if (ret)
989 return ret;
990#endif
991
992#if defined(CONFIG_SPI_MASTER)
993 ret = spi_register_driver(&adav80x_spi_driver);
994#endif
995
996 return ret;
997}
998module_init(adav80x_init);
999
1000static void __exit adav80x_exit(void)
1001{
1002#if IS_ENABLED(CONFIG_I2C)
1003 i2c_del_driver(&adav80x_i2c_driver);
1004#endif
1005#if defined(CONFIG_SPI_MASTER)
1006 spi_unregister_driver(&adav80x_spi_driver);
1007#endif
1008}
1009module_exit(adav80x_exit);
1010 902
1011MODULE_DESCRIPTION("ASoC ADAV80x driver"); 903MODULE_DESCRIPTION("ASoC ADAV80x driver");
1012MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 904MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
diff --git a/sound/soc/codecs/adav80x.h b/sound/soc/codecs/adav80x.h
index adb0fc76d4e3..8a1d7c09dca5 100644
--- a/sound/soc/codecs/adav80x.h
+++ b/sound/soc/codecs/adav80x.h
@@ -9,6 +9,13 @@
9#ifndef _ADAV80X_H 9#ifndef _ADAV80X_H
10#define _ADAV80X_H 10#define _ADAV80X_H
11 11
12#include <linux/regmap.h>
13
14struct device;
15
16extern const struct regmap_config adav80x_regmap_config;
17int adav80x_bus_probe(struct device *dev, struct regmap *regmap);
18
12enum adav80x_pll_src { 19enum adav80x_pll_src {
13 ADAV80X_PLL_SRC_XIN, 20 ADAV80X_PLL_SRC_XIN,
14 ADAV80X_PLL_SRC_XTAL, 21 ADAV80X_PLL_SRC_XTAL,
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index b4819dcd4f4d..10adf25d4c14 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -174,8 +174,6 @@ static int ak4104_probe(struct snd_soc_codec *codec)
174 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); 174 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
175 int ret; 175 int ret;
176 176
177 codec->control_data = ak4104->regmap;
178
179 /* set power-up and non-reset bits */ 177 /* set power-up and non-reset bits */
180 ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, 178 ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,
181 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 179 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN,
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index 94cbe508dd37..684b56f2856a 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -113,14 +113,14 @@ static const DECLARE_TLV_DB_SCALE(alc_tlv, -800, 50, 0);
113static const DECLARE_TLV_DB_SCALE(aux_in_tlv, -2100, 300, 0); 113static const DECLARE_TLV_DB_SCALE(aux_in_tlv, -2100, 300, 0);
114 114
115 115
116static const struct soc_enum ak4641_mono_out_enum = 116static SOC_ENUM_SINGLE_DECL(ak4641_mono_out_enum,
117 SOC_ENUM_SINGLE(AK4641_SIG1, 6, 2, ak4641_mono_out); 117 AK4641_SIG1, 6, ak4641_mono_out);
118static const struct soc_enum ak4641_hp_out_enum = 118static SOC_ENUM_SINGLE_DECL(ak4641_hp_out_enum,
119 SOC_ENUM_SINGLE(AK4641_MODE2, 2, 2, ak4641_hp_out); 119 AK4641_MODE2, 2, ak4641_hp_out);
120static const struct soc_enum ak4641_mic_select_enum = 120static SOC_ENUM_SINGLE_DECL(ak4641_mic_select_enum,
121 SOC_ENUM_SINGLE(AK4641_MIC, 1, 2, ak4641_mic_select); 121 AK4641_MIC, 1, ak4641_mic_select);
122static const struct soc_enum ak4641_mic_or_dac_enum = 122static SOC_ENUM_SINGLE_DECL(ak4641_mic_or_dac_enum,
123 SOC_ENUM_SINGLE(AK4641_BTIF, 4, 2, ak4641_mic_or_dac); 123 AK4641_BTIF, 4, ak4641_mic_or_dac);
124 124
125static const struct snd_kcontrol_new ak4641_snd_controls[] = { 125static const struct snd_kcontrol_new ak4641_snd_controls[] = {
126 SOC_ENUM("Mono 1 Output", ak4641_mono_out_enum), 126 SOC_ENUM("Mono 1 Output", ak4641_mono_out_enum),
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 25bdf6ad4a54..deb2b44669de 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/regmap.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19#include <sound/soc.h> 20#include <sound/soc.h>
20#include <sound/initval.h> 21#include <sound/initval.h>
@@ -23,104 +24,99 @@
23#include "ak4671.h" 24#include "ak4671.h"
24 25
25 26
26/* codec private data */
27struct ak4671_priv {
28 enum snd_soc_control_type control_type;
29};
30
31/* ak4671 register cache & default register settings */ 27/* ak4671 register cache & default register settings */
32static const u8 ak4671_reg[AK4671_CACHEREGNUM] = { 28static const struct reg_default ak4671_reg_defaults[] = {
33 0x00, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */ 29 { 0x00, 0x00 }, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */
34 0xf6, /* AK4671_PLL_MODE_SELECT0 (0x01) */ 30 { 0x01, 0xf6 }, /* AK4671_PLL_MODE_SELECT0 (0x01) */
35 0x00, /* AK4671_PLL_MODE_SELECT1 (0x02) */ 31 { 0x02, 0x00 }, /* AK4671_PLL_MODE_SELECT1 (0x02) */
36 0x02, /* AK4671_FORMAT_SELECT (0x03) */ 32 { 0x03, 0x02 }, /* AK4671_FORMAT_SELECT (0x03) */
37 0x00, /* AK4671_MIC_SIGNAL_SELECT (0x04) */ 33 { 0x04, 0x00 }, /* AK4671_MIC_SIGNAL_SELECT (0x04) */
38 0x55, /* AK4671_MIC_AMP_GAIN (0x05) */ 34 { 0x05, 0x55 }, /* AK4671_MIC_AMP_GAIN (0x05) */
39 0x00, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */ 35 { 0x06, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */
40 0x00, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */ 36 { 0x07, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */
41 0xb5, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */ 37 { 0x08, 0xb5 }, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */
42 0x00, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */ 38 { 0x09, 0x00 }, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */
43 0x00, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */ 39 { 0x0a, 0x00 }, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */
44 0x00, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */ 40 { 0x0b, 0x00 }, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */
45 0x00, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */ 41 { 0x0c, 0x00 }, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */
46 0x00, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */ 42 { 0x0d, 0x00 }, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */
47 0x00, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */ 43 { 0x0e, 0x00 }, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */
48 0x00, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */ 44 { 0x0f, 0x00 }, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */
49 0x00, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */ 45 { 0x10, 0x00 }, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */
50 0x80, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */ 46 { 0x11, 0x80 }, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */
51 0x91, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */ 47 { 0x12, 0x91 }, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */
52 0x91, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */ 48 { 0x13, 0x91 }, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */
53 0xe1, /* AK4671_ALC_REFERENCE_SELECT (0x14) */ 49 { 0x14, 0xe1 }, /* AK4671_ALC_REFERENCE_SELECT (0x14) */
54 0x00, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */ 50 { 0x15, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */
55 0x00, /* AK4671_ALC_TIMER_SELECT (0x16) */ 51 { 0x16, 0x00 }, /* AK4671_ALC_TIMER_SELECT (0x16) */
56 0x00, /* AK4671_ALC_MODE_CONTROL (0x17) */ 52 { 0x17, 0x00 }, /* AK4671_ALC_MODE_CONTROL (0x17) */
57 0x02, /* AK4671_MODE_CONTROL1 (0x18) */ 53 { 0x18, 0x02 }, /* AK4671_MODE_CONTROL1 (0x18) */
58 0x01, /* AK4671_MODE_CONTROL2 (0x19) */ 54 { 0x19, 0x01 }, /* AK4671_MODE_CONTROL2 (0x19) */
59 0x18, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */ 55 { 0x1a, 0x18 }, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */
60 0x18, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */ 56 { 0x1b, 0x18 }, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */
61 0x00, /* AK4671_SIDETONE_A_CONTROL (0x1c) */ 57 { 0x1c, 0x00 }, /* AK4671_SIDETONE_A_CONTROL (0x1c) */
62 0x02, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */ 58 { 0x1d, 0x02 }, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */
63 0x00, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */ 59 { 0x1e, 0x00 }, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */
64 0x00, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */ 60 { 0x1f, 0x00 }, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */
65 0x00, /* AK4671_FIL3_COEFFICIENT2 (0x20) */ 61 { 0x20, 0x00 }, /* AK4671_FIL3_COEFFICIENT2 (0x20) */
66 0x00, /* AK4671_FIL3_COEFFICIENT3 (0x21) */ 62 { 0x21, 0x00 }, /* AK4671_FIL3_COEFFICIENT3 (0x21) */
67 0x00, /* AK4671_EQ_COEFFICIENT0 (0x22) */ 63 { 0x22, 0x00 }, /* AK4671_EQ_COEFFICIENT0 (0x22) */
68 0x00, /* AK4671_EQ_COEFFICIENT1 (0x23) */ 64 { 0x23, 0x00 }, /* AK4671_EQ_COEFFICIENT1 (0x23) */
69 0x00, /* AK4671_EQ_COEFFICIENT2 (0x24) */ 65 { 0x24, 0x00 }, /* AK4671_EQ_COEFFICIENT2 (0x24) */
70 0x00, /* AK4671_EQ_COEFFICIENT3 (0x25) */ 66 { 0x25, 0x00 }, /* AK4671_EQ_COEFFICIENT3 (0x25) */
71 0x00, /* AK4671_EQ_COEFFICIENT4 (0x26) */ 67 { 0x26, 0x00 }, /* AK4671_EQ_COEFFICIENT4 (0x26) */
72 0x00, /* AK4671_EQ_COEFFICIENT5 (0x27) */ 68 { 0x27, 0x00 }, /* AK4671_EQ_COEFFICIENT5 (0x27) */
73 0xa9, /* AK4671_FIL1_COEFFICIENT0 (0x28) */ 69 { 0x28, 0xa9 }, /* AK4671_FIL1_COEFFICIENT0 (0x28) */
74 0x1f, /* AK4671_FIL1_COEFFICIENT1 (0x29) */ 70 { 0x29, 0x1f }, /* AK4671_FIL1_COEFFICIENT1 (0x29) */
75 0xad, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */ 71 { 0x2a, 0xad }, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */
76 0x20, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */ 72 { 0x2b, 0x20 }, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */
77 0x00, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */ 73 { 0x2c, 0x00 }, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */
78 0x00, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */ 74 { 0x2d, 0x00 }, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */
79 0x00, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */ 75 { 0x2e, 0x00 }, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */
80 0x00, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */ 76 { 0x2f, 0x00 }, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */
81 0x00, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */ 77 { 0x30, 0x00 }, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */
82 0x00, /* this register not used */ 78
83 0x00, /* AK4671_E1_COEFFICIENT0 (0x32) */ 79 { 0x32, 0x00 }, /* AK4671_E1_COEFFICIENT0 (0x32) */
84 0x00, /* AK4671_E1_COEFFICIENT1 (0x33) */ 80 { 0x33, 0x00 }, /* AK4671_E1_COEFFICIENT1 (0x33) */
85 0x00, /* AK4671_E1_COEFFICIENT2 (0x34) */ 81 { 0x34, 0x00 }, /* AK4671_E1_COEFFICIENT2 (0x34) */
86 0x00, /* AK4671_E1_COEFFICIENT3 (0x35) */ 82 { 0x35, 0x00 }, /* AK4671_E1_COEFFICIENT3 (0x35) */
87 0x00, /* AK4671_E1_COEFFICIENT4 (0x36) */ 83 { 0x36, 0x00 }, /* AK4671_E1_COEFFICIENT4 (0x36) */
88 0x00, /* AK4671_E1_COEFFICIENT5 (0x37) */ 84 { 0x37, 0x00 }, /* AK4671_E1_COEFFICIENT5 (0x37) */
89 0x00, /* AK4671_E2_COEFFICIENT0 (0x38) */ 85 { 0x38, 0x00 }, /* AK4671_E2_COEFFICIENT0 (0x38) */
90 0x00, /* AK4671_E2_COEFFICIENT1 (0x39) */ 86 { 0x39, 0x00 }, /* AK4671_E2_COEFFICIENT1 (0x39) */
91 0x00, /* AK4671_E2_COEFFICIENT2 (0x3a) */ 87 { 0x3a, 0x00 }, /* AK4671_E2_COEFFICIENT2 (0x3a) */
92 0x00, /* AK4671_E2_COEFFICIENT3 (0x3b) */ 88 { 0x3b, 0x00 }, /* AK4671_E2_COEFFICIENT3 (0x3b) */
93 0x00, /* AK4671_E2_COEFFICIENT4 (0x3c) */ 89 { 0x3c, 0x00 }, /* AK4671_E2_COEFFICIENT4 (0x3c) */
94 0x00, /* AK4671_E2_COEFFICIENT5 (0x3d) */ 90 { 0x3d, 0x00 }, /* AK4671_E2_COEFFICIENT5 (0x3d) */
95 0x00, /* AK4671_E3_COEFFICIENT0 (0x3e) */ 91 { 0x3e, 0x00 }, /* AK4671_E3_COEFFICIENT0 (0x3e) */
96 0x00, /* AK4671_E3_COEFFICIENT1 (0x3f) */ 92 { 0x3f, 0x00 }, /* AK4671_E3_COEFFICIENT1 (0x3f) */
97 0x00, /* AK4671_E3_COEFFICIENT2 (0x40) */ 93 { 0x40, 0x00 }, /* AK4671_E3_COEFFICIENT2 (0x40) */
98 0x00, /* AK4671_E3_COEFFICIENT3 (0x41) */ 94 { 0x41, 0x00 }, /* AK4671_E3_COEFFICIENT3 (0x41) */
99 0x00, /* AK4671_E3_COEFFICIENT4 (0x42) */ 95 { 0x42, 0x00 }, /* AK4671_E3_COEFFICIENT4 (0x42) */
100 0x00, /* AK4671_E3_COEFFICIENT5 (0x43) */ 96 { 0x43, 0x00 }, /* AK4671_E3_COEFFICIENT5 (0x43) */
101 0x00, /* AK4671_E4_COEFFICIENT0 (0x44) */ 97 { 0x44, 0x00 }, /* AK4671_E4_COEFFICIENT0 (0x44) */
102 0x00, /* AK4671_E4_COEFFICIENT1 (0x45) */ 98 { 0x45, 0x00 }, /* AK4671_E4_COEFFICIENT1 (0x45) */
103 0x00, /* AK4671_E4_COEFFICIENT2 (0x46) */ 99 { 0x46, 0x00 }, /* AK4671_E4_COEFFICIENT2 (0x46) */
104 0x00, /* AK4671_E4_COEFFICIENT3 (0x47) */ 100 { 0x47, 0x00 }, /* AK4671_E4_COEFFICIENT3 (0x47) */
105 0x00, /* AK4671_E4_COEFFICIENT4 (0x48) */ 101 { 0x48, 0x00 }, /* AK4671_E4_COEFFICIENT4 (0x48) */
106 0x00, /* AK4671_E4_COEFFICIENT5 (0x49) */ 102 { 0x49, 0x00 }, /* AK4671_E4_COEFFICIENT5 (0x49) */
107 0x00, /* AK4671_E5_COEFFICIENT0 (0x4a) */ 103 { 0x4a, 0x00 }, /* AK4671_E5_COEFFICIENT0 (0x4a) */
108 0x00, /* AK4671_E5_COEFFICIENT1 (0x4b) */ 104 { 0x4b, 0x00 }, /* AK4671_E5_COEFFICIENT1 (0x4b) */
109 0x00, /* AK4671_E5_COEFFICIENT2 (0x4c) */ 105 { 0x4c, 0x00 }, /* AK4671_E5_COEFFICIENT2 (0x4c) */
110 0x00, /* AK4671_E5_COEFFICIENT3 (0x4d) */ 106 { 0x4d, 0x00 }, /* AK4671_E5_COEFFICIENT3 (0x4d) */
111 0x00, /* AK4671_E5_COEFFICIENT4 (0x4e) */ 107 { 0x4e, 0x00 }, /* AK4671_E5_COEFFICIENT4 (0x4e) */
112 0x00, /* AK4671_E5_COEFFICIENT5 (0x4f) */ 108 { 0x4f, 0x00 }, /* AK4671_E5_COEFFICIENT5 (0x4f) */
113 0x88, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */ 109 { 0x50, 0x88 }, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */
114 0x88, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */ 110 { 0x51, 0x88 }, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */
115 0x08, /* AK4671_EQ_CONTRO_10KHZ (0x52) */ 111 { 0x52, 0x08 }, /* AK4671_EQ_CONTRO_10KHZ (0x52) */
116 0x00, /* AK4671_PCM_IF_CONTROL0 (0x53) */ 112 { 0x53, 0x00 }, /* AK4671_PCM_IF_CONTROL0 (0x53) */
117 0x00, /* AK4671_PCM_IF_CONTROL1 (0x54) */ 113 { 0x54, 0x00 }, /* AK4671_PCM_IF_CONTROL1 (0x54) */
118 0x00, /* AK4671_PCM_IF_CONTROL2 (0x55) */ 114 { 0x55, 0x00 }, /* AK4671_PCM_IF_CONTROL2 (0x55) */
119 0x18, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */ 115 { 0x56, 0x18 }, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */
120 0x18, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */ 116 { 0x57, 0x18 }, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */
121 0x00, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */ 117 { 0x58, 0x00 }, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */
122 0x00, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */ 118 { 0x59, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */
123 0x00, /* AK4671_SAR_ADC_CONTROL (0x5a) */ 119 { 0x5a, 0x00 }, /* AK4671_SAR_ADC_CONTROL (0x5a) */
124}; 120};
125 121
126/* 122/*
@@ -241,19 +237,17 @@ static const struct snd_kcontrol_new ak4671_rout3_mixer_controls[] = {
241/* Input MUXs */ 237/* Input MUXs */
242static const char *ak4671_lin_mux_texts[] = 238static const char *ak4671_lin_mux_texts[] =
243 {"LIN1", "LIN2", "LIN3", "LIN4"}; 239 {"LIN1", "LIN2", "LIN3", "LIN4"};
244static const struct soc_enum ak4671_lin_mux_enum = 240static SOC_ENUM_SINGLE_DECL(ak4671_lin_mux_enum,
245 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 0, 241 AK4671_MIC_SIGNAL_SELECT, 0,
246 ARRAY_SIZE(ak4671_lin_mux_texts), 242 ak4671_lin_mux_texts);
247 ak4671_lin_mux_texts);
248static const struct snd_kcontrol_new ak4671_lin_mux_control = 243static const struct snd_kcontrol_new ak4671_lin_mux_control =
249 SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum); 244 SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum);
250 245
251static const char *ak4671_rin_mux_texts[] = 246static const char *ak4671_rin_mux_texts[] =
252 {"RIN1", "RIN2", "RIN3", "RIN4"}; 247 {"RIN1", "RIN2", "RIN3", "RIN4"};
253static const struct soc_enum ak4671_rin_mux_enum = 248static SOC_ENUM_SINGLE_DECL(ak4671_rin_mux_enum,
254 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 2, 249 AK4671_MIC_SIGNAL_SELECT, 2,
255 ARRAY_SIZE(ak4671_rin_mux_texts), 250 ak4671_rin_mux_texts);
256 ak4671_rin_mux_texts);
257static const struct snd_kcontrol_new ak4671_rin_mux_control = 251static const struct snd_kcontrol_new ak4671_rin_mux_control =
258 SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum); 252 SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum);
259 253
@@ -619,18 +613,14 @@ static struct snd_soc_dai_driver ak4671_dai = {
619 613
620static int ak4671_probe(struct snd_soc_codec *codec) 614static int ak4671_probe(struct snd_soc_codec *codec)
621{ 615{
622 struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
623 int ret; 616 int ret;
624 617
625 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type); 618 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
626 if (ret < 0) { 619 if (ret < 0) {
627 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 620 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
628 return ret; 621 return ret;
629 } 622 }
630 623
631 snd_soc_add_codec_controls(codec, ak4671_snd_controls,
632 ARRAY_SIZE(ak4671_snd_controls));
633
634 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 624 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
635 625
636 return ret; 626 return ret;
@@ -646,28 +636,36 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
646 .probe = ak4671_probe, 636 .probe = ak4671_probe,
647 .remove = ak4671_remove, 637 .remove = ak4671_remove,
648 .set_bias_level = ak4671_set_bias_level, 638 .set_bias_level = ak4671_set_bias_level,
649 .reg_cache_size = AK4671_CACHEREGNUM, 639 .controls = ak4671_snd_controls,
650 .reg_word_size = sizeof(u8), 640 .num_controls = ARRAY_SIZE(ak4671_snd_controls),
651 .reg_cache_default = ak4671_reg,
652 .dapm_widgets = ak4671_dapm_widgets, 641 .dapm_widgets = ak4671_dapm_widgets,
653 .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), 642 .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets),
654 .dapm_routes = ak4671_intercon, 643 .dapm_routes = ak4671_intercon,
655 .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), 644 .num_dapm_routes = ARRAY_SIZE(ak4671_intercon),
656}; 645};
657 646
647static const struct regmap_config ak4671_regmap = {
648 .reg_bits = 8,
649 .val_bits = 8,
650
651 .max_register = AK4671_SAR_ADC_CONTROL,
652 .reg_defaults = ak4671_reg_defaults,
653 .num_reg_defaults = ARRAY_SIZE(ak4671_reg_defaults),
654 .cache_type = REGCACHE_RBTREE,
655};
656
658static int ak4671_i2c_probe(struct i2c_client *client, 657static int ak4671_i2c_probe(struct i2c_client *client,
659 const struct i2c_device_id *id) 658 const struct i2c_device_id *id)
660{ 659{
661 struct ak4671_priv *ak4671; 660 struct regmap *regmap;
662 int ret; 661 int ret;
663 662
664 ak4671 = devm_kzalloc(&client->dev, sizeof(struct ak4671_priv), 663 regmap = devm_regmap_init_i2c(client, &ak4671_regmap);
665 GFP_KERNEL); 664 if (IS_ERR(regmap)) {
666 if (ak4671 == NULL) 665 ret = PTR_ERR(regmap);
667 return -ENOMEM; 666 dev_err(&client->dev, "Failed to create regmap: %d\n", ret);
668 667 return ret;
669 i2c_set_clientdata(client, ak4671); 668 }
670 ak4671->control_type = SND_SOC_I2C;
671 669
672 ret = snd_soc_register_codec(&client->dev, 670 ret = snd_soc_register_codec(&client->dev,
673 &soc_codec_dev_ak4671, &ak4671_dai, 1); 671 &soc_codec_dev_ak4671, &ak4671_dai, 1);
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h
index 61cb7ab7552c..394a34d3f50a 100644
--- a/sound/soc/codecs/ak4671.h
+++ b/sound/soc/codecs/ak4671.h
@@ -105,8 +105,6 @@
105#define AK4671_DIGITAL_MIXING_CONTROL2 0x59 105#define AK4671_DIGITAL_MIXING_CONTROL2 0x59
106#define AK4671_SAR_ADC_CONTROL 0x5a 106#define AK4671_SAR_ADC_CONTROL 0x5a
107 107
108#define AK4671_CACHEREGNUM (AK4671_SAR_ADC_CONTROL + 1)
109
110/* Bitfield Definitions */ 108/* Bitfield Definitions */
111 109
112/* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */ 110/* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index d3036283482a..ed506253a914 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -21,6 +21,7 @@
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/pm.h> 22#include <linux/pm.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/regmap.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
@@ -38,26 +39,13 @@ MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)");
38 39
39/* codec private data */ 40/* codec private data */
40struct alc5623_priv { 41struct alc5623_priv {
41 enum snd_soc_control_type control_type; 42 struct regmap *regmap;
42 u8 id; 43 u8 id;
43 unsigned int sysclk; 44 unsigned int sysclk;
44 u16 reg_cache[ALC5623_VENDOR_ID2+2];
45 unsigned int add_ctrl; 45 unsigned int add_ctrl;
46 unsigned int jack_det_ctrl; 46 unsigned int jack_det_ctrl;
47}; 47};
48 48
49static void alc5623_fill_cache(struct snd_soc_codec *codec)
50{
51 int i, step = codec->driver->reg_cache_step;
52 u16 *cache = codec->reg_cache;
53
54 /* not really efficient ... */
55 codec->cache_bypass = 1;
56 for (i = 0 ; i < codec->driver->reg_cache_size ; i += step)
57 cache[i] = snd_soc_read(codec, i);
58 codec->cache_bypass = 0;
59}
60
61static inline int alc5623_reset(struct snd_soc_codec *codec) 49static inline int alc5623_reset(struct snd_soc_codec *codec)
62{ 50{
63 return snd_soc_write(codec, ALC5623_RESET, 0); 51 return snd_soc_write(codec, ALC5623_RESET, 0);
@@ -228,32 +216,37 @@ static const char *alc5623_aux_out_input_sel[] = {
228 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; 216 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
229 217
230/* auxout output mux */ 218/* auxout output mux */
231static const struct soc_enum alc5623_aux_out_input_enum = 219static SOC_ENUM_SINGLE_DECL(alc5623_aux_out_input_enum,
232SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel); 220 ALC5623_OUTPUT_MIXER_CTRL, 6,
221 alc5623_aux_out_input_sel);
233static const struct snd_kcontrol_new alc5623_auxout_mux_controls = 222static const struct snd_kcontrol_new alc5623_auxout_mux_controls =
234SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum); 223SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum);
235 224
236/* speaker output mux */ 225/* speaker output mux */
237static const struct soc_enum alc5623_spkout_input_enum = 226static SOC_ENUM_SINGLE_DECL(alc5623_spkout_input_enum,
238SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel); 227 ALC5623_OUTPUT_MIXER_CTRL, 10,
228 alc5623_spkout_input_sel);
239static const struct snd_kcontrol_new alc5623_spkout_mux_controls = 229static const struct snd_kcontrol_new alc5623_spkout_mux_controls =
240SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum); 230SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum);
241 231
242/* headphone left output mux */ 232/* headphone left output mux */
243static const struct soc_enum alc5623_hpl_out_input_enum = 233static SOC_ENUM_SINGLE_DECL(alc5623_hpl_out_input_enum,
244SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel); 234 ALC5623_OUTPUT_MIXER_CTRL, 9,
235 alc5623_hpl_out_input_sel);
245static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls = 236static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls =
246SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum); 237SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum);
247 238
248/* headphone right output mux */ 239/* headphone right output mux */
249static const struct soc_enum alc5623_hpr_out_input_enum = 240static SOC_ENUM_SINGLE_DECL(alc5623_hpr_out_input_enum,
250SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel); 241 ALC5623_OUTPUT_MIXER_CTRL, 8,
242 alc5623_hpr_out_input_sel);
251static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls = 243static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls =
252SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum); 244SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum);
253 245
254/* speaker output N select */ 246/* speaker output N select */
255static const struct soc_enum alc5623_spk_n_sour_enum = 247static SOC_ENUM_SINGLE_DECL(alc5623_spk_n_sour_enum,
256SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel); 248 ALC5623_OUTPUT_MIXER_CTRL, 14,
249 alc5623_spk_n_sour_sel);
257static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls = 250static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls =
258SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum); 251SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum);
259 252
@@ -338,8 +331,9 @@ SND_SOC_DAPM_VMID("Vmid"),
338}; 331};
339 332
340static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"}; 333static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"};
341static const struct soc_enum alc5623_amp_enum = 334static SOC_ENUM_SINGLE_DECL(alc5623_amp_enum,
342 SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names); 335 ALC5623_OUTPUT_MIXER_CTRL, 13,
336 alc5623_amp_names);
343static const struct snd_kcontrol_new alc5623_amp_mux_controls = 337static const struct snd_kcontrol_new alc5623_amp_mux_controls =
344 SOC_DAPM_ENUM("Route", alc5623_amp_enum); 338 SOC_DAPM_ENUM("Route", alc5623_amp_enum);
345 339
@@ -869,18 +863,28 @@ static struct snd_soc_dai_driver alc5623_dai = {
869 863
870static int alc5623_suspend(struct snd_soc_codec *codec) 864static int alc5623_suspend(struct snd_soc_codec *codec)
871{ 865{
866 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
867
872 alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); 868 alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
869 regcache_cache_only(alc5623->regmap, true);
870
873 return 0; 871 return 0;
874} 872}
875 873
876static int alc5623_resume(struct snd_soc_codec *codec) 874static int alc5623_resume(struct snd_soc_codec *codec)
877{ 875{
878 int i, step = codec->driver->reg_cache_step; 876 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
879 u16 *cache = codec->reg_cache; 877 int ret;
880 878
881 /* Sync reg_cache with the hardware */ 879 /* Sync reg_cache with the hardware */
882 for (i = 2 ; i < codec->driver->reg_cache_size ; i += step) 880 regcache_cache_only(alc5623->regmap, false);
883 snd_soc_write(codec, i, cache[i]); 881 ret = regcache_sync(alc5623->regmap);
882 if (ret != 0) {
883 dev_err(codec->dev, "Failed to sync register cache: %d\n",
884 ret);
885 regcache_cache_only(alc5623->regmap, true);
886 return ret;
887 }
884 888
885 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 889 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
886 890
@@ -900,14 +904,14 @@ static int alc5623_probe(struct snd_soc_codec *codec)
900 struct snd_soc_dapm_context *dapm = &codec->dapm; 904 struct snd_soc_dapm_context *dapm = &codec->dapm;
901 int ret; 905 int ret;
902 906
903 ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type); 907 codec->control_data = alc5623->regmap;
908 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
904 if (ret < 0) { 909 if (ret < 0) {
905 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 910 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
906 return ret; 911 return ret;
907 } 912 }
908 913
909 alc5623_reset(codec); 914 alc5623_reset(codec);
910 alc5623_fill_cache(codec);
911 915
912 /* power on device */ 916 /* power on device */
913 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 917 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -980,9 +984,15 @@ static struct snd_soc_codec_driver soc_codec_device_alc5623 = {
980 .suspend = alc5623_suspend, 984 .suspend = alc5623_suspend,
981 .resume = alc5623_resume, 985 .resume = alc5623_resume,
982 .set_bias_level = alc5623_set_bias_level, 986 .set_bias_level = alc5623_set_bias_level,
983 .reg_cache_size = ALC5623_VENDOR_ID2+2, 987};
984 .reg_word_size = sizeof(u16), 988
985 .reg_cache_step = 2, 989static const struct regmap_config alc5623_regmap = {
990 .reg_bits = 8,
991 .val_bits = 16,
992 .reg_stride = 2,
993
994 .max_register = ALC5623_VENDOR_ID2,
995 .cache_type = REGCACHE_RBTREE,
986}; 996};
987 997
988/* 998/*
@@ -996,19 +1006,32 @@ static int alc5623_i2c_probe(struct i2c_client *client,
996{ 1006{
997 struct alc5623_platform_data *pdata; 1007 struct alc5623_platform_data *pdata;
998 struct alc5623_priv *alc5623; 1008 struct alc5623_priv *alc5623;
999 int ret, vid1, vid2; 1009 unsigned int vid1, vid2;
1010 int ret;
1000 1011
1001 vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1); 1012 alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv),
1002 if (vid1 < 0) { 1013 GFP_KERNEL);
1003 dev_err(&client->dev, "failed to read I2C\n"); 1014 if (alc5623 == NULL)
1004 return -EIO; 1015 return -ENOMEM;
1016
1017 alc5623->regmap = devm_regmap_init_i2c(client, &alc5623_regmap);
1018 if (IS_ERR(alc5623->regmap)) {
1019 ret = PTR_ERR(alc5623->regmap);
1020 dev_err(&client->dev, "Failed to initialise I/O: %d\n", ret);
1021 return ret;
1022 }
1023
1024 ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID1, &vid1);
1025 if (ret < 0) {
1026 dev_err(&client->dev, "failed to read vendor ID1: %d\n", ret);
1027 return ret;
1005 } 1028 }
1006 vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); 1029 vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8);
1007 1030
1008 vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2); 1031 ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID2, &vid2);
1009 if (vid2 < 0) { 1032 if (ret < 0) {
1010 dev_err(&client->dev, "failed to read I2C\n"); 1033 dev_err(&client->dev, "failed to read vendor ID2: %d\n", ret);
1011 return -EIO; 1034 return ret;
1012 } 1035 }
1013 1036
1014 if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { 1037 if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) {
@@ -1021,11 +1044,6 @@ static int alc5623_i2c_probe(struct i2c_client *client,
1021 1044
1022 dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2); 1045 dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2);
1023 1046
1024 alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv),
1025 GFP_KERNEL);
1026 if (alc5623 == NULL)
1027 return -ENOMEM;
1028
1029 pdata = client->dev.platform_data; 1047 pdata = client->dev.platform_data;
1030 if (pdata) { 1048 if (pdata) {
1031 alc5623->add_ctrl = pdata->add_ctrl; 1049 alc5623->add_ctrl = pdata->add_ctrl;
@@ -1048,7 +1066,6 @@ static int alc5623_i2c_probe(struct i2c_client *client,
1048 } 1066 }
1049 1067
1050 i2c_set_clientdata(client, alc5623); 1068 i2c_set_clientdata(client, alc5623);
1051 alc5623->control_type = SND_SOC_I2C;
1052 1069
1053 ret = snd_soc_register_codec(&client->dev, 1070 ret = snd_soc_register_codec(&client->dev,
1054 &soc_codec_device_alc5623, &alc5623_dai, 1); 1071 &soc_codec_device_alc5623, &alc5623_dai, 1);
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index fb001c56cf8d..d885056ad8f2 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -293,51 +293,59 @@ static const char * const alc5632_i2s_out_sel[] = {
293 "ADC LR", "Voice Stereo Digital"}; 293 "ADC LR", "Voice Stereo Digital"};
294 294
295/* auxout output mux */ 295/* auxout output mux */
296static const struct soc_enum alc5632_aux_out_input_enum = 296static SOC_ENUM_SINGLE_DECL(alc5632_aux_out_input_enum,
297SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 6, 4, alc5632_aux_out_input_sel); 297 ALC5632_OUTPUT_MIXER_CTRL, 6,
298 alc5632_aux_out_input_sel);
298static const struct snd_kcontrol_new alc5632_auxout_mux_controls = 299static const struct snd_kcontrol_new alc5632_auxout_mux_controls =
299SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum); 300SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum);
300 301
301/* speaker output mux */ 302/* speaker output mux */
302static const struct soc_enum alc5632_spkout_input_enum = 303static SOC_ENUM_SINGLE_DECL(alc5632_spkout_input_enum,
303SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 10, 4, alc5632_spkout_input_sel); 304 ALC5632_OUTPUT_MIXER_CTRL, 10,
305 alc5632_spkout_input_sel);
304static const struct snd_kcontrol_new alc5632_spkout_mux_controls = 306static const struct snd_kcontrol_new alc5632_spkout_mux_controls =
305SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum); 307SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum);
306 308
307/* headphone left output mux */ 309/* headphone left output mux */
308static const struct soc_enum alc5632_hpl_out_input_enum = 310static SOC_ENUM_SINGLE_DECL(alc5632_hpl_out_input_enum,
309SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 9, 2, alc5632_hpl_out_input_sel); 311 ALC5632_OUTPUT_MIXER_CTRL, 9,
312 alc5632_hpl_out_input_sel);
310static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls = 313static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls =
311SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum); 314SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum);
312 315
313/* headphone right output mux */ 316/* headphone right output mux */
314static const struct soc_enum alc5632_hpr_out_input_enum = 317static SOC_ENUM_SINGLE_DECL(alc5632_hpr_out_input_enum,
315SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 8, 2, alc5632_hpr_out_input_sel); 318 ALC5632_OUTPUT_MIXER_CTRL, 8,
319 alc5632_hpr_out_input_sel);
316static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls = 320static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls =
317SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum); 321SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum);
318 322
319/* speaker output N select */ 323/* speaker output N select */
320static const struct soc_enum alc5632_spk_n_sour_enum = 324static SOC_ENUM_SINGLE_DECL(alc5632_spk_n_sour_enum,
321SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 14, 4, alc5632_spk_n_sour_sel); 325 ALC5632_OUTPUT_MIXER_CTRL, 14,
326 alc5632_spk_n_sour_sel);
322static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls = 327static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls =
323SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum); 328SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum);
324 329
325/* speaker amplifier */ 330/* speaker amplifier */
326static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"}; 331static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"};
327static const struct soc_enum alc5632_amp_enum = 332static SOC_ENUM_SINGLE_DECL(alc5632_amp_enum,
328 SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 13, 2, alc5632_amp_names); 333 ALC5632_OUTPUT_MIXER_CTRL, 13,
334 alc5632_amp_names);
329static const struct snd_kcontrol_new alc5632_amp_mux_controls = 335static const struct snd_kcontrol_new alc5632_amp_mux_controls =
330 SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); 336 SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
331 337
332/* ADC output select */ 338/* ADC output select */
333static const struct soc_enum alc5632_adcr_func_enum = 339static SOC_ENUM_SINGLE_DECL(alc5632_adcr_func_enum,
334 SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel); 340 ALC5632_DAC_FUNC_SELECT, 5,
341 alc5632_adcr_func_sel);
335static const struct snd_kcontrol_new alc5632_adcr_func_controls = 342static const struct snd_kcontrol_new alc5632_adcr_func_controls =
336 SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum); 343 SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum);
337 344
338/* I2S out select */ 345/* I2S out select */
339static const struct soc_enum alc5632_i2s_out_enum = 346static SOC_ENUM_SINGLE_DECL(alc5632_i2s_out_enum,
340 SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel); 347 ALC5632_I2S_OUT_CTL, 5,
348 alc5632_i2s_out_sel);
341static const struct snd_kcontrol_new alc5632_i2s_out_controls = 349static const struct snd_kcontrol_new alc5632_i2s_out_controls =
342 SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum); 350 SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum);
343 351
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index e4295fee8f13..29e198f57d4c 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -53,6 +53,14 @@
53#define ARIZONA_AIF_RX_ENABLES 0x1A 53#define ARIZONA_AIF_RX_ENABLES 0x1A
54#define ARIZONA_AIF_FORCE_WRITE 0x1B 54#define ARIZONA_AIF_FORCE_WRITE 0x1B
55 55
56#define ARIZONA_FLL_VCO_CORNER 141900000
57#define ARIZONA_FLL_MAX_FREF 13500000
58#define ARIZONA_FLL_MIN_FVCO 90000000
59#define ARIZONA_FLL_MAX_FRATIO 16
60#define ARIZONA_FLL_MAX_REFDIV 8
61#define ARIZONA_FLL_MIN_OUTDIV 2
62#define ARIZONA_FLL_MAX_OUTDIV 7
63
56#define arizona_fll_err(_fll, fmt, ...) \ 64#define arizona_fll_err(_fll, fmt, ...) \
57 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 65 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
58#define arizona_fll_warn(_fll, fmt, ...) \ 66#define arizona_fll_warn(_fll, fmt, ...) \
@@ -542,67 +550,76 @@ static const char *arizona_vol_ramp_text[] = {
542 "15ms/6dB", "30ms/6dB", 550 "15ms/6dB", "30ms/6dB",
543}; 551};
544 552
545const struct soc_enum arizona_in_vd_ramp = 553SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp,
546 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, 554 ARIZONA_INPUT_VOLUME_RAMP,
547 ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); 555 ARIZONA_IN_VD_RAMP_SHIFT,
556 arizona_vol_ramp_text);
548EXPORT_SYMBOL_GPL(arizona_in_vd_ramp); 557EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
549 558
550const struct soc_enum arizona_in_vi_ramp = 559SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp,
551 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, 560 ARIZONA_INPUT_VOLUME_RAMP,
552 ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); 561 ARIZONA_IN_VI_RAMP_SHIFT,
562 arizona_vol_ramp_text);
553EXPORT_SYMBOL_GPL(arizona_in_vi_ramp); 563EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
554 564
555const struct soc_enum arizona_out_vd_ramp = 565SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp,
556 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, 566 ARIZONA_OUTPUT_VOLUME_RAMP,
557 ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); 567 ARIZONA_OUT_VD_RAMP_SHIFT,
568 arizona_vol_ramp_text);
558EXPORT_SYMBOL_GPL(arizona_out_vd_ramp); 569EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
559 570
560const struct soc_enum arizona_out_vi_ramp = 571SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp,
561 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, 572 ARIZONA_OUTPUT_VOLUME_RAMP,
562 ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); 573 ARIZONA_OUT_VI_RAMP_SHIFT,
574 arizona_vol_ramp_text);
563EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); 575EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
564 576
565static const char *arizona_lhpf_mode_text[] = { 577static const char *arizona_lhpf_mode_text[] = {
566 "Low-pass", "High-pass" 578 "Low-pass", "High-pass"
567}; 579};
568 580
569const struct soc_enum arizona_lhpf1_mode = 581SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode,
570 SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2, 582 ARIZONA_HPLPF1_1,
571 arizona_lhpf_mode_text); 583 ARIZONA_LHPF1_MODE_SHIFT,
584 arizona_lhpf_mode_text);
572EXPORT_SYMBOL_GPL(arizona_lhpf1_mode); 585EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
573 586
574const struct soc_enum arizona_lhpf2_mode = 587SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode,
575 SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2, 588 ARIZONA_HPLPF2_1,
576 arizona_lhpf_mode_text); 589 ARIZONA_LHPF2_MODE_SHIFT,
590 arizona_lhpf_mode_text);
577EXPORT_SYMBOL_GPL(arizona_lhpf2_mode); 591EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
578 592
579const struct soc_enum arizona_lhpf3_mode = 593SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode,
580 SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2, 594 ARIZONA_HPLPF3_1,
581 arizona_lhpf_mode_text); 595 ARIZONA_LHPF3_MODE_SHIFT,
596 arizona_lhpf_mode_text);
582EXPORT_SYMBOL_GPL(arizona_lhpf3_mode); 597EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
583 598
584const struct soc_enum arizona_lhpf4_mode = 599SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode,
585 SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2, 600 ARIZONA_HPLPF4_1,
586 arizona_lhpf_mode_text); 601 ARIZONA_LHPF4_MODE_SHIFT,
602 arizona_lhpf_mode_text);
587EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); 603EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
588 604
589static const char *arizona_ng_hold_text[] = { 605static const char *arizona_ng_hold_text[] = {
590 "30ms", "120ms", "250ms", "500ms", 606 "30ms", "120ms", "250ms", "500ms",
591}; 607};
592 608
593const struct soc_enum arizona_ng_hold = 609SOC_ENUM_SINGLE_DECL(arizona_ng_hold,
594 SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT, 610 ARIZONA_NOISE_GATE_CONTROL,
595 4, arizona_ng_hold_text); 611 ARIZONA_NGATE_HOLD_SHIFT,
612 arizona_ng_hold_text);
596EXPORT_SYMBOL_GPL(arizona_ng_hold); 613EXPORT_SYMBOL_GPL(arizona_ng_hold);
597 614
598static const char * const arizona_in_hpf_cut_text[] = { 615static const char * const arizona_in_hpf_cut_text[] = {
599 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz" 616 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
600}; 617};
601 618
602const struct soc_enum arizona_in_hpf_cut_enum = 619SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum,
603 SOC_ENUM_SINGLE(ARIZONA_HPF_CONTROL, ARIZONA_IN_HPF_CUT_SHIFT, 620 ARIZONA_HPF_CONTROL,
604 ARRAY_SIZE(arizona_in_hpf_cut_text), 621 ARIZONA_IN_HPF_CUT_SHIFT,
605 arizona_in_hpf_cut_text); 622 arizona_in_hpf_cut_text);
606EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum); 623EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
607 624
608static const char * const arizona_in_dmic_osr_text[] = { 625static const char * const arizona_in_dmic_osr_text[] = {
@@ -1377,74 +1394,147 @@ struct arizona_fll_cfg {
1377 int gain; 1394 int gain;
1378}; 1395};
1379 1396
1380static int arizona_calc_fll(struct arizona_fll *fll, 1397static int arizona_validate_fll(struct arizona_fll *fll,
1381 struct arizona_fll_cfg *cfg, 1398 unsigned int Fref,
1382 unsigned int Fref, 1399 unsigned int Fout)
1383 unsigned int Fout)
1384{ 1400{
1385 unsigned int target, div, gcd_fll; 1401 unsigned int Fvco_min;
1386 int i, ratio; 1402
1403 if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
1404 arizona_fll_err(fll,
1405 "Can't scale %dMHz in to <=13.5MHz\n",
1406 Fref);
1407 return -EINVAL;
1408 }
1387 1409
1388 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout); 1410 Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
1411 if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
1412 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1413 Fout);
1414 return -EINVAL;
1415 }
1416
1417 return 0;
1418}
1419
1420static int arizona_find_fratio(unsigned int Fref, int *fratio)
1421{
1422 int i;
1423
1424 /* Find an appropriate FLL_FRATIO */
1425 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1426 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1427 if (fratio)
1428 *fratio = fll_fratios[i].fratio;
1429 return fll_fratios[i].ratio;
1430 }
1431 }
1432
1433 return -EINVAL;
1434}
1435
1436static int arizona_calc_fratio(struct arizona_fll *fll,
1437 struct arizona_fll_cfg *cfg,
1438 unsigned int target,
1439 unsigned int Fref, bool sync)
1440{
1441 int init_ratio, ratio;
1442 int refdiv, div;
1389 1443
1390 /* Fref must be <=13.5MHz */ 1444 /* Fref must be <=13.5MHz, find initial refdiv */
1391 div = 1; 1445 div = 1;
1392 cfg->refdiv = 0; 1446 cfg->refdiv = 0;
1393 while ((Fref / div) > 13500000) { 1447 while (Fref > ARIZONA_FLL_MAX_FREF) {
1394 div *= 2; 1448 div *= 2;
1449 Fref /= 2;
1395 cfg->refdiv++; 1450 cfg->refdiv++;
1396 1451
1397 if (div > 8) { 1452 if (div > ARIZONA_FLL_MAX_REFDIV)
1398 arizona_fll_err(fll,
1399 "Can't scale %dMHz in to <=13.5MHz\n",
1400 Fref);
1401 return -EINVAL; 1453 return -EINVAL;
1454 }
1455
1456 /* Find an appropriate FLL_FRATIO */
1457 init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
1458 if (init_ratio < 0) {
1459 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1460 Fref);
1461 return init_ratio;
1462 }
1463
1464 switch (fll->arizona->type) {
1465 case WM5110:
1466 if (fll->arizona->rev < 3 || sync)
1467 return init_ratio;
1468 break;
1469 default:
1470 return init_ratio;
1471 }
1472
1473 cfg->fratio = init_ratio - 1;
1474
1475 /* Adjust FRATIO/refdiv to avoid integer mode if possible */
1476 refdiv = cfg->refdiv;
1477
1478 while (div <= ARIZONA_FLL_MAX_REFDIV) {
1479 for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO;
1480 ratio++) {
1481 if (target % (ratio * Fref)) {
1482 cfg->refdiv = refdiv;
1483 cfg->fratio = ratio - 1;
1484 return ratio;
1485 }
1402 } 1486 }
1487
1488 for (ratio = init_ratio - 1; ratio >= 0; ratio--) {
1489 if (ARIZONA_FLL_VCO_CORNER / (fll->vco_mult * ratio) <
1490 Fref)
1491 break;
1492
1493 if (target % (ratio * Fref)) {
1494 cfg->refdiv = refdiv;
1495 cfg->fratio = ratio - 1;
1496 return ratio;
1497 }
1498 }
1499
1500 div *= 2;
1501 Fref /= 2;
1502 refdiv++;
1503 init_ratio = arizona_find_fratio(Fref, NULL);
1403 } 1504 }
1404 1505
1405 /* Apply the division for our remaining calculations */ 1506 arizona_fll_warn(fll, "Falling back to integer mode operation\n");
1406 Fref /= div; 1507 return cfg->fratio + 1;
1508}
1509
1510static int arizona_calc_fll(struct arizona_fll *fll,
1511 struct arizona_fll_cfg *cfg,
1512 unsigned int Fref, bool sync)
1513{
1514 unsigned int target, div, gcd_fll;
1515 int i, ratio;
1516
1517 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
1407 1518
1408 /* Fvco should be over the targt; don't check the upper bound */ 1519 /* Fvco should be over the targt; don't check the upper bound */
1409 div = 1; 1520 div = ARIZONA_FLL_MIN_OUTDIV;
1410 while (Fout * div < 90000000 * fll->vco_mult) { 1521 while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
1411 div++; 1522 div++;
1412 if (div > 7) { 1523 if (div > ARIZONA_FLL_MAX_OUTDIV)
1413 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1414 Fout);
1415 return -EINVAL; 1524 return -EINVAL;
1416 }
1417 } 1525 }
1418 target = Fout * div / fll->vco_mult; 1526 target = fll->fout * div / fll->vco_mult;
1419 cfg->outdiv = div; 1527 cfg->outdiv = div;
1420 1528
1421 arizona_fll_dbg(fll, "Fvco=%dHz\n", target); 1529 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
1422 1530
1423 /* Find an appropraite FLL_FRATIO and factor it out of the target */ 1531 /* Find an appropriate FLL_FRATIO and refdiv */
1424 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { 1532 ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
1425 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { 1533 if (ratio < 0)
1426 cfg->fratio = fll_fratios[i].fratio; 1534 return ratio;
1427 ratio = fll_fratios[i].ratio;
1428 break;
1429 }
1430 }
1431 if (i == ARRAY_SIZE(fll_fratios)) {
1432 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1433 Fref);
1434 return -EINVAL;
1435 }
1436 1535
1437 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) { 1536 /* Apply the division for our remaining calculations */
1438 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) { 1537 Fref = Fref / (1 << cfg->refdiv);
1439 cfg->gain = fll_gains[i].gain;
1440 break;
1441 }
1442 }
1443 if (i == ARRAY_SIZE(fll_gains)) {
1444 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1445 Fref);
1446 return -EINVAL;
1447 }
1448 1538
1449 cfg->n = target / (ratio * Fref); 1539 cfg->n = target / (ratio * Fref);
1450 1540
@@ -1469,6 +1559,18 @@ static int arizona_calc_fll(struct arizona_fll *fll,
1469 cfg->lambda >>= 1; 1559 cfg->lambda >>= 1;
1470 } 1560 }
1471 1561
1562 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1563 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1564 cfg->gain = fll_gains[i].gain;
1565 break;
1566 }
1567 }
1568 if (i == ARRAY_SIZE(fll_gains)) {
1569 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1570 Fref);
1571 return -EINVAL;
1572 }
1573
1472 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n", 1574 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
1473 cfg->n, cfg->theta, cfg->lambda); 1575 cfg->n, cfg->theta, cfg->lambda);
1474 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", 1576 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
@@ -1496,14 +1598,18 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1496 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | 1598 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1497 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); 1599 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1498 1600
1499 if (sync) 1601 if (sync) {
1500 regmap_update_bits_async(arizona->regmap, base + 0x7, 1602 regmap_update_bits(arizona->regmap, base + 0x7,
1501 ARIZONA_FLL1_GAIN_MASK, 1603 ARIZONA_FLL1_GAIN_MASK,
1502 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); 1604 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1503 else 1605 } else {
1504 regmap_update_bits_async(arizona->regmap, base + 0x9, 1606 regmap_update_bits(arizona->regmap, base + 0x5,
1505 ARIZONA_FLL1_GAIN_MASK, 1607 ARIZONA_FLL1_OUTDIV_MASK,
1506 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); 1608 cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1609 regmap_update_bits(arizona->regmap, base + 0x9,
1610 ARIZONA_FLL1_GAIN_MASK,
1611 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1612 }
1507 1613
1508 regmap_update_bits_async(arizona->regmap, base + 2, 1614 regmap_update_bits_async(arizona->regmap, base + 2,
1509 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, 1615 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
@@ -1526,13 +1632,12 @@ static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1526 return reg & ARIZONA_FLL1_ENA; 1632 return reg & ARIZONA_FLL1_ENA;
1527} 1633}
1528 1634
1529static void arizona_enable_fll(struct arizona_fll *fll, 1635static void arizona_enable_fll(struct arizona_fll *fll)
1530 struct arizona_fll_cfg *ref,
1531 struct arizona_fll_cfg *sync)
1532{ 1636{
1533 struct arizona *arizona = fll->arizona; 1637 struct arizona *arizona = fll->arizona;
1534 int ret; 1638 int ret;
1535 bool use_sync = false; 1639 bool use_sync = false;
1640 struct arizona_fll_cfg cfg;
1536 1641
1537 /* 1642 /*
1538 * If we have both REFCLK and SYNCCLK then enable both, 1643 * If we have both REFCLK and SYNCCLK then enable both,
@@ -1540,23 +1645,21 @@ static void arizona_enable_fll(struct arizona_fll *fll,
1540 */ 1645 */
1541 if (fll->ref_src >= 0 && fll->ref_freq && 1646 if (fll->ref_src >= 0 && fll->ref_freq &&
1542 fll->ref_src != fll->sync_src) { 1647 fll->ref_src != fll->sync_src) {
1543 regmap_update_bits_async(arizona->regmap, fll->base + 5, 1648 arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
1544 ARIZONA_FLL1_OUTDIV_MASK,
1545 ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1546 1649
1547 arizona_apply_fll(arizona, fll->base, ref, fll->ref_src, 1650 arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
1548 false); 1651 false);
1549 if (fll->sync_src >= 0) { 1652 if (fll->sync_src >= 0) {
1550 arizona_apply_fll(arizona, fll->base + 0x10, sync, 1653 arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
1654
1655 arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
1551 fll->sync_src, true); 1656 fll->sync_src, true);
1552 use_sync = true; 1657 use_sync = true;
1553 } 1658 }
1554 } else if (fll->sync_src >= 0) { 1659 } else if (fll->sync_src >= 0) {
1555 regmap_update_bits_async(arizona->regmap, fll->base + 5, 1660 arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
1556 ARIZONA_FLL1_OUTDIV_MASK,
1557 sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1558 1661
1559 arizona_apply_fll(arizona, fll->base, sync, 1662 arizona_apply_fll(arizona, fll->base, &cfg,
1560 fll->sync_src, false); 1663 fll->sync_src, false);
1561 1664
1562 regmap_update_bits_async(arizona->regmap, fll->base + 0x11, 1665 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
@@ -1618,32 +1721,22 @@ static void arizona_disable_fll(struct arizona_fll *fll)
1618int arizona_set_fll_refclk(struct arizona_fll *fll, int source, 1721int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1619 unsigned int Fref, unsigned int Fout) 1722 unsigned int Fref, unsigned int Fout)
1620{ 1723{
1621 struct arizona_fll_cfg ref, sync;
1622 int ret; 1724 int ret;
1623 1725
1624 if (fll->ref_src == source && fll->ref_freq == Fref) 1726 if (fll->ref_src == source && fll->ref_freq == Fref)
1625 return 0; 1727 return 0;
1626 1728
1627 if (fll->fout) { 1729 if (fll->fout && Fref > 0) {
1628 if (Fref > 0) { 1730 ret = arizona_validate_fll(fll, Fref, fll->fout);
1629 ret = arizona_calc_fll(fll, &ref, Fref, fll->fout); 1731 if (ret != 0)
1630 if (ret != 0) 1732 return ret;
1631 return ret;
1632 }
1633
1634 if (fll->sync_src >= 0) {
1635 ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
1636 fll->fout);
1637 if (ret != 0)
1638 return ret;
1639 }
1640 } 1733 }
1641 1734
1642 fll->ref_src = source; 1735 fll->ref_src = source;
1643 fll->ref_freq = Fref; 1736 fll->ref_freq = Fref;
1644 1737
1645 if (fll->fout && Fref > 0) { 1738 if (fll->fout && Fref > 0) {
1646 arizona_enable_fll(fll, &ref, &sync); 1739 arizona_enable_fll(fll);
1647 } 1740 }
1648 1741
1649 return 0; 1742 return 0;
@@ -1653,7 +1746,6 @@ EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1653int arizona_set_fll(struct arizona_fll *fll, int source, 1746int arizona_set_fll(struct arizona_fll *fll, int source,
1654 unsigned int Fref, unsigned int Fout) 1747 unsigned int Fref, unsigned int Fout)
1655{ 1748{
1656 struct arizona_fll_cfg ref, sync;
1657 int ret; 1749 int ret;
1658 1750
1659 if (fll->sync_src == source && 1751 if (fll->sync_src == source &&
@@ -1662,13 +1754,12 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1662 1754
1663 if (Fout) { 1755 if (Fout) {
1664 if (fll->ref_src >= 0) { 1756 if (fll->ref_src >= 0) {
1665 ret = arizona_calc_fll(fll, &ref, fll->ref_freq, 1757 ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
1666 Fout);
1667 if (ret != 0) 1758 if (ret != 0)
1668 return ret; 1759 return ret;
1669 } 1760 }
1670 1761
1671 ret = arizona_calc_fll(fll, &sync, Fref, Fout); 1762 ret = arizona_validate_fll(fll, Fref, Fout);
1672 if (ret != 0) 1763 if (ret != 0)
1673 return ret; 1764 return ret;
1674 } 1765 }
@@ -1678,7 +1769,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1678 fll->fout = Fout; 1769 fll->fout = Fout;
1679 1770
1680 if (Fout) { 1771 if (Fout) {
1681 arizona_enable_fll(fll, &ref, &sync); 1772 arizona_enable_fll(fll);
1682 } else { 1773 } else {
1683 arizona_disable_fll(fll); 1774 arizona_disable_fll(fll);
1684 } 1775 }
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index ce05fd93dc74..aef4965750c7 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -159,7 +159,6 @@ static bool cs4271_volatile_reg(struct device *dev, unsigned int reg)
159} 159}
160 160
161struct cs4271_private { 161struct cs4271_private {
162 /* SND_SOC_I2C or SND_SOC_SPI */
163 unsigned int mclk; 162 unsigned int mclk;
164 bool master; 163 bool master;
165 bool deemph; 164 bool deemph;
@@ -540,14 +539,10 @@ static int cs4271_probe(struct snd_soc_codec *codec)
540 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); 539 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
541 struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; 540 struct cs4271_platform_data *cs4271plat = codec->dev->platform_data;
542 int ret; 541 int ret;
543 int gpio_nreset = -EINVAL;
544 bool amutec_eq_bmutec = false; 542 bool amutec_eq_bmutec = false;
545 543
546#ifdef CONFIG_OF 544#ifdef CONFIG_OF
547 if (of_match_device(cs4271_dt_ids, codec->dev)) { 545 if (of_match_device(cs4271_dt_ids, codec->dev)) {
548 gpio_nreset = of_get_named_gpio(codec->dev->of_node,
549 "reset-gpio", 0);
550
551 if (of_get_property(codec->dev->of_node, 546 if (of_get_property(codec->dev->of_node,
552 "cirrus,amutec-eq-bmutec", NULL)) 547 "cirrus,amutec-eq-bmutec", NULL))
553 amutec_eq_bmutec = true; 548 amutec_eq_bmutec = true;
@@ -559,27 +554,19 @@ static int cs4271_probe(struct snd_soc_codec *codec)
559#endif 554#endif
560 555
561 if (cs4271plat) { 556 if (cs4271plat) {
562 if (gpio_is_valid(cs4271plat->gpio_nreset))
563 gpio_nreset = cs4271plat->gpio_nreset;
564
565 amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec; 557 amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec;
566 cs4271->enable_soft_reset = cs4271plat->enable_soft_reset; 558 cs4271->enable_soft_reset = cs4271plat->enable_soft_reset;
567 } 559 }
568 560
569 if (gpio_nreset >= 0) 561 if (gpio_is_valid(cs4271->gpio_nreset)) {
570 if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset"))
571 gpio_nreset = -EINVAL;
572 if (gpio_nreset >= 0) {
573 /* Reset codec */ 562 /* Reset codec */
574 gpio_direction_output(gpio_nreset, 0); 563 gpio_direction_output(cs4271->gpio_nreset, 0);
575 udelay(1); 564 udelay(1);
576 gpio_set_value(gpio_nreset, 1); 565 gpio_set_value(cs4271->gpio_nreset, 1);
577 /* Give the codec time to wake up */ 566 /* Give the codec time to wake up */
578 udelay(1); 567 udelay(1);
579 } 568 }
580 569
581 cs4271->gpio_nreset = gpio_nreset;
582
583 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, 570 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
584 CS4271_MODE2_PDN | CS4271_MODE2_CPEN, 571 CS4271_MODE2_PDN | CS4271_MODE2_CPEN,
585 CS4271_MODE2_PDN | CS4271_MODE2_CPEN); 572 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
@@ -625,6 +612,36 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
625 .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes), 612 .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes),
626}; 613};
627 614
615static int cs4271_common_probe(struct device *dev,
616 struct cs4271_private **c)
617{
618 struct cs4271_platform_data *cs4271plat = dev->platform_data;
619 struct cs4271_private *cs4271;
620
621 cs4271 = devm_kzalloc(dev, sizeof(*cs4271), GFP_KERNEL);
622 if (!cs4271)
623 return -ENOMEM;
624
625 if (of_match_device(cs4271_dt_ids, dev))
626 cs4271->gpio_nreset =
627 of_get_named_gpio(dev->of_node, "reset-gpio", 0);
628
629 if (cs4271plat)
630 cs4271->gpio_nreset = cs4271plat->gpio_nreset;
631
632 if (gpio_is_valid(cs4271->gpio_nreset)) {
633 int ret;
634
635 ret = devm_gpio_request(dev, cs4271->gpio_nreset,
636 "CS4271 Reset");
637 if (ret < 0)
638 return ret;
639 }
640
641 *c = cs4271;
642 return 0;
643}
644
628#if defined(CONFIG_SPI_MASTER) 645#if defined(CONFIG_SPI_MASTER)
629 646
630static const struct regmap_config cs4271_spi_regmap = { 647static const struct regmap_config cs4271_spi_regmap = {
@@ -644,10 +661,11 @@ static const struct regmap_config cs4271_spi_regmap = {
644static int cs4271_spi_probe(struct spi_device *spi) 661static int cs4271_spi_probe(struct spi_device *spi)
645{ 662{
646 struct cs4271_private *cs4271; 663 struct cs4271_private *cs4271;
664 int ret;
647 665
648 cs4271 = devm_kzalloc(&spi->dev, sizeof(*cs4271), GFP_KERNEL); 666 ret = cs4271_common_probe(&spi->dev, &cs4271);
649 if (!cs4271) 667 if (ret < 0)
650 return -ENOMEM; 668 return ret;
651 669
652 spi_set_drvdata(spi, cs4271); 670 spi_set_drvdata(spi, cs4271);
653 cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap); 671 cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap);
@@ -698,10 +716,11 @@ static int cs4271_i2c_probe(struct i2c_client *client,
698 const struct i2c_device_id *id) 716 const struct i2c_device_id *id)
699{ 717{
700 struct cs4271_private *cs4271; 718 struct cs4271_private *cs4271;
719 int ret;
701 720
702 cs4271 = devm_kzalloc(&client->dev, sizeof(*cs4271), GFP_KERNEL); 721 ret = cs4271_common_probe(&client->dev, &cs4271);
703 if (!cs4271) 722 if (ret < 0)
704 return -ENOMEM; 723 return ret;
705 724
706 i2c_set_clientdata(client, cs4271); 725 i2c_set_clientdata(client, cs4271);
707 cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap); 726 cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap);
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 6e9ea8379a91..3eab46020a30 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -30,6 +30,7 @@
30#include <sound/pcm_params.h> 30#include <sound/pcm_params.h>
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <linux/i2c.h> 32#include <linux/i2c.h>
33#include <linux/regmap.h>
33 34
34#include "cs42l51.h" 35#include "cs42l51.h"
35 36
@@ -40,7 +41,6 @@ enum master_slave_mode {
40}; 41};
41 42
42struct cs42l51_private { 43struct cs42l51_private {
43 enum snd_soc_control_type control_type;
44 unsigned int mclk; 44 unsigned int mclk;
45 unsigned int audio_mode; /* The mode (I2S or left-justified) */ 45 unsigned int audio_mode; /* The mode (I2S or left-justified) */
46 enum master_slave_mode func; 46 enum master_slave_mode func;
@@ -52,24 +52,6 @@ struct cs42l51_private {
52 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ 52 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
53 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) 53 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
54 54
55static int cs42l51_fill_cache(struct snd_soc_codec *codec)
56{
57 u8 *cache = codec->reg_cache + 1;
58 struct i2c_client *i2c_client = to_i2c_client(codec->dev);
59 s32 length;
60
61 length = i2c_smbus_read_i2c_block_data(i2c_client,
62 CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache);
63 if (length != CS42L51_NUMREGS) {
64 dev_err(&i2c_client->dev,
65 "I2C read failure, addr=0x%x (ret=%d vs %d)\n",
66 i2c_client->addr, length, CS42L51_NUMREGS);
67 return -EIO;
68 }
69
70 return 0;
71}
72
73static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, 55static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
74 struct snd_ctl_elem_value *ucontrol) 56 struct snd_ctl_elem_value *ucontrol)
75{ 57{
@@ -505,16 +487,9 @@ static struct snd_soc_dai_driver cs42l51_dai = {
505 487
506static int cs42l51_probe(struct snd_soc_codec *codec) 488static int cs42l51_probe(struct snd_soc_codec *codec)
507{ 489{
508 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
509 int ret, reg; 490 int ret, reg;
510 491
511 ret = cs42l51_fill_cache(codec); 492 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
512 if (ret < 0) {
513 dev_err(codec->dev, "failed to fill register cache\n");
514 return ret;
515 }
516
517 ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
518 if (ret < 0) { 493 if (ret < 0) {
519 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 494 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
520 return ret; 495 return ret;
@@ -538,8 +513,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
538 513
539static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { 514static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
540 .probe = cs42l51_probe, 515 .probe = cs42l51_probe,
541 .reg_cache_size = CS42L51_NUMREGS + 1,
542 .reg_word_size = sizeof(u8),
543 516
544 .controls = cs42l51_snd_controls, 517 .controls = cs42l51_snd_controls,
545 .num_controls = ARRAY_SIZE(cs42l51_snd_controls), 518 .num_controls = ARRAY_SIZE(cs42l51_snd_controls),
@@ -549,38 +522,53 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
549 .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), 522 .num_dapm_routes = ARRAY_SIZE(cs42l51_routes),
550}; 523};
551 524
525static const struct regmap_config cs42l51_regmap = {
526 .reg_bits = 8,
527 .val_bits = 8,
528
529 .max_register = CS42L51_CHARGE_FREQ,
530 .cache_type = REGCACHE_RBTREE,
531};
532
552static int cs42l51_i2c_probe(struct i2c_client *i2c_client, 533static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
553 const struct i2c_device_id *id) 534 const struct i2c_device_id *id)
554{ 535{
555 struct cs42l51_private *cs42l51; 536 struct cs42l51_private *cs42l51;
537 struct regmap *regmap;
538 unsigned int val;
556 int ret; 539 int ret;
557 540
541 regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap);
542 if (IS_ERR(regmap)) {
543 ret = PTR_ERR(regmap);
544 dev_err(&i2c_client->dev, "Failed to create regmap: %d\n",
545 ret);
546 return ret;
547 }
548
558 /* Verify that we have a CS42L51 */ 549 /* Verify that we have a CS42L51 */
559 ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID); 550 ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val);
560 if (ret < 0) { 551 if (ret < 0) {
561 dev_err(&i2c_client->dev, "failed to read I2C\n"); 552 dev_err(&i2c_client->dev, "failed to read I2C\n");
562 goto error; 553 goto error;
563 } 554 }
564 555
565 if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && 556 if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
566 (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { 557 (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
567 dev_err(&i2c_client->dev, "Invalid chip id\n"); 558 dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val);
568 ret = -ENODEV; 559 ret = -ENODEV;
569 goto error; 560 goto error;
570 } 561 }
571 562
572 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", 563 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
573 ret & 7); 564 val & 7);
574 565
575 cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private), 566 cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private),
576 GFP_KERNEL); 567 GFP_KERNEL);
577 if (!cs42l51) { 568 if (!cs42l51)
578 dev_err(&i2c_client->dev, "could not allocate codec\n");
579 return -ENOMEM; 569 return -ENOMEM;
580 }
581 570
582 i2c_set_clientdata(i2c_client, cs42l51); 571 i2c_set_clientdata(i2c_client, cs42l51);
583 cs42l51->control_type = SND_SOC_I2C;
584 572
585 ret = snd_soc_register_codec(&i2c_client->dev, 573 ret = snd_soc_register_codec(&i2c_client->dev,
586 &soc_codec_device_cs42l51, &cs42l51_dai, 1); 574 &soc_codec_device_cs42l51, &cs42l51_dai, 1);
@@ -600,10 +588,17 @@ static const struct i2c_device_id cs42l51_id[] = {
600}; 588};
601MODULE_DEVICE_TABLE(i2c, cs42l51_id); 589MODULE_DEVICE_TABLE(i2c, cs42l51_id);
602 590
591static const struct of_device_id cs42l51_of_match[] = {
592 { .compatible = "cirrus,cs42l51", },
593 { }
594};
595MODULE_DEVICE_TABLE(of, cs42l51_of_match);
596
603static struct i2c_driver cs42l51_i2c_driver = { 597static struct i2c_driver cs42l51_i2c_driver = {
604 .driver = { 598 .driver = {
605 .name = "cs42l51-codec", 599 .name = "cs42l51-codec",
606 .owner = THIS_MODULE, 600 .owner = THIS_MODULE,
601 .of_match_table = cs42l51_of_match,
607 }, 602 },
608 .id_table = cs42l51_id, 603 .id_table = cs42l51_id,
609 .probe = cs42l51_i2c_probe, 604 .probe = cs42l51_i2c_probe,
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 0bac6d5a4ac8..be455ea5f2fe 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -210,13 +210,11 @@ static const char * const cs42l52_adca_text[] = {
210static const char * const cs42l52_adcb_text[] = { 210static const char * const cs42l52_adcb_text[] = {
211 "Input1B", "Input2B", "Input3B", "Input4B", "PGA Input Right"}; 211 "Input1B", "Input2B", "Input3B", "Input4B", "PGA Input Right"};
212 212
213static const struct soc_enum adca_enum = 213static SOC_ENUM_SINGLE_DECL(adca_enum,
214 SOC_ENUM_SINGLE(CS42L52_ADC_PGA_A, 5, 214 CS42L52_ADC_PGA_A, 5, cs42l52_adca_text);
215 ARRAY_SIZE(cs42l52_adca_text), cs42l52_adca_text);
216 215
217static const struct soc_enum adcb_enum = 216static SOC_ENUM_SINGLE_DECL(adcb_enum,
218 SOC_ENUM_SINGLE(CS42L52_ADC_PGA_B, 5, 217 CS42L52_ADC_PGA_B, 5, cs42l52_adcb_text);
219 ARRAY_SIZE(cs42l52_adcb_text), cs42l52_adcb_text);
220 218
221static const struct snd_kcontrol_new adca_mux = 219static const struct snd_kcontrol_new adca_mux =
222 SOC_DAPM_ENUM("Left ADC Input Capture Mux", adca_enum); 220 SOC_DAPM_ENUM("Left ADC Input Capture Mux", adca_enum);
@@ -229,26 +227,22 @@ static const char * const mic_bias_level_text[] = {
229 "0.8 +VA", "0.83 +VA", "0.91 +VA" 227 "0.8 +VA", "0.83 +VA", "0.91 +VA"
230}; 228};
231 229
232static const struct soc_enum mic_bias_level_enum = 230static SOC_ENUM_SINGLE_DECL(mic_bias_level_enum,
233 SOC_ENUM_SINGLE(CS42L52_IFACE_CTL2, 0, 231 CS42L52_IFACE_CTL2, 0, mic_bias_level_text);
234 ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text);
235 232
236static const char * const cs42l52_mic_text[] = { "MIC1", "MIC2" }; 233static const char * const cs42l52_mic_text[] = { "MIC1", "MIC2" };
237 234
238static const struct soc_enum mica_enum = 235static SOC_ENUM_SINGLE_DECL(mica_enum,
239 SOC_ENUM_SINGLE(CS42L52_MICA_CTL, 5, 236 CS42L52_MICA_CTL, 5, cs42l52_mic_text);
240 ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text);
241 237
242static const struct soc_enum micb_enum = 238static SOC_ENUM_SINGLE_DECL(micb_enum,
243 SOC_ENUM_SINGLE(CS42L52_MICB_CTL, 5, 239 CS42L52_MICB_CTL, 5, cs42l52_mic_text);
244 ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text);
245 240
246static const char * const digital_output_mux_text[] = {"ADC", "DSP"}; 241static const char * const digital_output_mux_text[] = {"ADC", "DSP"};
247 242
248static const struct soc_enum digital_output_mux_enum = 243static SOC_ENUM_SINGLE_DECL(digital_output_mux_enum,
249 SOC_ENUM_SINGLE(CS42L52_ADC_MISC_CTL, 6, 244 CS42L52_ADC_MISC_CTL, 6,
250 ARRAY_SIZE(digital_output_mux_text), 245 digital_output_mux_text);
251 digital_output_mux_text);
252 246
253static const struct snd_kcontrol_new digital_output_mux = 247static const struct snd_kcontrol_new digital_output_mux =
254 SOC_DAPM_ENUM("Digital Output Mux", digital_output_mux_enum); 248 SOC_DAPM_ENUM("Digital Output Mux", digital_output_mux_enum);
@@ -258,18 +252,18 @@ static const char * const hp_gain_num_text[] = {
258 "0.7099", "0.8399", "1.000", "1.1430" 252 "0.7099", "0.8399", "1.000", "1.1430"
259}; 253};
260 254
261static const struct soc_enum hp_gain_enum = 255static SOC_ENUM_SINGLE_DECL(hp_gain_enum,
262 SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 5, 256 CS42L52_PB_CTL1, 5,
263 ARRAY_SIZE(hp_gain_num_text), hp_gain_num_text); 257 hp_gain_num_text);
264 258
265static const char * const beep_pitch_text[] = { 259static const char * const beep_pitch_text[] = {
266 "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5", 260 "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5",
267 "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7" 261 "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7"
268}; 262};
269 263
270static const struct soc_enum beep_pitch_enum = 264static SOC_ENUM_SINGLE_DECL(beep_pitch_enum,
271 SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 4, 265 CS42L52_BEEP_FREQ, 4,
272 ARRAY_SIZE(beep_pitch_text), beep_pitch_text); 266 beep_pitch_text);
273 267
274static const char * const beep_ontime_text[] = { 268static const char * const beep_ontime_text[] = {
275 "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s", 269 "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s",
@@ -277,66 +271,66 @@ static const char * const beep_ontime_text[] = {
277 "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s" 271 "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s"
278}; 272};
279 273
280static const struct soc_enum beep_ontime_enum = 274static SOC_ENUM_SINGLE_DECL(beep_ontime_enum,
281 SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 0, 275 CS42L52_BEEP_FREQ, 0,
282 ARRAY_SIZE(beep_ontime_text), beep_ontime_text); 276 beep_ontime_text);
283 277
284static const char * const beep_offtime_text[] = { 278static const char * const beep_offtime_text[] = {
285 "1.23 s", "2.58 s", "3.90 s", "5.20 s", 279 "1.23 s", "2.58 s", "3.90 s", "5.20 s",
286 "6.60 s", "8.05 s", "9.35 s", "10.80 s" 280 "6.60 s", "8.05 s", "9.35 s", "10.80 s"
287}; 281};
288 282
289static const struct soc_enum beep_offtime_enum = 283static SOC_ENUM_SINGLE_DECL(beep_offtime_enum,
290 SOC_ENUM_SINGLE(CS42L52_BEEP_VOL, 5, 284 CS42L52_BEEP_VOL, 5,
291 ARRAY_SIZE(beep_offtime_text), beep_offtime_text); 285 beep_offtime_text);
292 286
293static const char * const beep_config_text[] = { 287static const char * const beep_config_text[] = {
294 "Off", "Single", "Multiple", "Continuous" 288 "Off", "Single", "Multiple", "Continuous"
295}; 289};
296 290
297static const struct soc_enum beep_config_enum = 291static SOC_ENUM_SINGLE_DECL(beep_config_enum,
298 SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 6, 292 CS42L52_BEEP_TONE_CTL, 6,
299 ARRAY_SIZE(beep_config_text), beep_config_text); 293 beep_config_text);
300 294
301static const char * const beep_bass_text[] = { 295static const char * const beep_bass_text[] = {
302 "50 Hz", "100 Hz", "200 Hz", "250 Hz" 296 "50 Hz", "100 Hz", "200 Hz", "250 Hz"
303}; 297};
304 298
305static const struct soc_enum beep_bass_enum = 299static SOC_ENUM_SINGLE_DECL(beep_bass_enum,
306 SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 1, 300 CS42L52_BEEP_TONE_CTL, 1,
307 ARRAY_SIZE(beep_bass_text), beep_bass_text); 301 beep_bass_text);
308 302
309static const char * const beep_treble_text[] = { 303static const char * const beep_treble_text[] = {
310 "5 kHz", "7 kHz", "10 kHz", " 15 kHz" 304 "5 kHz", "7 kHz", "10 kHz", " 15 kHz"
311}; 305};
312 306
313static const struct soc_enum beep_treble_enum = 307static SOC_ENUM_SINGLE_DECL(beep_treble_enum,
314 SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 3, 308 CS42L52_BEEP_TONE_CTL, 3,
315 ARRAY_SIZE(beep_treble_text), beep_treble_text); 309 beep_treble_text);
316 310
317static const char * const ng_threshold_text[] = { 311static const char * const ng_threshold_text[] = {
318 "-34dB", "-37dB", "-40dB", "-43dB", 312 "-34dB", "-37dB", "-40dB", "-43dB",
319 "-46dB", "-52dB", "-58dB", "-64dB" 313 "-46dB", "-52dB", "-58dB", "-64dB"
320}; 314};
321 315
322static const struct soc_enum ng_threshold_enum = 316static SOC_ENUM_SINGLE_DECL(ng_threshold_enum,
323 SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 2, 317 CS42L52_NOISE_GATE_CTL, 2,
324 ARRAY_SIZE(ng_threshold_text), ng_threshold_text); 318 ng_threshold_text);
325 319
326static const char * const cs42l52_ng_delay_text[] = { 320static const char * const cs42l52_ng_delay_text[] = {
327 "50ms", "100ms", "150ms", "200ms"}; 321 "50ms", "100ms", "150ms", "200ms"};
328 322
329static const struct soc_enum ng_delay_enum = 323static SOC_ENUM_SINGLE_DECL(ng_delay_enum,
330 SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 0, 324 CS42L52_NOISE_GATE_CTL, 0,
331 ARRAY_SIZE(cs42l52_ng_delay_text), cs42l52_ng_delay_text); 325 cs42l52_ng_delay_text);
332 326
333static const char * const cs42l52_ng_type_text[] = { 327static const char * const cs42l52_ng_type_text[] = {
334 "Apply Specific", "Apply All" 328 "Apply Specific", "Apply All"
335}; 329};
336 330
337static const struct soc_enum ng_type_enum = 331static SOC_ENUM_SINGLE_DECL(ng_type_enum,
338 SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 6, 332 CS42L52_NOISE_GATE_CTL, 6,
339 ARRAY_SIZE(cs42l52_ng_type_text), cs42l52_ng_type_text); 333 cs42l52_ng_type_text);
340 334
341static const char * const left_swap_text[] = { 335static const char * const left_swap_text[] = {
342 "Left", "LR 2", "Right"}; 336 "Left", "LR 2", "Right"};
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index 549d5d6a3fef..06f429184821 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -278,13 +278,13 @@ static const DECLARE_TLV_DB_SCALE(attn_tlv, -6300, 100, 1);
278static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" }; 278static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" };
279static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" }; 279static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" };
280 280
281static const struct soc_enum pgaa_enum = 281static SOC_ENUM_SINGLE_DECL(pgaa_enum,
282 SOC_ENUM_SINGLE(CS42L73_ADCIPC, 3, 282 CS42L73_ADCIPC, 3,
283 ARRAY_SIZE(cs42l73_pgaa_text), cs42l73_pgaa_text); 283 cs42l73_pgaa_text);
284 284
285static const struct soc_enum pgab_enum = 285static SOC_ENUM_SINGLE_DECL(pgab_enum,
286 SOC_ENUM_SINGLE(CS42L73_ADCIPC, 7, 286 CS42L73_ADCIPC, 7,
287 ARRAY_SIZE(cs42l73_pgab_text), cs42l73_pgab_text); 287 cs42l73_pgab_text);
288 288
289static const struct snd_kcontrol_new pgaa_mux = 289static const struct snd_kcontrol_new pgaa_mux =
290 SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum); 290 SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum);
@@ -309,9 +309,9 @@ static const struct snd_kcontrol_new input_right_mixer[] = {
309static const char * const cs42l73_ng_delay_text[] = { 309static const char * const cs42l73_ng_delay_text[] = {
310 "50ms", "100ms", "150ms", "200ms" }; 310 "50ms", "100ms", "150ms", "200ms" };
311 311
312static const struct soc_enum ng_delay_enum = 312static SOC_ENUM_SINGLE_DECL(ng_delay_enum,
313 SOC_ENUM_SINGLE(CS42L73_NGCAB, 0, 313 CS42L73_NGCAB, 0,
314 ARRAY_SIZE(cs42l73_ng_delay_text), cs42l73_ng_delay_text); 314 cs42l73_ng_delay_text);
315 315
316static const char * const cs42l73_mono_mix_texts[] = { 316static const char * const cs42l73_mono_mix_texts[] = {
317 "Left", "Right", "Mono Mix"}; 317 "Left", "Right", "Mono Mix"};
@@ -357,19 +357,19 @@ static const struct snd_kcontrol_new esl_xsp_mixer =
357static const char * const cs42l73_ip_swap_text[] = { 357static const char * const cs42l73_ip_swap_text[] = {
358 "Stereo", "Mono A", "Mono B", "Swap A-B"}; 358 "Stereo", "Mono A", "Mono B", "Swap A-B"};
359 359
360static const struct soc_enum ip_swap_enum = 360static SOC_ENUM_SINGLE_DECL(ip_swap_enum,
361 SOC_ENUM_SINGLE(CS42L73_MIOPC, 6, 361 CS42L73_MIOPC, 6,
362 ARRAY_SIZE(cs42l73_ip_swap_text), cs42l73_ip_swap_text); 362 cs42l73_ip_swap_text);
363 363
364static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"}; 364static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"};
365 365
366static const struct soc_enum vsp_output_mux_enum = 366static SOC_ENUM_SINGLE_DECL(vsp_output_mux_enum,
367 SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 5, 367 CS42L73_MIXERCTL, 5,
368 ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text); 368 cs42l73_spo_mixer_text);
369 369
370static const struct soc_enum xsp_output_mux_enum = 370static SOC_ENUM_SINGLE_DECL(xsp_output_mux_enum,
371 SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 4, 371 CS42L73_MIXERCTL, 4,
372 ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text); 372 cs42l73_spo_mixer_text);
373 373
374static const struct snd_kcontrol_new vsp_output_mux = 374static const struct snd_kcontrol_new vsp_output_mux =
375 SOC_DAPM_ENUM("Route", vsp_output_mux_enum); 375 SOC_DAPM_ENUM("Route", vsp_output_mux_enum);
@@ -1108,7 +1108,7 @@ static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1108 return 0; 1108 return 0;
1109} 1109}
1110 1110
1111static u32 cs42l73_asrc_rates[] = { 1111static const unsigned int cs42l73_asrc_rates[] = {
1112 8000, 11025, 12000, 16000, 22050, 1112 8000, 11025, 12000, 16000, 22050,
1113 24000, 32000, 44100, 48000 1113 24000, 32000, 44100, 48000
1114}; 1114};
@@ -1241,7 +1241,7 @@ static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate)
1241 0x7F, tristate << 7); 1241 0x7F, tristate << 7);
1242} 1242}
1243 1243
1244static struct snd_pcm_hw_constraint_list constraints_12_24 = { 1244static const struct snd_pcm_hw_constraint_list constraints_12_24 = {
1245 .count = ARRAY_SIZE(cs42l73_asrc_rates), 1245 .count = ARRAY_SIZE(cs42l73_asrc_rates),
1246 .list = cs42l73_asrc_rates, 1246 .list = cs42l73_asrc_rates,
1247}; 1247};
@@ -1255,9 +1255,6 @@ static int cs42l73_pcm_startup(struct snd_pcm_substream *substream,
1255 return 0; 1255 return 0;
1256} 1256}
1257 1257
1258/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */
1259#define CS42L73_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT)
1260
1261 1258
1262#define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 1259#define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1263 SNDRV_PCM_FMTBIT_S24_LE) 1260 SNDRV_PCM_FMTBIT_S24_LE)
@@ -1278,14 +1275,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
1278 .stream_name = "XSP Playback", 1275 .stream_name = "XSP Playback",
1279 .channels_min = 1, 1276 .channels_min = 1,
1280 .channels_max = 2, 1277 .channels_max = 2,
1281 .rates = CS42L73_RATES, 1278 .rates = SNDRV_PCM_RATE_KNOT,
1282 .formats = CS42L73_FORMATS, 1279 .formats = CS42L73_FORMATS,
1283 }, 1280 },
1284 .capture = { 1281 .capture = {
1285 .stream_name = "XSP Capture", 1282 .stream_name = "XSP Capture",
1286 .channels_min = 1, 1283 .channels_min = 1,
1287 .channels_max = 2, 1284 .channels_max = 2,
1288 .rates = CS42L73_RATES, 1285 .rates = SNDRV_PCM_RATE_KNOT,
1289 .formats = CS42L73_FORMATS, 1286 .formats = CS42L73_FORMATS,
1290 }, 1287 },
1291 .ops = &cs42l73_ops, 1288 .ops = &cs42l73_ops,
@@ -1298,14 +1295,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
1298 .stream_name = "ASP Playback", 1295 .stream_name = "ASP Playback",
1299 .channels_min = 2, 1296 .channels_min = 2,
1300 .channels_max = 2, 1297 .channels_max = 2,
1301 .rates = CS42L73_RATES, 1298 .rates = SNDRV_PCM_RATE_KNOT,
1302 .formats = CS42L73_FORMATS, 1299 .formats = CS42L73_FORMATS,
1303 }, 1300 },
1304 .capture = { 1301 .capture = {
1305 .stream_name = "ASP Capture", 1302 .stream_name = "ASP Capture",
1306 .channels_min = 2, 1303 .channels_min = 2,
1307 .channels_max = 2, 1304 .channels_max = 2,
1308 .rates = CS42L73_RATES, 1305 .rates = SNDRV_PCM_RATE_KNOT,
1309 .formats = CS42L73_FORMATS, 1306 .formats = CS42L73_FORMATS,
1310 }, 1307 },
1311 .ops = &cs42l73_ops, 1308 .ops = &cs42l73_ops,
@@ -1318,14 +1315,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
1318 .stream_name = "VSP Playback", 1315 .stream_name = "VSP Playback",
1319 .channels_min = 1, 1316 .channels_min = 1,
1320 .channels_max = 2, 1317 .channels_max = 2,
1321 .rates = CS42L73_RATES, 1318 .rates = SNDRV_PCM_RATE_KNOT,
1322 .formats = CS42L73_FORMATS, 1319 .formats = CS42L73_FORMATS,
1323 }, 1320 },
1324 .capture = { 1321 .capture = {
1325 .stream_name = "VSP Capture", 1322 .stream_name = "VSP Capture",
1326 .channels_min = 1, 1323 .channels_min = 1,
1327 .channels_max = 2, 1324 .channels_max = 2,
1328 .rates = CS42L73_RATES, 1325 .rates = SNDRV_PCM_RATE_KNOT,
1329 .formats = CS42L73_FORMATS, 1326 .formats = CS42L73_FORMATS,
1330 }, 1327 },
1331 .ops = &cs42l73_ops, 1328 .ops = &cs42l73_ops,
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index e62e294a8033..01e55fc72307 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -307,29 +307,29 @@ static const char * const da7210_hpf_cutoff_txt[] = {
307 "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi" 307 "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi"
308}; 308};
309 309
310static const struct soc_enum da7210_dac_hpf_cutoff = 310static SOC_ENUM_SINGLE_DECL(da7210_dac_hpf_cutoff,
311 SOC_ENUM_SINGLE(DA7210_DAC_HPF, 0, 4, da7210_hpf_cutoff_txt); 311 DA7210_DAC_HPF, 0, da7210_hpf_cutoff_txt);
312 312
313static const struct soc_enum da7210_adc_hpf_cutoff = 313static SOC_ENUM_SINGLE_DECL(da7210_adc_hpf_cutoff,
314 SOC_ENUM_SINGLE(DA7210_ADC_HPF, 0, 4, da7210_hpf_cutoff_txt); 314 DA7210_ADC_HPF, 0, da7210_hpf_cutoff_txt);
315 315
316/* ADC and DAC voice (8kHz) high pass cutoff value */ 316/* ADC and DAC voice (8kHz) high pass cutoff value */
317static const char * const da7210_vf_cutoff_txt[] = { 317static const char * const da7210_vf_cutoff_txt[] = {
318 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" 318 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
319}; 319};
320 320
321static const struct soc_enum da7210_dac_vf_cutoff = 321static SOC_ENUM_SINGLE_DECL(da7210_dac_vf_cutoff,
322 SOC_ENUM_SINGLE(DA7210_DAC_HPF, 4, 8, da7210_vf_cutoff_txt); 322 DA7210_DAC_HPF, 4, da7210_vf_cutoff_txt);
323 323
324static const struct soc_enum da7210_adc_vf_cutoff = 324static SOC_ENUM_SINGLE_DECL(da7210_adc_vf_cutoff,
325 SOC_ENUM_SINGLE(DA7210_ADC_HPF, 4, 8, da7210_vf_cutoff_txt); 325 DA7210_ADC_HPF, 4, da7210_vf_cutoff_txt);
326 326
327static const char *da7210_hp_mode_txt[] = { 327static const char *da7210_hp_mode_txt[] = {
328 "Class H", "Class G" 328 "Class H", "Class G"
329}; 329};
330 330
331static const struct soc_enum da7210_hp_mode_sel = 331static SOC_ENUM_SINGLE_DECL(da7210_hp_mode_sel,
332 SOC_ENUM_SINGLE(DA7210_HP_CFG, 0, 2, da7210_hp_mode_txt); 332 DA7210_HP_CFG, 0, da7210_hp_mode_txt);
333 333
334/* ALC can be enabled only if noise suppression is disabled */ 334/* ALC can be enabled only if noise suppression is disabled */
335static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, 335static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index 0c77e7ad7423..439d10387f10 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -63,30 +63,30 @@ static const char * const da7213_voice_hpf_corner_txt[] = {
63 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" 63 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
64}; 64};
65 65
66static const struct soc_enum da7213_dac_voice_hpf_corner = 66static SOC_ENUM_SINGLE_DECL(da7213_dac_voice_hpf_corner,
67 SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT, 67 DA7213_DAC_FILTERS1,
68 DA7213_VOICE_HPF_CORNER_MAX, 68 DA7213_VOICE_HPF_CORNER_SHIFT,
69 da7213_voice_hpf_corner_txt); 69 da7213_voice_hpf_corner_txt);
70 70
71static const struct soc_enum da7213_adc_voice_hpf_corner = 71static SOC_ENUM_SINGLE_DECL(da7213_adc_voice_hpf_corner,
72 SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT, 72 DA7213_ADC_FILTERS1,
73 DA7213_VOICE_HPF_CORNER_MAX, 73 DA7213_VOICE_HPF_CORNER_SHIFT,
74 da7213_voice_hpf_corner_txt); 74 da7213_voice_hpf_corner_txt);
75 75
76/* ADC and DAC high pass filter cutoff value */ 76/* ADC and DAC high pass filter cutoff value */
77static const char * const da7213_audio_hpf_corner_txt[] = { 77static const char * const da7213_audio_hpf_corner_txt[] = {
78 "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000" 78 "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
79}; 79};
80 80
81static const struct soc_enum da7213_dac_audio_hpf_corner = 81static SOC_ENUM_SINGLE_DECL(da7213_dac_audio_hpf_corner,
82 SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT, 82 DA7213_DAC_FILTERS1
83 DA7213_AUDIO_HPF_CORNER_MAX, 83 , DA7213_AUDIO_HPF_CORNER_SHIFT,
84 da7213_audio_hpf_corner_txt); 84 da7213_audio_hpf_corner_txt);
85 85
86static const struct soc_enum da7213_adc_audio_hpf_corner = 86static SOC_ENUM_SINGLE_DECL(da7213_adc_audio_hpf_corner,
87 SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT, 87 DA7213_ADC_FILTERS1,
88 DA7213_AUDIO_HPF_CORNER_MAX, 88 DA7213_AUDIO_HPF_CORNER_SHIFT,
89 da7213_audio_hpf_corner_txt); 89 da7213_audio_hpf_corner_txt);
90 90
91/* Gain ramping rate value */ 91/* Gain ramping rate value */
92static const char * const da7213_gain_ramp_rate_txt[] = { 92static const char * const da7213_gain_ramp_rate_txt[] = {
@@ -94,52 +94,50 @@ static const char * const da7213_gain_ramp_rate_txt[] = {
94 "nominal rate / 32" 94 "nominal rate / 32"
95}; 95};
96 96
97static const struct soc_enum da7213_gain_ramp_rate = 97static SOC_ENUM_SINGLE_DECL(da7213_gain_ramp_rate,
98 SOC_ENUM_SINGLE(DA7213_GAIN_RAMP_CTRL, DA7213_GAIN_RAMP_RATE_SHIFT, 98 DA7213_GAIN_RAMP_CTRL,
99 DA7213_GAIN_RAMP_RATE_MAX, da7213_gain_ramp_rate_txt); 99 DA7213_GAIN_RAMP_RATE_SHIFT,
100 da7213_gain_ramp_rate_txt);
100 101
101/* DAC noise gate setup time value */ 102/* DAC noise gate setup time value */
102static const char * const da7213_dac_ng_setup_time_txt[] = { 103static const char * const da7213_dac_ng_setup_time_txt[] = {
103 "256 samples", "512 samples", "1024 samples", "2048 samples" 104 "256 samples", "512 samples", "1024 samples", "2048 samples"
104}; 105};
105 106
106static const struct soc_enum da7213_dac_ng_setup_time = 107static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_setup_time,
107 SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME, 108 DA7213_DAC_NG_SETUP_TIME,
108 DA7213_DAC_NG_SETUP_TIME_SHIFT, 109 DA7213_DAC_NG_SETUP_TIME_SHIFT,
109 DA7213_DAC_NG_SETUP_TIME_MAX, 110 da7213_dac_ng_setup_time_txt);
110 da7213_dac_ng_setup_time_txt);
111 111
112/* DAC noise gate rampup rate value */ 112/* DAC noise gate rampup rate value */
113static const char * const da7213_dac_ng_rampup_txt[] = { 113static const char * const da7213_dac_ng_rampup_txt[] = {
114 "0.02 ms/dB", "0.16 ms/dB" 114 "0.02 ms/dB", "0.16 ms/dB"
115}; 115};
116 116
117static const struct soc_enum da7213_dac_ng_rampup_rate = 117static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_rampup_rate,
118 SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME, 118 DA7213_DAC_NG_SETUP_TIME,
119 DA7213_DAC_NG_RAMPUP_RATE_SHIFT, 119 DA7213_DAC_NG_RAMPUP_RATE_SHIFT,
120 DA7213_DAC_NG_RAMP_RATE_MAX, 120 da7213_dac_ng_rampup_txt);
121 da7213_dac_ng_rampup_txt);
122 121
123/* DAC noise gate rampdown rate value */ 122/* DAC noise gate rampdown rate value */
124static const char * const da7213_dac_ng_rampdown_txt[] = { 123static const char * const da7213_dac_ng_rampdown_txt[] = {
125 "0.64 ms/dB", "20.48 ms/dB" 124 "0.64 ms/dB", "20.48 ms/dB"
126}; 125};
127 126
128static const struct soc_enum da7213_dac_ng_rampdown_rate = 127static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_rampdown_rate,
129 SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME, 128 DA7213_DAC_NG_SETUP_TIME,
130 DA7213_DAC_NG_RAMPDN_RATE_SHIFT, 129 DA7213_DAC_NG_RAMPDN_RATE_SHIFT,
131 DA7213_DAC_NG_RAMP_RATE_MAX, 130 da7213_dac_ng_rampdown_txt);
132 da7213_dac_ng_rampdown_txt);
133 131
134/* DAC soft mute rate value */ 132/* DAC soft mute rate value */
135static const char * const da7213_dac_soft_mute_rate_txt[] = { 133static const char * const da7213_dac_soft_mute_rate_txt[] = {
136 "1", "2", "4", "8", "16", "32", "64" 134 "1", "2", "4", "8", "16", "32", "64"
137}; 135};
138 136
139static const struct soc_enum da7213_dac_soft_mute_rate = 137static SOC_ENUM_SINGLE_DECL(da7213_dac_soft_mute_rate,
140 SOC_ENUM_SINGLE(DA7213_DAC_FILTERS5, DA7213_DAC_SOFTMUTE_RATE_SHIFT, 138 DA7213_DAC_FILTERS5,
141 DA7213_DAC_SOFTMUTE_RATE_MAX, 139 DA7213_DAC_SOFTMUTE_RATE_SHIFT,
142 da7213_dac_soft_mute_rate_txt); 140 da7213_dac_soft_mute_rate_txt);
143 141
144/* ALC Attack Rate select */ 142/* ALC Attack Rate select */
145static const char * const da7213_alc_attack_rate_txt[] = { 143static const char * const da7213_alc_attack_rate_txt[] = {
@@ -147,9 +145,10 @@ static const char * const da7213_alc_attack_rate_txt[] = {
147 "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" 145 "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
148}; 146};
149 147
150static const struct soc_enum da7213_alc_attack_rate = 148static SOC_ENUM_SINGLE_DECL(da7213_alc_attack_rate,
151 SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_ATTACK_SHIFT, 149 DA7213_ALC_CTRL2,
152 DA7213_ALC_ATTACK_MAX, da7213_alc_attack_rate_txt); 150 DA7213_ALC_ATTACK_SHIFT,
151 da7213_alc_attack_rate_txt);
153 152
154/* ALC Release Rate select */ 153/* ALC Release Rate select */
155static const char * const da7213_alc_release_rate_txt[] = { 154static const char * const da7213_alc_release_rate_txt[] = {
@@ -157,9 +156,10 @@ static const char * const da7213_alc_release_rate_txt[] = {
157 "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" 156 "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
158}; 157};
159 158
160static const struct soc_enum da7213_alc_release_rate = 159static SOC_ENUM_SINGLE_DECL(da7213_alc_release_rate,
161 SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_RELEASE_SHIFT, 160 DA7213_ALC_CTRL2,
162 DA7213_ALC_RELEASE_MAX, da7213_alc_release_rate_txt); 161 DA7213_ALC_RELEASE_SHIFT,
162 da7213_alc_release_rate_txt);
163 163
164/* ALC Hold Time select */ 164/* ALC Hold Time select */
165static const char * const da7213_alc_hold_time_txt[] = { 165static const char * const da7213_alc_hold_time_txt[] = {
@@ -168,22 +168,25 @@ static const char * const da7213_alc_hold_time_txt[] = {
168 "253952/fs", "507904/fs", "1015808/fs", "2031616/fs" 168 "253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
169}; 169};
170 170
171static const struct soc_enum da7213_alc_hold_time = 171static SOC_ENUM_SINGLE_DECL(da7213_alc_hold_time,
172 SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_HOLD_SHIFT, 172 DA7213_ALC_CTRL3,
173 DA7213_ALC_HOLD_MAX, da7213_alc_hold_time_txt); 173 DA7213_ALC_HOLD_SHIFT,
174 da7213_alc_hold_time_txt);
174 175
175/* ALC Input Signal Tracking rate select */ 176/* ALC Input Signal Tracking rate select */
176static const char * const da7213_alc_integ_rate_txt[] = { 177static const char * const da7213_alc_integ_rate_txt[] = {
177 "1/4", "1/16", "1/256", "1/65536" 178 "1/4", "1/16", "1/256", "1/65536"
178}; 179};
179 180
180static const struct soc_enum da7213_alc_integ_attack_rate = 181static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_attack_rate,
181 SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_ATTACK_SHIFT, 182 DA7213_ALC_CTRL3,
182 DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt); 183 DA7213_ALC_INTEG_ATTACK_SHIFT,
184 da7213_alc_integ_rate_txt);
183 185
184static const struct soc_enum da7213_alc_integ_release_rate = 186static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_release_rate,
185 SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_RELEASE_SHIFT, 187 DA7213_ALC_CTRL3,
186 DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt); 188 DA7213_ALC_INTEG_RELEASE_SHIFT,
189 da7213_alc_integ_rate_txt);
187 190
188 191
189/* 192/*
@@ -584,15 +587,17 @@ static const char * const da7213_mic_amp_in_sel_txt[] = {
584 "Differential", "MIC_P", "MIC_N" 587 "Differential", "MIC_P", "MIC_N"
585}; 588};
586 589
587static const struct soc_enum da7213_mic_1_amp_in_sel = 590static SOC_ENUM_SINGLE_DECL(da7213_mic_1_amp_in_sel,
588 SOC_ENUM_SINGLE(DA7213_MIC_1_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT, 591 DA7213_MIC_1_CTRL,
589 DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt); 592 DA7213_MIC_AMP_IN_SEL_SHIFT,
593 da7213_mic_amp_in_sel_txt);
590static const struct snd_kcontrol_new da7213_mic_1_amp_in_sel_mux = 594static const struct snd_kcontrol_new da7213_mic_1_amp_in_sel_mux =
591 SOC_DAPM_ENUM("Mic 1 Amp Source MUX", da7213_mic_1_amp_in_sel); 595 SOC_DAPM_ENUM("Mic 1 Amp Source MUX", da7213_mic_1_amp_in_sel);
592 596
593static const struct soc_enum da7213_mic_2_amp_in_sel = 597static SOC_ENUM_SINGLE_DECL(da7213_mic_2_amp_in_sel,
594 SOC_ENUM_SINGLE(DA7213_MIC_2_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT, 598 DA7213_MIC_2_CTRL,
595 DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt); 599 DA7213_MIC_AMP_IN_SEL_SHIFT,
600 da7213_mic_amp_in_sel_txt);
596static const struct snd_kcontrol_new da7213_mic_2_amp_in_sel_mux = 601static const struct snd_kcontrol_new da7213_mic_2_amp_in_sel_mux =
597 SOC_DAPM_ENUM("Mic 2 Amp Source MUX", da7213_mic_2_amp_in_sel); 602 SOC_DAPM_ENUM("Mic 2 Amp Source MUX", da7213_mic_2_amp_in_sel);
598 603
@@ -601,15 +606,17 @@ static const char * const da7213_dai_src_txt[] = {
601 "ADC Left", "ADC Right", "DAI Input Left", "DAI Input Right" 606 "ADC Left", "ADC Right", "DAI Input Left", "DAI Input Right"
602}; 607};
603 608
604static const struct soc_enum da7213_dai_l_src = 609static SOC_ENUM_SINGLE_DECL(da7213_dai_l_src,
605 SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_L_SRC_SHIFT, 610 DA7213_DIG_ROUTING_DAI,
606 DA7213_DAI_SRC_MAX, da7213_dai_src_txt); 611 DA7213_DAI_L_SRC_SHIFT,
612 da7213_dai_src_txt);
607static const struct snd_kcontrol_new da7213_dai_l_src_mux = 613static const struct snd_kcontrol_new da7213_dai_l_src_mux =
608 SOC_DAPM_ENUM("DAI Left Source MUX", da7213_dai_l_src); 614 SOC_DAPM_ENUM("DAI Left Source MUX", da7213_dai_l_src);
609 615
610static const struct soc_enum da7213_dai_r_src = 616static SOC_ENUM_SINGLE_DECL(da7213_dai_r_src,
611 SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_R_SRC_SHIFT, 617 DA7213_DIG_ROUTING_DAI,
612 DA7213_DAI_SRC_MAX, da7213_dai_src_txt); 618 DA7213_DAI_R_SRC_SHIFT,
619 da7213_dai_src_txt);
613static const struct snd_kcontrol_new da7213_dai_r_src_mux = 620static const struct snd_kcontrol_new da7213_dai_r_src_mux =
614 SOC_DAPM_ENUM("DAI Right Source MUX", da7213_dai_r_src); 621 SOC_DAPM_ENUM("DAI Right Source MUX", da7213_dai_r_src);
615 622
@@ -619,15 +626,17 @@ static const char * const da7213_dac_src_txt[] = {
619 "DAI Input Right" 626 "DAI Input Right"
620}; 627};
621 628
622static const struct soc_enum da7213_dac_l_src = 629static SOC_ENUM_SINGLE_DECL(da7213_dac_l_src,
623 SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_L_SRC_SHIFT, 630 DA7213_DIG_ROUTING_DAC,
624 DA7213_DAC_SRC_MAX, da7213_dac_src_txt); 631 DA7213_DAC_L_SRC_SHIFT,
632 da7213_dac_src_txt);
625static const struct snd_kcontrol_new da7213_dac_l_src_mux = 633static const struct snd_kcontrol_new da7213_dac_l_src_mux =
626 SOC_DAPM_ENUM("DAC Left Source MUX", da7213_dac_l_src); 634 SOC_DAPM_ENUM("DAC Left Source MUX", da7213_dac_l_src);
627 635
628static const struct soc_enum da7213_dac_r_src = 636static SOC_ENUM_SINGLE_DECL(da7213_dac_r_src,
629 SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_R_SRC_SHIFT, 637 DA7213_DIG_ROUTING_DAC,
630 DA7213_DAC_SRC_MAX, da7213_dac_src_txt); 638 DA7213_DAC_R_SRC_SHIFT,
639 da7213_dac_src_txt);
631static const struct snd_kcontrol_new da7213_dac_r_src_mux = 640static const struct snd_kcontrol_new da7213_dac_r_src_mux =
632 SOC_DAPM_ENUM("DAC Right Source MUX", da7213_dac_r_src); 641 SOC_DAPM_ENUM("DAC Right Source MUX", da7213_dac_r_src);
633 642
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c
index f295b6569910..4d1c302f5a76 100644
--- a/sound/soc/codecs/da732x.c
+++ b/sound/soc/codecs/da732x.c
@@ -269,81 +269,65 @@ static const char *da732x_hpf_voice[] = {
269 "150Hz", "200Hz", "300Hz", "400Hz" 269 "150Hz", "200Hz", "300Hz", "400Hz"
270}; 270};
271 271
272static const struct soc_enum da732x_dac1_hpf_mode_enum[] = { 272static SOC_ENUM_SINGLE_DECL(da732x_dac1_hpf_mode_enum,
273 SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT, 273 DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT,
274 DA732X_HPF_MODE_MAX, da732x_hpf_mode) 274 da732x_hpf_mode);
275};
276 275
277static const struct soc_enum da732x_dac2_hpf_mode_enum[] = { 276static SOC_ENUM_SINGLE_DECL(da732x_dac2_hpf_mode_enum,
278 SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT, 277 DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT,
279 DA732X_HPF_MODE_MAX, da732x_hpf_mode) 278 da732x_hpf_mode);
280};
281 279
282static const struct soc_enum da732x_dac3_hpf_mode_enum[] = { 280static SOC_ENUM_SINGLE_DECL(da732x_dac3_hpf_mode_enum,
283 SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT, 281 DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT,
284 DA732X_HPF_MODE_MAX, da732x_hpf_mode) 282 da732x_hpf_mode);
285};
286 283
287static const struct soc_enum da732x_adc1_hpf_mode_enum[] = { 284static SOC_ENUM_SINGLE_DECL(da732x_adc1_hpf_mode_enum,
288 SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT, 285 DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT,
289 DA732X_HPF_MODE_MAX, da732x_hpf_mode) 286 da732x_hpf_mode);
290};
291 287
292static const struct soc_enum da732x_adc2_hpf_mode_enum[] = { 288static SOC_ENUM_SINGLE_DECL(da732x_adc2_hpf_mode_enum,
293 SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT, 289 DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT,
294 DA732X_HPF_MODE_MAX, da732x_hpf_mode) 290 da732x_hpf_mode);
295};
296 291
297static const struct soc_enum da732x_dac1_hp_filter_enum[] = { 292static SOC_ENUM_SINGLE_DECL(da732x_dac1_hp_filter_enum,
298 SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT, 293 DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT,
299 DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 294 da732x_hpf_music);
300};
301 295
302static const struct soc_enum da732x_dac2_hp_filter_enum[] = { 296static SOC_ENUM_SINGLE_DECL(da732x_dac2_hp_filter_enum,
303 SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT, 297 DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT,
304 DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 298 da732x_hpf_music);
305};
306 299
307static const struct soc_enum da732x_dac3_hp_filter_enum[] = { 300static SOC_ENUM_SINGLE_DECL(da732x_dac3_hp_filter_enum,
308 SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT, 301 DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT,
309 DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 302 da732x_hpf_music);
310};
311 303
312static const struct soc_enum da732x_adc1_hp_filter_enum[] = { 304static SOC_ENUM_SINGLE_DECL(da732x_adc1_hp_filter_enum,
313 SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT, 305 DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT,
314 DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 306 da732x_hpf_music);
315};
316 307
317static const struct soc_enum da732x_adc2_hp_filter_enum[] = { 308static SOC_ENUM_SINGLE_DECL(da732x_adc2_hp_filter_enum,
318 SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT, 309 DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT,
319 DA732X_HPF_MUSIC_MAX, da732x_hpf_music) 310 da732x_hpf_music);
320};
321 311
322static const struct soc_enum da732x_dac1_voice_filter_enum[] = { 312static SOC_ENUM_SINGLE_DECL(da732x_dac1_voice_filter_enum,
323 SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT, 313 DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT,
324 DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 314 da732x_hpf_voice);
325};
326 315
327static const struct soc_enum da732x_dac2_voice_filter_enum[] = { 316static SOC_ENUM_SINGLE_DECL(da732x_dac2_voice_filter_enum,
328 SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT, 317 DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT,
329 DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 318 da732x_hpf_voice);
330};
331 319
332static const struct soc_enum da732x_dac3_voice_filter_enum[] = { 320static SOC_ENUM_SINGLE_DECL(da732x_dac3_voice_filter_enum,
333 SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT, 321 DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT,
334 DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 322 da732x_hpf_voice);
335};
336 323
337static const struct soc_enum da732x_adc1_voice_filter_enum[] = { 324static SOC_ENUM_SINGLE_DECL(da732x_adc1_voice_filter_enum,
338 SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT, 325 DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT,
339 DA732X_HPF_VOICE_MAX, da732x_hpf_voice) 326 da732x_hpf_voice);
340};
341
342static const struct soc_enum da732x_adc2_voice_filter_enum[] = {
343 SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT,
344 DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
345};
346 327
328static SOC_ENUM_SINGLE_DECL(da732x_adc2_voice_filter_enum,
329 DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT,
330 da732x_hpf_voice);
347 331
348static int da732x_hpf_set(struct snd_kcontrol *kcontrol, 332static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
349 struct snd_ctl_elem_value *ucontrol) 333 struct snd_ctl_elem_value *ucontrol)
@@ -714,65 +698,65 @@ static const char *enable_text[] = {
714}; 698};
715 699
716/* ADC1LMUX */ 700/* ADC1LMUX */
717static const struct soc_enum adc1l_enum = 701static SOC_ENUM_SINGLE_DECL(adc1l_enum,
718 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT, 702 DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT,
719 DA732X_ADCL_MUX_MAX, adcl_text); 703 adcl_text);
720static const struct snd_kcontrol_new adc1l_mux = 704static const struct snd_kcontrol_new adc1l_mux =
721 SOC_DAPM_ENUM("ADC Route", adc1l_enum); 705 SOC_DAPM_ENUM("ADC Route", adc1l_enum);
722 706
723/* ADC1RMUX */ 707/* ADC1RMUX */
724static const struct soc_enum adc1r_enum = 708static SOC_ENUM_SINGLE_DECL(adc1r_enum,
725 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT, 709 DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT,
726 DA732X_ADCR_MUX_MAX, adcr_text); 710 adcr_text);
727static const struct snd_kcontrol_new adc1r_mux = 711static const struct snd_kcontrol_new adc1r_mux =
728 SOC_DAPM_ENUM("ADC Route", adc1r_enum); 712 SOC_DAPM_ENUM("ADC Route", adc1r_enum);
729 713
730/* ADC2LMUX */ 714/* ADC2LMUX */
731static const struct soc_enum adc2l_enum = 715static SOC_ENUM_SINGLE_DECL(adc2l_enum,
732 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT, 716 DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT,
733 DA732X_ADCL_MUX_MAX, adcl_text); 717 adcl_text);
734static const struct snd_kcontrol_new adc2l_mux = 718static const struct snd_kcontrol_new adc2l_mux =
735 SOC_DAPM_ENUM("ADC Route", adc2l_enum); 719 SOC_DAPM_ENUM("ADC Route", adc2l_enum);
736 720
737/* ADC2RMUX */ 721/* ADC2RMUX */
738static const struct soc_enum adc2r_enum = 722static SOC_ENUM_SINGLE_DECL(adc2r_enum,
739 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT, 723 DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT,
740 DA732X_ADCR_MUX_MAX, adcr_text); 724 adcr_text);
741 725
742static const struct snd_kcontrol_new adc2r_mux = 726static const struct snd_kcontrol_new adc2r_mux =
743 SOC_DAPM_ENUM("ADC Route", adc2r_enum); 727 SOC_DAPM_ENUM("ADC Route", adc2r_enum);
744 728
745static const struct soc_enum da732x_hp_left_output = 729static SOC_ENUM_SINGLE_DECL(da732x_hp_left_output,
746 SOC_ENUM_SINGLE(DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT, 730 DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT,
747 DA732X_DAC_EN_MAX, enable_text); 731 enable_text);
748 732
749static const struct snd_kcontrol_new hpl_mux = 733static const struct snd_kcontrol_new hpl_mux =
750 SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output); 734 SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output);
751 735
752static const struct soc_enum da732x_hp_right_output = 736static SOC_ENUM_SINGLE_DECL(da732x_hp_right_output,
753 SOC_ENUM_SINGLE(DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT, 737 DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT,
754 DA732X_DAC_EN_MAX, enable_text); 738 enable_text);
755 739
756static const struct snd_kcontrol_new hpr_mux = 740static const struct snd_kcontrol_new hpr_mux =
757 SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output); 741 SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output);
758 742
759static const struct soc_enum da732x_speaker_output = 743static SOC_ENUM_SINGLE_DECL(da732x_speaker_output,
760 SOC_ENUM_SINGLE(DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT, 744 DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT,
761 DA732X_DAC_EN_MAX, enable_text); 745 enable_text);
762 746
763static const struct snd_kcontrol_new spk_mux = 747static const struct snd_kcontrol_new spk_mux =
764 SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output); 748 SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output);
765 749
766static const struct soc_enum da732x_lout4_output = 750static SOC_ENUM_SINGLE_DECL(da732x_lout4_output,
767 SOC_ENUM_SINGLE(DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT, 751 DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT,
768 DA732X_DAC_EN_MAX, enable_text); 752 enable_text);
769 753
770static const struct snd_kcontrol_new lout4_mux = 754static const struct snd_kcontrol_new lout4_mux =
771 SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output); 755 SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output);
772 756
773static const struct soc_enum da732x_lout2_output = 757static SOC_ENUM_SINGLE_DECL(da732x_lout2_output,
774 SOC_ENUM_SINGLE(DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT, 758 DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT,
775 DA732X_DAC_EN_MAX, enable_text); 759 enable_text);
776 760
777static const struct snd_kcontrol_new lout2_mux = 761static const struct snd_kcontrol_new lout2_mux =
778 SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output); 762 SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output);
@@ -1268,11 +1252,23 @@ static struct snd_soc_dai_driver da732x_dai[] = {
1268 }, 1252 },
1269}; 1253};
1270 1254
1255static bool da732x_volatile(struct device *dev, unsigned int reg)
1256{
1257 switch (reg) {
1258 case DA732X_REG_HPL_DAC_OFF_CNTL:
1259 case DA732X_REG_HPR_DAC_OFF_CNTL:
1260 return true;
1261 default:
1262 return false;
1263 }
1264}
1265
1271static const struct regmap_config da732x_regmap = { 1266static const struct regmap_config da732x_regmap = {
1272 .reg_bits = 8, 1267 .reg_bits = 8,
1273 .val_bits = 8, 1268 .val_bits = 8,
1274 1269
1275 .max_register = DA732X_MAX_REG, 1270 .max_register = DA732X_MAX_REG,
1271 .volatile_reg = da732x_volatile,
1276 .reg_defaults = da732x_reg_cache, 1272 .reg_defaults = da732x_reg_cache,
1277 .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), 1273 .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache),
1278 .cache_type = REGCACHE_RBTREE, 1274 .cache_type = REGCACHE_RBTREE,
@@ -1487,8 +1483,8 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
1487 1483
1488 da732x_hp_dc_offset_cancellation(codec); 1484 da732x_hp_dc_offset_cancellation(codec);
1489 1485
1490 regcache_cache_only(codec->control_data, false); 1486 regcache_cache_only(da732x->regmap, false);
1491 regcache_sync(codec->control_data); 1487 regcache_sync(da732x->regmap);
1492 } else { 1488 } else {
1493 snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, 1489 snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
1494 DA732X_BIAS_BOOST_MASK, 1490 DA732X_BIAS_BOOST_MASK,
@@ -1499,7 +1495,7 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
1499 } 1495 }
1500 break; 1496 break;
1501 case SND_SOC_BIAS_OFF: 1497 case SND_SOC_BIAS_OFF:
1502 regcache_cache_only(codec->control_data, true); 1498 regcache_cache_only(da732x->regmap, true);
1503 da732x_set_charge_pump(codec, DA732X_DISABLE_CP); 1499 da732x_set_charge_pump(codec, DA732X_DISABLE_CP);
1504 snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN, 1500 snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN,
1505 DA732X_BIAS_DIS); 1501 DA732X_BIAS_DIS);
@@ -1554,7 +1550,6 @@ static struct snd_soc_codec_driver soc_codec_dev_da732x = {
1554 .dapm_routes = da732x_dapm_routes, 1550 .dapm_routes = da732x_dapm_routes,
1555 .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), 1551 .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes),
1556 .set_pll = da732x_set_dai_pll, 1552 .set_pll = da732x_set_dai_pll,
1557 .reg_cache_size = ARRAY_SIZE(da732x_reg_cache),
1558}; 1553};
1559 1554
1560static int da732x_i2c_probe(struct i2c_client *i2c, 1555static int da732x_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/da732x.h b/sound/soc/codecs/da732x.h
index c8ce5475de22..1dceafeec415 100644
--- a/sound/soc/codecs/da732x.h
+++ b/sound/soc/codecs/da732x.h
@@ -113,9 +113,6 @@
113#define DA732X_EQ_OVERALL_VOL_DB_MIN -1800 113#define DA732X_EQ_OVERALL_VOL_DB_MIN -1800
114#define DA732X_EQ_OVERALL_VOL_DB_INC 600 114#define DA732X_EQ_OVERALL_VOL_DB_INC 600
115 115
116#define DA732X_SOC_ENUM_DOUBLE_R(xreg, xrreg, xmax, xtext) \
117 {.reg = xreg, .reg2 = xrreg, .max = xmax, .texts = xtext}
118
119enum da732x_sysctl { 116enum da732x_sysctl {
120 DA732X_SR_8KHZ = 0x1, 117 DA732X_SR_8KHZ = 0x1,
121 DA732X_SR_11_025KHZ = 0x2, 118 DA732X_SR_11_025KHZ = 0x2,
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c
index 52b79a487ac7..f118daa91234 100644
--- a/sound/soc/codecs/da9055.c
+++ b/sound/soc/codecs/da9055.c
@@ -18,6 +18,8 @@
18#include <linux/regmap.h> 18#include <linux/regmap.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
21#include <sound/pcm.h> 23#include <sound/pcm.h>
22#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
23#include <sound/soc.h> 25#include <sound/soc.h>
@@ -321,22 +323,22 @@ static const char * const da9055_hpf_cutoff_txt[] = {
321 "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000" 323 "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
322}; 324};
323 325
324static const struct soc_enum da9055_dac_hpf_cutoff = 326static SOC_ENUM_SINGLE_DECL(da9055_dac_hpf_cutoff,
325 SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt); 327 DA9055_DAC_FILTERS1, 4, da9055_hpf_cutoff_txt);
326 328
327static const struct soc_enum da9055_adc_hpf_cutoff = 329static SOC_ENUM_SINGLE_DECL(da9055_adc_hpf_cutoff,
328 SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt); 330 DA9055_ADC_FILTERS1, 4, da9055_hpf_cutoff_txt);
329 331
330/* ADC and DAC voice mode (8kHz) high pass cutoff value */ 332/* ADC and DAC voice mode (8kHz) high pass cutoff value */
331static const char * const da9055_vf_cutoff_txt[] = { 333static const char * const da9055_vf_cutoff_txt[] = {
332 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" 334 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
333}; 335};
334 336
335static const struct soc_enum da9055_dac_vf_cutoff = 337static SOC_ENUM_SINGLE_DECL(da9055_dac_vf_cutoff,
336 SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 0, 8, da9055_vf_cutoff_txt); 338 DA9055_DAC_FILTERS1, 0, da9055_vf_cutoff_txt);
337 339
338static const struct soc_enum da9055_adc_vf_cutoff = 340static SOC_ENUM_SINGLE_DECL(da9055_adc_vf_cutoff,
339 SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 0, 8, da9055_vf_cutoff_txt); 341 DA9055_ADC_FILTERS1, 0, da9055_vf_cutoff_txt);
340 342
341/* Gain ramping rate value */ 343/* Gain ramping rate value */
342static const char * const da9055_gain_ramping_txt[] = { 344static const char * const da9055_gain_ramping_txt[] = {
@@ -344,44 +346,44 @@ static const char * const da9055_gain_ramping_txt[] = {
344 "nominal rate / 8" 346 "nominal rate / 8"
345}; 347};
346 348
347static const struct soc_enum da9055_gain_ramping_rate = 349static SOC_ENUM_SINGLE_DECL(da9055_gain_ramping_rate,
348 SOC_ENUM_SINGLE(DA9055_GAIN_RAMP_CTRL, 0, 4, da9055_gain_ramping_txt); 350 DA9055_GAIN_RAMP_CTRL, 0, da9055_gain_ramping_txt);
349 351
350/* DAC noise gate setup time value */ 352/* DAC noise gate setup time value */
351static const char * const da9055_dac_ng_setup_time_txt[] = { 353static const char * const da9055_dac_ng_setup_time_txt[] = {
352 "256 samples", "512 samples", "1024 samples", "2048 samples" 354 "256 samples", "512 samples", "1024 samples", "2048 samples"
353}; 355};
354 356
355static const struct soc_enum da9055_dac_ng_setup_time = 357static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_setup_time,
356 SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 0, 4, 358 DA9055_DAC_NG_SETUP_TIME, 0,
357 da9055_dac_ng_setup_time_txt); 359 da9055_dac_ng_setup_time_txt);
358 360
359/* DAC noise gate rampup rate value */ 361/* DAC noise gate rampup rate value */
360static const char * const da9055_dac_ng_rampup_txt[] = { 362static const char * const da9055_dac_ng_rampup_txt[] = {
361 "0.02 ms/dB", "0.16 ms/dB" 363 "0.02 ms/dB", "0.16 ms/dB"
362}; 364};
363 365
364static const struct soc_enum da9055_dac_ng_rampup_rate = 366static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_rampup_rate,
365 SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 2, 2, 367 DA9055_DAC_NG_SETUP_TIME, 2,
366 da9055_dac_ng_rampup_txt); 368 da9055_dac_ng_rampup_txt);
367 369
368/* DAC noise gate rampdown rate value */ 370/* DAC noise gate rampdown rate value */
369static const char * const da9055_dac_ng_rampdown_txt[] = { 371static const char * const da9055_dac_ng_rampdown_txt[] = {
370 "0.64 ms/dB", "20.48 ms/dB" 372 "0.64 ms/dB", "20.48 ms/dB"
371}; 373};
372 374
373static const struct soc_enum da9055_dac_ng_rampdown_rate = 375static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_rampdown_rate,
374 SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 3, 2, 376 DA9055_DAC_NG_SETUP_TIME, 3,
375 da9055_dac_ng_rampdown_txt); 377 da9055_dac_ng_rampdown_txt);
376 378
377/* DAC soft mute rate value */ 379/* DAC soft mute rate value */
378static const char * const da9055_dac_soft_mute_rate_txt[] = { 380static const char * const da9055_dac_soft_mute_rate_txt[] = {
379 "1", "2", "4", "8", "16", "32", "64" 381 "1", "2", "4", "8", "16", "32", "64"
380}; 382};
381 383
382static const struct soc_enum da9055_dac_soft_mute_rate = 384static SOC_ENUM_SINGLE_DECL(da9055_dac_soft_mute_rate,
383 SOC_ENUM_SINGLE(DA9055_DAC_FILTERS5, 4, 7, 385 DA9055_DAC_FILTERS5, 4,
384 da9055_dac_soft_mute_rate_txt); 386 da9055_dac_soft_mute_rate_txt);
385 387
386/* DAC routing select */ 388/* DAC routing select */
387static const char * const da9055_dac_src_txt[] = { 389static const char * const da9055_dac_src_txt[] = {
@@ -389,40 +391,40 @@ static const char * const da9055_dac_src_txt[] = {
389 "AIF input right" 391 "AIF input right"
390}; 392};
391 393
392static const struct soc_enum da9055_dac_l_src = 394static SOC_ENUM_SINGLE_DECL(da9055_dac_l_src,
393 SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 0, 4, da9055_dac_src_txt); 395 DA9055_DIG_ROUTING_DAC, 0, da9055_dac_src_txt);
394 396
395static const struct soc_enum da9055_dac_r_src = 397static SOC_ENUM_SINGLE_DECL(da9055_dac_r_src,
396 SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 4, 4, da9055_dac_src_txt); 398 DA9055_DIG_ROUTING_DAC, 4, da9055_dac_src_txt);
397 399
398/* MIC PGA Left source select */ 400/* MIC PGA Left source select */
399static const char * const da9055_mic_l_src_txt[] = { 401static const char * const da9055_mic_l_src_txt[] = {
400 "MIC1_P_N", "MIC1_P", "MIC1_N", "MIC2_L" 402 "MIC1_P_N", "MIC1_P", "MIC1_N", "MIC2_L"
401}; 403};
402 404
403static const struct soc_enum da9055_mic_l_src = 405static SOC_ENUM_SINGLE_DECL(da9055_mic_l_src,
404 SOC_ENUM_SINGLE(DA9055_MIXIN_L_SELECT, 4, 4, da9055_mic_l_src_txt); 406 DA9055_MIXIN_L_SELECT, 4, da9055_mic_l_src_txt);
405 407
406/* MIC PGA Right source select */ 408/* MIC PGA Right source select */
407static const char * const da9055_mic_r_src_txt[] = { 409static const char * const da9055_mic_r_src_txt[] = {
408 "MIC2_R_L", "MIC2_R", "MIC2_L" 410 "MIC2_R_L", "MIC2_R", "MIC2_L"
409}; 411};
410 412
411static const struct soc_enum da9055_mic_r_src = 413static SOC_ENUM_SINGLE_DECL(da9055_mic_r_src,
412 SOC_ENUM_SINGLE(DA9055_MIXIN_R_SELECT, 4, 3, da9055_mic_r_src_txt); 414 DA9055_MIXIN_R_SELECT, 4, da9055_mic_r_src_txt);
413 415
414/* ALC Input Signal Tracking rate select */ 416/* ALC Input Signal Tracking rate select */
415static const char * const da9055_signal_tracking_rate_txt[] = { 417static const char * const da9055_signal_tracking_rate_txt[] = {
416 "1/4", "1/16", "1/256", "1/65536" 418 "1/4", "1/16", "1/256", "1/65536"
417}; 419};
418 420
419static const struct soc_enum da9055_integ_attack_rate = 421static SOC_ENUM_SINGLE_DECL(da9055_integ_attack_rate,
420 SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 4, 4, 422 DA9055_ALC_CTRL3, 4,
421 da9055_signal_tracking_rate_txt); 423 da9055_signal_tracking_rate_txt);
422 424
423static const struct soc_enum da9055_integ_release_rate = 425static SOC_ENUM_SINGLE_DECL(da9055_integ_release_rate,
424 SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 6, 4, 426 DA9055_ALC_CTRL3, 6,
425 da9055_signal_tracking_rate_txt); 427 da9055_signal_tracking_rate_txt);
426 428
427/* ALC Attack Rate select */ 429/* ALC Attack Rate select */
428static const char * const da9055_attack_rate_txt[] = { 430static const char * const da9055_attack_rate_txt[] = {
@@ -430,8 +432,8 @@ static const char * const da9055_attack_rate_txt[] = {
430 "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" 432 "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
431}; 433};
432 434
433static const struct soc_enum da9055_attack_rate = 435static SOC_ENUM_SINGLE_DECL(da9055_attack_rate,
434 SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 0, 13, da9055_attack_rate_txt); 436 DA9055_ALC_CTRL2, 0, da9055_attack_rate_txt);
435 437
436/* ALC Release Rate select */ 438/* ALC Release Rate select */
437static const char * const da9055_release_rate_txt[] = { 439static const char * const da9055_release_rate_txt[] = {
@@ -439,8 +441,8 @@ static const char * const da9055_release_rate_txt[] = {
439 "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" 441 "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
440}; 442};
441 443
442static const struct soc_enum da9055_release_rate = 444static SOC_ENUM_SINGLE_DECL(da9055_release_rate,
443 SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 4, 11, da9055_release_rate_txt); 445 DA9055_ALC_CTRL2, 4, da9055_release_rate_txt);
444 446
445/* ALC Hold Time select */ 447/* ALC Hold Time select */
446static const char * const da9055_hold_time_txt[] = { 448static const char * const da9055_hold_time_txt[] = {
@@ -449,8 +451,8 @@ static const char * const da9055_hold_time_txt[] = {
449 "253952/fs", "507904/fs", "1015808/fs", "2031616/fs" 451 "253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
450}; 452};
451 453
452static const struct soc_enum da9055_hold_time = 454static SOC_ENUM_SINGLE_DECL(da9055_hold_time,
453 SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 0, 16, da9055_hold_time_txt); 455 DA9055_ALC_CTRL3, 0, da9055_hold_time_txt);
454 456
455static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val) 457static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
456{ 458{
@@ -1523,17 +1525,30 @@ static int da9055_remove(struct i2c_client *client)
1523 return 0; 1525 return 0;
1524} 1526}
1525 1527
1528/*
1529 * DO NOT change the device Ids. The naming is intentionally specific as both
1530 * the CODEC and PMIC parts of this chip are instantiated separately as I2C
1531 * devices (both have configurable I2C addresses, and are to all intents and
1532 * purposes separate). As a result there are specific DA9055 Ids for CODEC
1533 * and PMIC, which must be different to operate together.
1534 */
1526static const struct i2c_device_id da9055_i2c_id[] = { 1535static const struct i2c_device_id da9055_i2c_id[] = {
1527 { "da9055", 0 }, 1536 { "da9055-codec", 0 },
1528 { } 1537 { }
1529}; 1538};
1530MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); 1539MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);
1531 1540
1541static const struct of_device_id da9055_of_match[] = {
1542 { .compatible = "dlg,da9055-codec", },
1543 { }
1544};
1545
1532/* I2C codec control layer */ 1546/* I2C codec control layer */
1533static struct i2c_driver da9055_i2c_driver = { 1547static struct i2c_driver da9055_i2c_driver = {
1534 .driver = { 1548 .driver = {
1535 .name = "da9055", 1549 .name = "da9055-codec",
1536 .owner = THIS_MODULE, 1550 .owner = THIS_MODULE,
1551 .of_match_table = of_match_ptr(da9055_of_match),
1537 }, 1552 },
1538 .probe = da9055_i2c_probe, 1553 .probe = da9055_i2c_probe,
1539 .remove = da9055_remove, 1554 .remove = da9055_remove,
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
index 5839048ec467..cb736ddc446d 100644
--- a/sound/soc/codecs/isabelle.c
+++ b/sound/soc/codecs/isabelle.c
@@ -140,13 +140,17 @@ static const char *isabelle_rx1_texts[] = {"VRX1", "ARX1"};
140static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"}; 140static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"};
141 141
142static const struct soc_enum isabelle_rx1_enum[] = { 142static const struct soc_enum isabelle_rx1_enum[] = {
143 SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, 1, isabelle_rx1_texts), 143 SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3,
144 SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, 1, isabelle_rx1_texts), 144 ARRAY_SIZE(isabelle_rx1_texts), isabelle_rx1_texts),
145 SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5,
146 ARRAY_SIZE(isabelle_rx1_texts), isabelle_rx1_texts),
145}; 147};
146 148
147static const struct soc_enum isabelle_rx2_enum[] = { 149static const struct soc_enum isabelle_rx2_enum[] = {
148 SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, 1, isabelle_rx2_texts), 150 SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2,
149 SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, 1, isabelle_rx2_texts), 151 ARRAY_SIZE(isabelle_rx2_texts), isabelle_rx2_texts),
152 SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4,
153 ARRAY_SIZE(isabelle_rx2_texts), isabelle_rx2_texts),
150}; 154};
151 155
152/* Headset DAC playback switches */ 156/* Headset DAC playback switches */
@@ -161,13 +165,17 @@ static const char *isabelle_atx_texts[] = {"AMIC1", "DMIC"};
161static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"}; 165static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"};
162 166
163static const struct soc_enum isabelle_atx_enum[] = { 167static const struct soc_enum isabelle_atx_enum[] = {
164 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, 1, isabelle_atx_texts), 168 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7,
165 SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_atx_texts), 169 ARRAY_SIZE(isabelle_atx_texts), isabelle_atx_texts),
170 SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0,
171 ARRAY_SIZE(isabelle_atx_texts), isabelle_atx_texts),
166}; 172};
167 173
168static const struct soc_enum isabelle_vtx_enum[] = { 174static const struct soc_enum isabelle_vtx_enum[] = {
169 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, 1, isabelle_vtx_texts), 175 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6,
170 SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_vtx_texts), 176 ARRAY_SIZE(isabelle_vtx_texts), isabelle_vtx_texts),
177 SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0,
178 ARRAY_SIZE(isabelle_vtx_texts), isabelle_vtx_texts),
171}; 179};
172 180
173static const struct snd_kcontrol_new atx_mux_controls = 181static const struct snd_kcontrol_new atx_mux_controls =
@@ -183,17 +191,13 @@ static const char *isabelle_amic1_texts[] = {
183/* Left analog microphone selection */ 191/* Left analog microphone selection */
184static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"}; 192static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"};
185 193
186static const struct soc_enum isabelle_amic1_enum[] = { 194static SOC_ENUM_SINGLE_DECL(isabelle_amic1_enum,
187 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 5, 195 ISABELLE_AMIC_CFG_REG, 5,
188 ARRAY_SIZE(isabelle_amic1_texts), 196 isabelle_amic1_texts);
189 isabelle_amic1_texts),
190};
191 197
192static const struct soc_enum isabelle_amic2_enum[] = { 198static SOC_ENUM_SINGLE_DECL(isabelle_amic2_enum,
193 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 4, 199 ISABELLE_AMIC_CFG_REG, 4,
194 ARRAY_SIZE(isabelle_amic2_texts), 200 isabelle_amic2_texts);
195 isabelle_amic2_texts),
196};
197 201
198static const struct snd_kcontrol_new amic1_control = 202static const struct snd_kcontrol_new amic1_control =
199 SOC_DAPM_ENUM("Route", isabelle_amic1_enum); 203 SOC_DAPM_ENUM("Route", isabelle_amic1_enum);
@@ -206,16 +210,20 @@ static const char *isabelle_st_audio_texts[] = {"ATX1", "ATX2"};
206static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"}; 210static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"};
207 211
208static const struct soc_enum isabelle_st_audio_enum[] = { 212static const struct soc_enum isabelle_st_audio_enum[] = {
209 SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, 1, 213 SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7,
214 ARRAY_SIZE(isabelle_st_audio_texts),
210 isabelle_st_audio_texts), 215 isabelle_st_audio_texts),
211 SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, 1, 216 SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7,
217 ARRAY_SIZE(isabelle_st_audio_texts),
212 isabelle_st_audio_texts), 218 isabelle_st_audio_texts),
213}; 219};
214 220
215static const struct soc_enum isabelle_st_voice_enum[] = { 221static const struct soc_enum isabelle_st_voice_enum[] = {
216 SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, 1, 222 SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7,
223 ARRAY_SIZE(isabelle_st_voice_texts),
217 isabelle_st_voice_texts), 224 isabelle_st_voice_texts),
218 SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, 1, 225 SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7,
226 ARRAY_SIZE(isabelle_st_voice_texts),
219 isabelle_st_voice_texts), 227 isabelle_st_voice_texts),
220}; 228};
221 229
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
index e19490cfb3a8..6b7fe5e54881 100644
--- a/sound/soc/codecs/lm49453.c
+++ b/sound/soc/codecs/lm49453.c
@@ -195,18 +195,18 @@ struct lm49453_priv {
195 195
196static const char *lm49453_mic2mode_text[] = {"Single Ended", "Differential"}; 196static const char *lm49453_mic2mode_text[] = {"Single Ended", "Differential"};
197 197
198static const SOC_ENUM_SINGLE_DECL(lm49453_mic2mode_enum, LM49453_P0_MICR_REG, 5, 198static SOC_ENUM_SINGLE_DECL(lm49453_mic2mode_enum, LM49453_P0_MICR_REG, 5,
199 lm49453_mic2mode_text); 199 lm49453_mic2mode_text);
200 200
201static const char *lm49453_dmic_cfg_text[] = {"DMICDAT1", "DMICDAT2"}; 201static const char *lm49453_dmic_cfg_text[] = {"DMICDAT1", "DMICDAT2"};
202 202
203static const SOC_ENUM_SINGLE_DECL(lm49453_dmic12_cfg_enum, 203static SOC_ENUM_SINGLE_DECL(lm49453_dmic12_cfg_enum,
204 LM49453_P0_DIGITAL_MIC1_CONFIG_REG, 204 LM49453_P0_DIGITAL_MIC1_CONFIG_REG, 7,
205 7, lm49453_dmic_cfg_text); 205 lm49453_dmic_cfg_text);
206 206
207static const SOC_ENUM_SINGLE_DECL(lm49453_dmic34_cfg_enum, 207static SOC_ENUM_SINGLE_DECL(lm49453_dmic34_cfg_enum,
208 LM49453_P0_DIGITAL_MIC2_CONFIG_REG, 208 LM49453_P0_DIGITAL_MIC2_CONFIG_REG, 7,
209 7, lm49453_dmic_cfg_text); 209 lm49453_dmic_cfg_text);
210 210
211/* MUX Controls */ 211/* MUX Controls */
212static const char *lm49453_adcl_mux_text[] = { "MIC1", "Aux_L" }; 212static const char *lm49453_adcl_mux_text[] = { "MIC1", "Aux_L" };
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index ee660e2d3df3..bb1ecfc4459b 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1849,7 +1849,7 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
1849 1849
1850 /* Now point the soc_enum to .texts array items */ 1850 /* Now point the soc_enum to .texts array items */
1851 max98088->eq_enum.texts = max98088->eq_texts; 1851 max98088->eq_enum.texts = max98088->eq_texts;
1852 max98088->eq_enum.max = max98088->eq_textcnt; 1852 max98088->eq_enum.items = max98088->eq_textcnt;
1853 1853
1854 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); 1854 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
1855 if (ret != 0) 1855 if (ret != 0)
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 51f9b3d16b41..f363de19be07 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -336,6 +336,7 @@ static bool max98090_readable_register(struct device *dev, unsigned int reg)
336 case M98090_REG_RECORD_TDM_SLOT: 336 case M98090_REG_RECORD_TDM_SLOT:
337 case M98090_REG_SAMPLE_RATE: 337 case M98090_REG_SAMPLE_RATE:
338 case M98090_REG_DMIC34_BIQUAD_BASE ... M98090_REG_DMIC34_BIQUAD_BASE + 0x0E: 338 case M98090_REG_DMIC34_BIQUAD_BASE ... M98090_REG_DMIC34_BIQUAD_BASE + 0x0E:
339 case M98090_REG_REVISION_ID:
339 return true; 340 return true;
340 default: 341 default:
341 return false; 342 return false;
@@ -512,65 +513,75 @@ static const char *max98090_perf_pwr_text[] =
512static const char *max98090_pwr_perf_text[] = 513static const char *max98090_pwr_perf_text[] =
513 { "Low Power", "High Performance" }; 514 { "Low Power", "High Performance" };
514 515
515static const struct soc_enum max98090_vcmbandgap_enum = 516static SOC_ENUM_SINGLE_DECL(max98090_vcmbandgap_enum,
516 SOC_ENUM_SINGLE(M98090_REG_BIAS_CONTROL, M98090_VCM_MODE_SHIFT, 517 M98090_REG_BIAS_CONTROL,
517 ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); 518 M98090_VCM_MODE_SHIFT,
519 max98090_pwr_perf_text);
518 520
519static const char *max98090_osr128_text[] = { "64*fs", "128*fs" }; 521static const char *max98090_osr128_text[] = { "64*fs", "128*fs" };
520 522
521static const struct soc_enum max98090_osr128_enum = 523static SOC_ENUM_SINGLE_DECL(max98090_osr128_enum,
522 SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_OSR128_SHIFT, 524 M98090_REG_ADC_CONTROL,
523 ARRAY_SIZE(max98090_osr128_text), max98090_osr128_text); 525 M98090_OSR128_SHIFT,
526 max98090_osr128_text);
524 527
525static const char *max98090_mode_text[] = { "Voice", "Music" }; 528static const char *max98090_mode_text[] = { "Voice", "Music" };
526 529
527static const struct soc_enum max98090_mode_enum = 530static SOC_ENUM_SINGLE_DECL(max98090_mode_enum,
528 SOC_ENUM_SINGLE(M98090_REG_FILTER_CONFIG, M98090_MODE_SHIFT, 531 M98090_REG_FILTER_CONFIG,
529 ARRAY_SIZE(max98090_mode_text), max98090_mode_text); 532 M98090_MODE_SHIFT,
533 max98090_mode_text);
530 534
531static const struct soc_enum max98090_filter_dmic34mode_enum = 535static SOC_ENUM_SINGLE_DECL(max98090_filter_dmic34mode_enum,
532 SOC_ENUM_SINGLE(M98090_REG_FILTER_CONFIG, 536 M98090_REG_FILTER_CONFIG,
533 M98090_FLT_DMIC34MODE_SHIFT, 537 M98090_FLT_DMIC34MODE_SHIFT,
534 ARRAY_SIZE(max98090_mode_text), max98090_mode_text); 538 max98090_mode_text);
535 539
536static const char *max98090_drcatk_text[] = 540static const char *max98090_drcatk_text[] =
537 { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" }; 541 { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" };
538 542
539static const struct soc_enum max98090_drcatk_enum = 543static SOC_ENUM_SINGLE_DECL(max98090_drcatk_enum,
540 SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCATK_SHIFT, 544 M98090_REG_DRC_TIMING,
541 ARRAY_SIZE(max98090_drcatk_text), max98090_drcatk_text); 545 M98090_DRCATK_SHIFT,
546 max98090_drcatk_text);
542 547
543static const char *max98090_drcrls_text[] = 548static const char *max98090_drcrls_text[] =
544 { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" }; 549 { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" };
545 550
546static const struct soc_enum max98090_drcrls_enum = 551static SOC_ENUM_SINGLE_DECL(max98090_drcrls_enum,
547 SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCRLS_SHIFT, 552 M98090_REG_DRC_TIMING,
548 ARRAY_SIZE(max98090_drcrls_text), max98090_drcrls_text); 553 M98090_DRCRLS_SHIFT,
554 max98090_drcrls_text);
549 555
550static const char *max98090_alccmp_text[] = 556static const char *max98090_alccmp_text[] =
551 { "1:1", "1:1.5", "1:2", "1:4", "1:INF" }; 557 { "1:1", "1:1.5", "1:2", "1:4", "1:INF" };
552 558
553static const struct soc_enum max98090_alccmp_enum = 559static SOC_ENUM_SINGLE_DECL(max98090_alccmp_enum,
554 SOC_ENUM_SINGLE(M98090_REG_DRC_COMPRESSOR, M98090_DRCCMP_SHIFT, 560 M98090_REG_DRC_COMPRESSOR,
555 ARRAY_SIZE(max98090_alccmp_text), max98090_alccmp_text); 561 M98090_DRCCMP_SHIFT,
562 max98090_alccmp_text);
556 563
557static const char *max98090_drcexp_text[] = { "1:1", "2:1", "3:1" }; 564static const char *max98090_drcexp_text[] = { "1:1", "2:1", "3:1" };
558 565
559static const struct soc_enum max98090_drcexp_enum = 566static SOC_ENUM_SINGLE_DECL(max98090_drcexp_enum,
560 SOC_ENUM_SINGLE(M98090_REG_DRC_EXPANDER, M98090_DRCEXP_SHIFT, 567 M98090_REG_DRC_EXPANDER,
561 ARRAY_SIZE(max98090_drcexp_text), max98090_drcexp_text); 568 M98090_DRCEXP_SHIFT,
569 max98090_drcexp_text);
562 570
563static const struct soc_enum max98090_dac_perfmode_enum = 571static SOC_ENUM_SINGLE_DECL(max98090_dac_perfmode_enum,
564 SOC_ENUM_SINGLE(M98090_REG_DAC_CONTROL, M98090_PERFMODE_SHIFT, 572 M98090_REG_DAC_CONTROL,
565 ARRAY_SIZE(max98090_perf_pwr_text), max98090_perf_pwr_text); 573 M98090_PERFMODE_SHIFT,
574 max98090_perf_pwr_text);
566 575
567static const struct soc_enum max98090_dachp_enum = 576static SOC_ENUM_SINGLE_DECL(max98090_dachp_enum,
568 SOC_ENUM_SINGLE(M98090_REG_DAC_CONTROL, M98090_DACHP_SHIFT, 577 M98090_REG_DAC_CONTROL,
569 ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); 578 M98090_DACHP_SHIFT,
579 max98090_pwr_perf_text);
570 580
571static const struct soc_enum max98090_adchp_enum = 581static SOC_ENUM_SINGLE_DECL(max98090_adchp_enum,
572 SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_ADCHP_SHIFT, 582 M98090_REG_ADC_CONTROL,
573 ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); 583 M98090_ADCHP_SHIFT,
584 max98090_pwr_perf_text);
574 585
575static const struct snd_kcontrol_new max98090_snd_controls[] = { 586static const struct snd_kcontrol_new max98090_snd_controls[] = {
576 SOC_ENUM("MIC Bias VCM Bandgap", max98090_vcmbandgap_enum), 587 SOC_ENUM("MIC Bias VCM Bandgap", max98090_vcmbandgap_enum),
@@ -841,39 +852,42 @@ static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
841 852
842static const char *mic1_mux_text[] = { "IN12", "IN56" }; 853static const char *mic1_mux_text[] = { "IN12", "IN56" };
843 854
844static const struct soc_enum mic1_mux_enum = 855static SOC_ENUM_SINGLE_DECL(mic1_mux_enum,
845 SOC_ENUM_SINGLE(M98090_REG_INPUT_MODE, M98090_EXTMIC1_SHIFT, 856 M98090_REG_INPUT_MODE,
846 ARRAY_SIZE(mic1_mux_text), mic1_mux_text); 857 M98090_EXTMIC1_SHIFT,
858 mic1_mux_text);
847 859
848static const struct snd_kcontrol_new max98090_mic1_mux = 860static const struct snd_kcontrol_new max98090_mic1_mux =
849 SOC_DAPM_ENUM("MIC1 Mux", mic1_mux_enum); 861 SOC_DAPM_ENUM("MIC1 Mux", mic1_mux_enum);
850 862
851static const char *mic2_mux_text[] = { "IN34", "IN56" }; 863static const char *mic2_mux_text[] = { "IN34", "IN56" };
852 864
853static const struct soc_enum mic2_mux_enum = 865static SOC_ENUM_SINGLE_DECL(mic2_mux_enum,
854 SOC_ENUM_SINGLE(M98090_REG_INPUT_MODE, M98090_EXTMIC2_SHIFT, 866 M98090_REG_INPUT_MODE,
855 ARRAY_SIZE(mic2_mux_text), mic2_mux_text); 867 M98090_EXTMIC2_SHIFT,
868 mic2_mux_text);
856 869
857static const struct snd_kcontrol_new max98090_mic2_mux = 870static const struct snd_kcontrol_new max98090_mic2_mux =
858 SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum); 871 SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum);
859 872
860static const char *dmic_mux_text[] = { "ADC", "DMIC" }; 873static const char *dmic_mux_text[] = { "ADC", "DMIC" };
861 874
862static const struct soc_enum dmic_mux_enum = 875static SOC_ENUM_SINGLE_VIRT_DECL(dmic_mux_enum, dmic_mux_text);
863 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dmic_mux_text), dmic_mux_text);
864 876
865static const struct snd_kcontrol_new max98090_dmic_mux = 877static const struct snd_kcontrol_new max98090_dmic_mux =
866 SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum); 878 SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum);
867 879
868static const char *max98090_micpre_text[] = { "Off", "On" }; 880static const char *max98090_micpre_text[] = { "Off", "On" };
869 881
870static const struct soc_enum max98090_pa1en_enum = 882static SOC_ENUM_SINGLE_DECL(max98090_pa1en_enum,
871 SOC_ENUM_SINGLE(M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT, 883 M98090_REG_MIC1_INPUT_LEVEL,
872 ARRAY_SIZE(max98090_micpre_text), max98090_micpre_text); 884 M98090_MIC_PA1EN_SHIFT,
885 max98090_micpre_text);
873 886
874static const struct soc_enum max98090_pa2en_enum = 887static SOC_ENUM_SINGLE_DECL(max98090_pa2en_enum,
875 SOC_ENUM_SINGLE(M98090_REG_MIC2_INPUT_LEVEL, M98090_MIC_PA2EN_SHIFT, 888 M98090_REG_MIC2_INPUT_LEVEL,
876 ARRAY_SIZE(max98090_micpre_text), max98090_micpre_text); 889 M98090_MIC_PA2EN_SHIFT,
890 max98090_micpre_text);
877 891
878/* LINEA mixer switch */ 892/* LINEA mixer switch */
879static const struct snd_kcontrol_new max98090_linea_mixer_controls[] = { 893static const struct snd_kcontrol_new max98090_linea_mixer_controls[] = {
@@ -937,13 +951,15 @@ static const struct snd_kcontrol_new max98090_right_adc_mixer_controls[] = {
937 951
938static const char *lten_mux_text[] = { "Normal", "Loopthrough" }; 952static const char *lten_mux_text[] = { "Normal", "Loopthrough" };
939 953
940static const struct soc_enum ltenl_mux_enum = 954static SOC_ENUM_SINGLE_DECL(ltenl_mux_enum,
941 SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LTEN_SHIFT, 955 M98090_REG_IO_CONFIGURATION,
942 ARRAY_SIZE(lten_mux_text), lten_mux_text); 956 M98090_LTEN_SHIFT,
957 lten_mux_text);
943 958
944static const struct soc_enum ltenr_mux_enum = 959static SOC_ENUM_SINGLE_DECL(ltenr_mux_enum,
945 SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LTEN_SHIFT, 960 M98090_REG_IO_CONFIGURATION,
946 ARRAY_SIZE(lten_mux_text), lten_mux_text); 961 M98090_LTEN_SHIFT,
962 lten_mux_text);
947 963
948static const struct snd_kcontrol_new max98090_ltenl_mux = 964static const struct snd_kcontrol_new max98090_ltenl_mux =
949 SOC_DAPM_ENUM("LTENL Mux", ltenl_mux_enum); 965 SOC_DAPM_ENUM("LTENL Mux", ltenl_mux_enum);
@@ -953,13 +969,15 @@ static const struct snd_kcontrol_new max98090_ltenr_mux =
953 969
954static const char *lben_mux_text[] = { "Normal", "Loopback" }; 970static const char *lben_mux_text[] = { "Normal", "Loopback" };
955 971
956static const struct soc_enum lbenl_mux_enum = 972static SOC_ENUM_SINGLE_DECL(lbenl_mux_enum,
957 SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LBEN_SHIFT, 973 M98090_REG_IO_CONFIGURATION,
958 ARRAY_SIZE(lben_mux_text), lben_mux_text); 974 M98090_LBEN_SHIFT,
975 lben_mux_text);
959 976
960static const struct soc_enum lbenr_mux_enum = 977static SOC_ENUM_SINGLE_DECL(lbenr_mux_enum,
961 SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LBEN_SHIFT, 978 M98090_REG_IO_CONFIGURATION,
962 ARRAY_SIZE(lben_mux_text), lben_mux_text); 979 M98090_LBEN_SHIFT,
980 lben_mux_text);
963 981
964static const struct snd_kcontrol_new max98090_lbenl_mux = 982static const struct snd_kcontrol_new max98090_lbenl_mux =
965 SOC_DAPM_ENUM("LBENL Mux", lbenl_mux_enum); 983 SOC_DAPM_ENUM("LBENL Mux", lbenl_mux_enum);
@@ -971,13 +989,15 @@ static const char *stenl_mux_text[] = { "Normal", "Sidetone Left" };
971 989
972static const char *stenr_mux_text[] = { "Normal", "Sidetone Right" }; 990static const char *stenr_mux_text[] = { "Normal", "Sidetone Right" };
973 991
974static const struct soc_enum stenl_mux_enum = 992static SOC_ENUM_SINGLE_DECL(stenl_mux_enum,
975 SOC_ENUM_SINGLE(M98090_REG_ADC_SIDETONE, M98090_DSTSL_SHIFT, 993 M98090_REG_ADC_SIDETONE,
976 ARRAY_SIZE(stenl_mux_text), stenl_mux_text); 994 M98090_DSTSL_SHIFT,
995 stenl_mux_text);
977 996
978static const struct soc_enum stenr_mux_enum = 997static SOC_ENUM_SINGLE_DECL(stenr_mux_enum,
979 SOC_ENUM_SINGLE(M98090_REG_ADC_SIDETONE, M98090_DSTSR_SHIFT, 998 M98090_REG_ADC_SIDETONE,
980 ARRAY_SIZE(stenr_mux_text), stenr_mux_text); 999 M98090_DSTSR_SHIFT,
1000 stenr_mux_text);
981 1001
982static const struct snd_kcontrol_new max98090_stenl_mux = 1002static const struct snd_kcontrol_new max98090_stenl_mux =
983 SOC_DAPM_ENUM("STENL Mux", stenl_mux_enum); 1003 SOC_DAPM_ENUM("STENL Mux", stenl_mux_enum);
@@ -1085,9 +1105,10 @@ static const struct snd_kcontrol_new max98090_right_rcv_mixer_controls[] = {
1085 1105
1086static const char *linmod_mux_text[] = { "Left Only", "Left and Right" }; 1106static const char *linmod_mux_text[] = { "Left Only", "Left and Right" };
1087 1107
1088static const struct soc_enum linmod_mux_enum = 1108static SOC_ENUM_SINGLE_DECL(linmod_mux_enum,
1089 SOC_ENUM_SINGLE(M98090_REG_LOUTR_MIXER, M98090_LINMOD_SHIFT, 1109 M98090_REG_LOUTR_MIXER,
1090 ARRAY_SIZE(linmod_mux_text), linmod_mux_text); 1110 M98090_LINMOD_SHIFT,
1111 linmod_mux_text);
1091 1112
1092static const struct snd_kcontrol_new max98090_linmod_mux = 1113static const struct snd_kcontrol_new max98090_linmod_mux =
1093 SOC_DAPM_ENUM("LINMOD Mux", linmod_mux_enum); 1114 SOC_DAPM_ENUM("LINMOD Mux", linmod_mux_enum);
@@ -1097,16 +1118,18 @@ static const char *mixhpsel_mux_text[] = { "DAC Only", "HP Mixer" };
1097/* 1118/*
1098 * This is a mux as it selects the HP output, but to DAPM it is a Mixer enable 1119 * This is a mux as it selects the HP output, but to DAPM it is a Mixer enable
1099 */ 1120 */
1100static const struct soc_enum mixhplsel_mux_enum = 1121static SOC_ENUM_SINGLE_DECL(mixhplsel_mux_enum,
1101 SOC_ENUM_SINGLE(M98090_REG_HP_CONTROL, M98090_MIXHPLSEL_SHIFT, 1122 M98090_REG_HP_CONTROL,
1102 ARRAY_SIZE(mixhpsel_mux_text), mixhpsel_mux_text); 1123 M98090_MIXHPLSEL_SHIFT,
1124 mixhpsel_mux_text);
1103 1125
1104static const struct snd_kcontrol_new max98090_mixhplsel_mux = 1126static const struct snd_kcontrol_new max98090_mixhplsel_mux =
1105 SOC_DAPM_ENUM("MIXHPLSEL Mux", mixhplsel_mux_enum); 1127 SOC_DAPM_ENUM("MIXHPLSEL Mux", mixhplsel_mux_enum);
1106 1128
1107static const struct soc_enum mixhprsel_mux_enum = 1129static SOC_ENUM_SINGLE_DECL(mixhprsel_mux_enum,
1108 SOC_ENUM_SINGLE(M98090_REG_HP_CONTROL, M98090_MIXHPRSEL_SHIFT, 1130 M98090_REG_HP_CONTROL,
1109 ARRAY_SIZE(mixhpsel_mux_text), mixhpsel_mux_text); 1131 M98090_MIXHPRSEL_SHIFT,
1132 mixhpsel_mux_text);
1110 1133
1111static const struct snd_kcontrol_new max98090_mixhprsel_mux = 1134static const struct snd_kcontrol_new max98090_mixhprsel_mux =
1112 SOC_DAPM_ENUM("MIXHPRSEL Mux", mixhprsel_mux_enum); 1135 SOC_DAPM_ENUM("MIXHPRSEL Mux", mixhprsel_mux_enum);
@@ -1769,16 +1792,6 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
1769 1792
1770 switch (level) { 1793 switch (level) {
1771 case SND_SOC_BIAS_ON: 1794 case SND_SOC_BIAS_ON:
1772 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1773 ret = regcache_sync(max98090->regmap);
1774
1775 if (ret != 0) {
1776 dev_err(codec->dev,
1777 "Failed to sync cache: %d\n", ret);
1778 return ret;
1779 }
1780 }
1781
1782 if (max98090->jack_state == M98090_JACK_STATE_HEADSET) { 1795 if (max98090->jack_state == M98090_JACK_STATE_HEADSET) {
1783 /* 1796 /*
1784 * Set to normal bias level. 1797 * Set to normal bias level.
@@ -1792,6 +1805,16 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
1792 break; 1805 break;
1793 1806
1794 case SND_SOC_BIAS_STANDBY: 1807 case SND_SOC_BIAS_STANDBY:
1808 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1809 ret = regcache_sync(max98090->regmap);
1810 if (ret != 0) {
1811 dev_err(codec->dev,
1812 "Failed to sync cache: %d\n", ret);
1813 return ret;
1814 }
1815 }
1816 break;
1817
1795 case SND_SOC_BIAS_OFF: 1818 case SND_SOC_BIAS_OFF:
1796 /* Set internal pull-up to lowest power mode */ 1819 /* Set internal pull-up to lowest power mode */
1797 snd_soc_update_bits(codec, M98090_REG_JACK_DETECT, 1820 snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 3ba1170ebb53..5bce9cde4a6d 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -1861,7 +1861,7 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
1861 1861
1862 /* Now point the soc_enum to .texts array items */ 1862 /* Now point the soc_enum to .texts array items */
1863 max98095->eq_enum.texts = max98095->eq_texts; 1863 max98095->eq_enum.texts = max98095->eq_texts;
1864 max98095->eq_enum.max = max98095->eq_textcnt; 1864 max98095->eq_enum.items = max98095->eq_textcnt;
1865 1865
1866 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); 1866 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
1867 if (ret != 0) 1867 if (ret != 0)
@@ -2016,7 +2016,7 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
2016 2016
2017 /* Now point the soc_enum to .texts array items */ 2017 /* Now point the soc_enum to .texts array items */
2018 max98095->bq_enum.texts = max98095->bq_texts; 2018 max98095->bq_enum.texts = max98095->bq_texts;
2019 max98095->bq_enum.max = max98095->bq_textcnt; 2019 max98095->bq_enum.items = max98095->bq_textcnt;
2020 2020
2021 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); 2021 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
2022 if (ret != 0) 2022 if (ret != 0)
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index 582c2bbd42cb..ec89b8f90a64 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -408,8 +408,7 @@ static const char * const adcl_enum_text[] = {
408 "MC1L", "RXINL", 408 "MC1L", "RXINL",
409}; 409};
410 410
411static const struct soc_enum adcl_enum = 411static SOC_ENUM_SINGLE_VIRT_DECL(adcl_enum, adcl_enum_text);
412 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(adcl_enum_text), adcl_enum_text);
413 412
414static const struct snd_kcontrol_new left_input_mux = 413static const struct snd_kcontrol_new left_input_mux =
415 SOC_DAPM_ENUM_VIRT("Route", adcl_enum); 414 SOC_DAPM_ENUM_VIRT("Route", adcl_enum);
@@ -418,8 +417,7 @@ static const char * const adcr_enum_text[] = {
418 "MC1R", "MC2", "RXINR", "TXIN", 417 "MC1R", "MC2", "RXINR", "TXIN",
419}; 418};
420 419
421static const struct soc_enum adcr_enum = 420static SOC_ENUM_SINGLE_VIRT_DECL(adcr_enum, adcr_enum_text);
422 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(adcr_enum_text), adcr_enum_text);
423 421
424static const struct snd_kcontrol_new right_input_mux = 422static const struct snd_kcontrol_new right_input_mux =
425 SOC_DAPM_ENUM_VIRT("Route", adcr_enum); 423 SOC_DAPM_ENUM_VIRT("Route", adcr_enum);
@@ -430,8 +428,8 @@ static const struct snd_kcontrol_new samp_ctl =
430static const char * const speaker_amp_source_text[] = { 428static const char * const speaker_amp_source_text[] = {
431 "CODEC", "Right" 429 "CODEC", "Right"
432}; 430};
433static const SOC_ENUM_SINGLE_DECL(speaker_amp_source, MC13783_AUDIO_RX0, 4, 431static SOC_ENUM_SINGLE_DECL(speaker_amp_source, MC13783_AUDIO_RX0, 4,
434 speaker_amp_source_text); 432 speaker_amp_source_text);
435static const struct snd_kcontrol_new speaker_amp_source_mux = 433static const struct snd_kcontrol_new speaker_amp_source_mux =
436 SOC_DAPM_ENUM("Speaker Amp Source MUX", speaker_amp_source); 434 SOC_DAPM_ENUM("Speaker Amp Source MUX", speaker_amp_source);
437 435
@@ -439,8 +437,8 @@ static const char * const headset_amp_source_text[] = {
439 "CODEC", "Mixer" 437 "CODEC", "Mixer"
440}; 438};
441 439
442static const SOC_ENUM_SINGLE_DECL(headset_amp_source, MC13783_AUDIO_RX0, 11, 440static SOC_ENUM_SINGLE_DECL(headset_amp_source, MC13783_AUDIO_RX0, 11,
443 headset_amp_source_text); 441 headset_amp_source_text);
444static const struct snd_kcontrol_new headset_amp_source_mux = 442static const struct snd_kcontrol_new headset_amp_source_mux =
445 SOC_DAPM_ENUM("Headset Amp Source MUX", headset_amp_source); 443 SOC_DAPM_ENUM("Headset Amp Source MUX", headset_amp_source);
446 444
@@ -580,9 +578,9 @@ static struct snd_soc_dapm_route mc13783_routes[] = {
580static const char * const mc13783_3d_mixer[] = {"Stereo", "Phase Mix", 578static const char * const mc13783_3d_mixer[] = {"Stereo", "Phase Mix",
581 "Mono", "Mono Mix"}; 579 "Mono", "Mono Mix"};
582 580
583static const struct soc_enum mc13783_enum_3d_mixer = 581static SOC_ENUM_SINGLE_DECL(mc13783_enum_3d_mixer,
584 SOC_ENUM_SINGLE(MC13783_AUDIO_RX1, 16, ARRAY_SIZE(mc13783_3d_mixer), 582 MC13783_AUDIO_RX1, 16,
585 mc13783_3d_mixer); 583 mc13783_3d_mixer);
586 584
587static struct snd_kcontrol_new mc13783_control_list[] = { 585static struct snd_kcontrol_new mc13783_control_list[] = {
588 SOC_SINGLE("Loudspeaker enable", MC13783_AUDIO_RX0, 5, 1, 0), 586 SOC_SINGLE("Loudspeaker enable", MC13783_AUDIO_RX0, 5, 1, 0),
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
index 185fa3bc3052..577fb8776ce7 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -73,11 +73,11 @@ static const DECLARE_TLV_DB_SCALE(ngth, -7650, 150, 0);
73static const char * const ml26124_companding[] = {"16bit PCM", "u-law", 73static const char * const ml26124_companding[] = {"16bit PCM", "u-law",
74 "A-law"}; 74 "A-law"};
75 75
76static const struct soc_enum ml26124_adc_companding_enum 76static SOC_ENUM_SINGLE_DECL(ml26124_adc_companding_enum,
77 = SOC_ENUM_SINGLE(ML26124_SAI_TRANS_CTL, 6, 3, ml26124_companding); 77 ML26124_SAI_TRANS_CTL, 6, ml26124_companding);
78 78
79static const struct soc_enum ml26124_dac_companding_enum 79static SOC_ENUM_SINGLE_DECL(ml26124_dac_companding_enum,
80 = SOC_ENUM_SINGLE(ML26124_SAI_RCV_CTL, 6, 3, ml26124_companding); 80 ML26124_SAI_RCV_CTL, 6, ml26124_companding);
81 81
82static const struct snd_kcontrol_new ml26124_snd_controls[] = { 82static const struct snd_kcontrol_new ml26124_snd_controls[] = {
83 SOC_SINGLE_TLV("Capture Digital Volume", ML26124_RECORD_DIG_VOL, 0, 83 SOC_SINGLE_TLV("Capture Digital Volume", ML26124_RECORD_DIG_VOL, 0,
@@ -136,8 +136,8 @@ static const struct snd_kcontrol_new ml26124_output_mixer_controls[] = {
136static const char * const ml26124_input_select[] = {"Analog MIC SingleEnded in", 136static const char * const ml26124_input_select[] = {"Analog MIC SingleEnded in",
137 "Digital MIC in", "Analog MIC Differential in"}; 137 "Digital MIC in", "Analog MIC Differential in"};
138 138
139static const struct soc_enum ml26124_insel_enum = 139static SOC_ENUM_SINGLE_DECL(ml26124_insel_enum,
140 SOC_ENUM_SINGLE(ML26124_MIC_IF_CTL, 0, 3, ml26124_input_select); 140 ML26124_MIC_IF_CTL, 0, ml26124_input_select);
141 141
142static const struct snd_kcontrol_new ml26124_input_mux_controls = 142static const struct snd_kcontrol_new ml26124_input_mux_controls =
143 SOC_DAPM_ENUM("Input Select", ml26124_insel_enum); 143 SOC_DAPM_ENUM("Input Select", ml26124_insel_enum);
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c
index 73f9c3630e2c..e427544183d7 100644
--- a/sound/soc/codecs/pcm1681.c
+++ b/sound/soc/codecs/pcm1681.c
@@ -172,16 +172,21 @@ static int pcm1681_hw_params(struct snd_pcm_substream *substream,
172 struct snd_soc_codec *codec = dai->codec; 172 struct snd_soc_codec *codec = dai->codec;
173 struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); 173 struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
174 int val = 0, ret; 174 int val = 0, ret;
175 int pcm_format = params_format(params);
176 175
177 priv->rate = params_rate(params); 176 priv->rate = params_rate(params);
178 177
179 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { 178 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
180 case SND_SOC_DAIFMT_RIGHT_J: 179 case SND_SOC_DAIFMT_RIGHT_J:
181 if (pcm_format == SNDRV_PCM_FORMAT_S24_LE) 180 switch (params_width(params)) {
182 val = 0x00; 181 case 24:
183 else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE) 182 val = 0;
184 val = 0x03; 183 break;
184 case 16:
185 val = 3;
186 break;
187 default:
188 return -EINVAL;
189 }
185 break; 190 break;
186 case SND_SOC_DAIFMT_I2S: 191 case SND_SOC_DAIFMT_I2S:
187 val = 0x04; 192 val = 0x04;
diff --git a/sound/soc/codecs/pcm1792a.c b/sound/soc/codecs/pcm1792a.c
index 7146653a8e16..3a80ba4452df 100644
--- a/sound/soc/codecs/pcm1792a.c
+++ b/sound/soc/codecs/pcm1792a.c
@@ -107,24 +107,35 @@ static int pcm1792a_hw_params(struct snd_pcm_substream *substream,
107 struct snd_soc_codec *codec = dai->codec; 107 struct snd_soc_codec *codec = dai->codec;
108 struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec); 108 struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec);
109 int val = 0, ret; 109 int val = 0, ret;
110 int pcm_format = params_format(params);
111 110
112 priv->rate = params_rate(params); 111 priv->rate = params_rate(params);
113 112
114 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { 113 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
115 case SND_SOC_DAIFMT_RIGHT_J: 114 case SND_SOC_DAIFMT_RIGHT_J:
116 if (pcm_format == SNDRV_PCM_FORMAT_S24_LE || 115 switch (params_width(params)) {
117 pcm_format == SNDRV_PCM_FORMAT_S32_LE) 116 case 24:
118 val = 0x02; 117 case 32:
119 else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE) 118 val = 2;
120 val = 0x00; 119 break;
120 case 16:
121 val = 0;
122 break;
123 default:
124 return -EINVAL;
125 }
121 break; 126 break;
122 case SND_SOC_DAIFMT_I2S: 127 case SND_SOC_DAIFMT_I2S:
123 if (pcm_format == SNDRV_PCM_FORMAT_S24_LE || 128 switch (params_width(params)) {
124 pcm_format == SNDRV_PCM_FORMAT_S32_LE) 129 case 24:
125 val = 0x05; 130 case 32:
126 else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE) 131 val = 5;
127 val = 0x04; 132 break;
133 case 16:
134 val = 4;
135 break;
136 default:
137 return -EINVAL;
138 }
128 break; 139 break;
129 default: 140 default:
130 dev_err(codec->dev, "Invalid DAI format\n"); 141 dev_err(codec->dev, "Invalid DAI format\n");
diff --git a/sound/soc/codecs/pcm512x-i2c.c b/sound/soc/codecs/pcm512x-i2c.c
new file mode 100644
index 000000000000..4d62230bd378
--- /dev/null
+++ b/sound/soc/codecs/pcm512x-i2c.c
@@ -0,0 +1,71 @@
1/*
2 * Driver for the PCM512x CODECs
3 *
4 * Author: Mark Brown <broonie@linaro.org>
5 * Copyright 2014 Linaro Ltd
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/i2c.h>
20
21#include "pcm512x.h"
22
23static int pcm512x_i2c_probe(struct i2c_client *i2c,
24 const struct i2c_device_id *id)
25{
26 struct regmap *regmap;
27
28 regmap = devm_regmap_init_i2c(i2c, &pcm512x_regmap);
29 if (IS_ERR(regmap))
30 return PTR_ERR(regmap);
31
32 return pcm512x_probe(&i2c->dev, regmap);
33}
34
35static int pcm512x_i2c_remove(struct i2c_client *i2c)
36{
37 pcm512x_remove(&i2c->dev);
38 return 0;
39}
40
41static const struct i2c_device_id pcm512x_i2c_id[] = {
42 { "pcm5121", },
43 { "pcm5122", },
44 { }
45};
46MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id);
47
48static const struct of_device_id pcm512x_of_match[] = {
49 { .compatible = "ti,pcm5121", },
50 { .compatible = "ti,pcm5122", },
51 { }
52};
53MODULE_DEVICE_TABLE(of, pcm512x_of_match);
54
55static struct i2c_driver pcm512x_i2c_driver = {
56 .probe = pcm512x_i2c_probe,
57 .remove = pcm512x_i2c_remove,
58 .id_table = pcm512x_i2c_id,
59 .driver = {
60 .name = "pcm512x",
61 .owner = THIS_MODULE,
62 .of_match_table = pcm512x_of_match,
63 .pm = &pcm512x_pm_ops,
64 },
65};
66
67module_i2c_driver(pcm512x_i2c_driver);
68
69MODULE_DESCRIPTION("ASoC PCM512x codec driver - I2C");
70MODULE_AUTHOR("Mark Brown <broonie@linaro.org>");
71MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/pcm512x-spi.c b/sound/soc/codecs/pcm512x-spi.c
new file mode 100644
index 000000000000..f297058c0038
--- /dev/null
+++ b/sound/soc/codecs/pcm512x-spi.c
@@ -0,0 +1,69 @@
1/*
2 * Driver for the PCM512x CODECs
3 *
4 * Author: Mark Brown <broonie@linaro.org>
5 * Copyright 2014 Linaro Ltd
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/spi/spi.h>
20
21#include "pcm512x.h"
22
23static int pcm512x_spi_probe(struct spi_device *spi)
24{
25 struct regmap *regmap;
26 int ret;
27
28 regmap = devm_regmap_init_spi(spi, &pcm512x_regmap);
29 if (IS_ERR(regmap)) {
30 ret = PTR_ERR(regmap);
31 return ret;
32 }
33
34 return pcm512x_probe(&spi->dev, regmap);
35}
36
37static int pcm512x_spi_remove(struct spi_device *spi)
38{
39 pcm512x_remove(&spi->dev);
40 return 0;
41}
42
43static const struct spi_device_id pcm512x_spi_id[] = {
44 { "pcm5121", },
45 { "pcm5122", },
46 { },
47};
48MODULE_DEVICE_TABLE(spi, pcm512x_spi_id);
49
50static const struct of_device_id pcm512x_of_match[] = {
51 { .compatible = "ti,pcm5121", },
52 { .compatible = "ti,pcm5122", },
53 { }
54};
55MODULE_DEVICE_TABLE(of, pcm512x_of_match);
56
57static struct spi_driver pcm512x_spi_driver = {
58 .probe = pcm512x_spi_probe,
59 .remove = pcm512x_spi_remove,
60 .id_table = pcm512x_spi_id,
61 .driver = {
62 .name = "pcm512x",
63 .owner = THIS_MODULE,
64 .of_match_table = pcm512x_of_match,
65 .pm = &pcm512x_pm_ops,
66 },
67};
68
69module_spi_driver(pcm512x_spi_driver);
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
new file mode 100644
index 000000000000..4b4c0c7bb918
--- /dev/null
+++ b/sound/soc/codecs/pcm512x.c
@@ -0,0 +1,589 @@
1/*
2 * Driver for the PCM512x CODECs
3 *
4 * Author: Mark Brown <broonie@linaro.org>
5 * Copyright 2014 Linaro Ltd
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/clk.h>
21#include <linux/pm_runtime.h>
22#include <linux/regmap.h>
23#include <linux/regulator/consumer.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/tlv.h>
27
28#include "pcm512x.h"
29
30#define PCM512x_NUM_SUPPLIES 3
31static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = {
32 "AVDD",
33 "DVDD",
34 "CPVDD",
35};
36
37struct pcm512x_priv {
38 struct regmap *regmap;
39 struct clk *sclk;
40 struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES];
41 struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES];
42};
43
44/*
45 * We can't use the same notifier block for more than one supply and
46 * there's no way I can see to get from a callback to the caller
47 * except container_of().
48 */
49#define PCM512x_REGULATOR_EVENT(n) \
50static int pcm512x_regulator_event_##n(struct notifier_block *nb, \
51 unsigned long event, void *data) \
52{ \
53 struct pcm512x_priv *pcm512x = container_of(nb, struct pcm512x_priv, \
54 supply_nb[n]); \
55 if (event & REGULATOR_EVENT_DISABLE) { \
56 regcache_mark_dirty(pcm512x->regmap); \
57 regcache_cache_only(pcm512x->regmap, true); \
58 } \
59 return 0; \
60}
61
62PCM512x_REGULATOR_EVENT(0)
63PCM512x_REGULATOR_EVENT(1)
64PCM512x_REGULATOR_EVENT(2)
65
66static const struct reg_default pcm512x_reg_defaults[] = {
67 { PCM512x_RESET, 0x00 },
68 { PCM512x_POWER, 0x00 },
69 { PCM512x_MUTE, 0x00 },
70 { PCM512x_DSP, 0x00 },
71 { PCM512x_PLL_REF, 0x00 },
72 { PCM512x_DAC_ROUTING, 0x11 },
73 { PCM512x_DSP_PROGRAM, 0x01 },
74 { PCM512x_CLKDET, 0x00 },
75 { PCM512x_AUTO_MUTE, 0x00 },
76 { PCM512x_ERROR_DETECT, 0x00 },
77 { PCM512x_DIGITAL_VOLUME_1, 0x00 },
78 { PCM512x_DIGITAL_VOLUME_2, 0x30 },
79 { PCM512x_DIGITAL_VOLUME_3, 0x30 },
80 { PCM512x_DIGITAL_MUTE_1, 0x22 },
81 { PCM512x_DIGITAL_MUTE_2, 0x00 },
82 { PCM512x_DIGITAL_MUTE_3, 0x07 },
83 { PCM512x_OUTPUT_AMPLITUDE, 0x00 },
84 { PCM512x_ANALOG_GAIN_CTRL, 0x00 },
85 { PCM512x_UNDERVOLTAGE_PROT, 0x00 },
86 { PCM512x_ANALOG_MUTE_CTRL, 0x00 },
87 { PCM512x_ANALOG_GAIN_BOOST, 0x00 },
88 { PCM512x_VCOM_CTRL_1, 0x00 },
89 { PCM512x_VCOM_CTRL_2, 0x01 },
90};
91
92static bool pcm512x_readable(struct device *dev, unsigned int reg)
93{
94 switch (reg) {
95 case PCM512x_RESET:
96 case PCM512x_POWER:
97 case PCM512x_MUTE:
98 case PCM512x_PLL_EN:
99 case PCM512x_SPI_MISO_FUNCTION:
100 case PCM512x_DSP:
101 case PCM512x_GPIO_EN:
102 case PCM512x_BCLK_LRCLK_CFG:
103 case PCM512x_DSP_GPIO_INPUT:
104 case PCM512x_MASTER_MODE:
105 case PCM512x_PLL_REF:
106 case PCM512x_PLL_COEFF_0:
107 case PCM512x_PLL_COEFF_1:
108 case PCM512x_PLL_COEFF_2:
109 case PCM512x_PLL_COEFF_3:
110 case PCM512x_PLL_COEFF_4:
111 case PCM512x_DSP_CLKDIV:
112 case PCM512x_DAC_CLKDIV:
113 case PCM512x_NCP_CLKDIV:
114 case PCM512x_OSR_CLKDIV:
115 case PCM512x_MASTER_CLKDIV_1:
116 case PCM512x_MASTER_CLKDIV_2:
117 case PCM512x_FS_SPEED_MODE:
118 case PCM512x_IDAC_1:
119 case PCM512x_IDAC_2:
120 case PCM512x_ERROR_DETECT:
121 case PCM512x_I2S_1:
122 case PCM512x_I2S_2:
123 case PCM512x_DAC_ROUTING:
124 case PCM512x_DSP_PROGRAM:
125 case PCM512x_CLKDET:
126 case PCM512x_AUTO_MUTE:
127 case PCM512x_DIGITAL_VOLUME_1:
128 case PCM512x_DIGITAL_VOLUME_2:
129 case PCM512x_DIGITAL_VOLUME_3:
130 case PCM512x_DIGITAL_MUTE_1:
131 case PCM512x_DIGITAL_MUTE_2:
132 case PCM512x_DIGITAL_MUTE_3:
133 case PCM512x_GPIO_OUTPUT_1:
134 case PCM512x_GPIO_OUTPUT_2:
135 case PCM512x_GPIO_OUTPUT_3:
136 case PCM512x_GPIO_OUTPUT_4:
137 case PCM512x_GPIO_OUTPUT_5:
138 case PCM512x_GPIO_OUTPUT_6:
139 case PCM512x_GPIO_CONTROL_1:
140 case PCM512x_GPIO_CONTROL_2:
141 case PCM512x_OVERFLOW:
142 case PCM512x_RATE_DET_1:
143 case PCM512x_RATE_DET_2:
144 case PCM512x_RATE_DET_3:
145 case PCM512x_RATE_DET_4:
146 case PCM512x_ANALOG_MUTE_DET:
147 case PCM512x_GPIN:
148 case PCM512x_DIGITAL_MUTE_DET:
149 case PCM512x_OUTPUT_AMPLITUDE:
150 case PCM512x_ANALOG_GAIN_CTRL:
151 case PCM512x_UNDERVOLTAGE_PROT:
152 case PCM512x_ANALOG_MUTE_CTRL:
153 case PCM512x_ANALOG_GAIN_BOOST:
154 case PCM512x_VCOM_CTRL_1:
155 case PCM512x_VCOM_CTRL_2:
156 case PCM512x_CRAM_CTRL:
157 return true;
158 default:
159 /* There are 256 raw register addresses */
160 return reg < 0xff;
161 }
162}
163
164static bool pcm512x_volatile(struct device *dev, unsigned int reg)
165{
166 switch (reg) {
167 case PCM512x_PLL_EN:
168 case PCM512x_OVERFLOW:
169 case PCM512x_RATE_DET_1:
170 case PCM512x_RATE_DET_2:
171 case PCM512x_RATE_DET_3:
172 case PCM512x_RATE_DET_4:
173 case PCM512x_ANALOG_MUTE_DET:
174 case PCM512x_GPIN:
175 case PCM512x_DIGITAL_MUTE_DET:
176 case PCM512x_CRAM_CTRL:
177 return true;
178 default:
179 /* There are 256 raw register addresses */
180 return reg < 0xff;
181 }
182}
183
184static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1);
185static const DECLARE_TLV_DB_SCALE(analog_tlv, -600, 600, 0);
186static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0);
187
188static const char * const pcm512x_dsp_program_texts[] = {
189 "FIR interpolation with de-emphasis",
190 "Low latency IIR with de-emphasis",
191 "Fixed process flow",
192 "High attenuation with de-emphasis",
193 "Ringing-less low latency FIR",
194};
195
196static const unsigned int pcm512x_dsp_program_values[] = {
197 1,
198 2,
199 3,
200 5,
201 7,
202};
203
204static SOC_VALUE_ENUM_SINGLE_DECL(pcm512x_dsp_program,
205 PCM512x_DSP_PROGRAM, 0, 0x1f,
206 pcm512x_dsp_program_texts,
207 pcm512x_dsp_program_values);
208
209static const char * const pcm512x_clk_missing_text[] = {
210 "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s"
211};
212
213static const struct soc_enum pcm512x_clk_missing =
214 SOC_ENUM_SINGLE(PCM512x_CLKDET, 0, 8, pcm512x_clk_missing_text);
215
216static const char * const pcm512x_autom_text[] = {
217 "21ms", "106ms", "213ms", "533ms", "1.07s", "2.13s", "5.33s", "10.66s"
218};
219
220static const struct soc_enum pcm512x_autom_l =
221 SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATML_SHIFT, 8,
222 pcm512x_autom_text);
223
224static const struct soc_enum pcm512x_autom_r =
225 SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATMR_SHIFT, 8,
226 pcm512x_autom_text);
227
228static const char * const pcm512x_ramp_rate_text[] = {
229 "1 sample/update", "2 samples/update", "4 samples/update",
230 "Immediate"
231};
232
233static const struct soc_enum pcm512x_vndf =
234 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDF_SHIFT, 4,
235 pcm512x_ramp_rate_text);
236
237static const struct soc_enum pcm512x_vnuf =
238 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUF_SHIFT, 4,
239 pcm512x_ramp_rate_text);
240
241static const struct soc_enum pcm512x_vedf =
242 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDF_SHIFT, 4,
243 pcm512x_ramp_rate_text);
244
245static const char * const pcm512x_ramp_step_text[] = {
246 "4dB/step", "2dB/step", "1dB/step", "0.5dB/step"
247};
248
249static const struct soc_enum pcm512x_vnds =
250 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDS_SHIFT, 4,
251 pcm512x_ramp_step_text);
252
253static const struct soc_enum pcm512x_vnus =
254 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUS_SHIFT, 4,
255 pcm512x_ramp_step_text);
256
257static const struct soc_enum pcm512x_veds =
258 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4,
259 pcm512x_ramp_step_text);
260
261static const struct snd_kcontrol_new pcm512x_controls[] = {
262SOC_DOUBLE_R_TLV("Playback Digital Volume", PCM512x_DIGITAL_VOLUME_2,
263 PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
264SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL,
265 PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv),
266SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST,
267 PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv),
268SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT,
269 PCM512x_RQMR_SHIFT, 1, 1),
270
271SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1),
272SOC_VALUE_ENUM("DSP Program", pcm512x_dsp_program),
273
274SOC_ENUM("Clock Missing Period", pcm512x_clk_missing),
275SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l),
276SOC_ENUM("Auto Mute Time Right", pcm512x_autom_r),
277SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3,
278 PCM512x_ACTL_SHIFT, 1, 0),
279SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT,
280 PCM512x_AMLR_SHIFT, 1, 0),
281
282SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf),
283SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds),
284SOC_ENUM("Volume Ramp Up Rate", pcm512x_vnuf),
285SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus),
286SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf),
287SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds),
288};
289
290static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = {
291SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
292SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
293
294SND_SOC_DAPM_OUTPUT("OUTL"),
295SND_SOC_DAPM_OUTPUT("OUTR"),
296};
297
298static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = {
299 { "DACL", NULL, "Playback" },
300 { "DACR", NULL, "Playback" },
301
302 { "OUTL", NULL, "DACL" },
303 { "OUTR", NULL, "DACR" },
304};
305
306static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
307 enum snd_soc_bias_level level)
308{
309 struct pcm512x_priv *pcm512x = dev_get_drvdata(codec->dev);
310 int ret;
311
312 switch (level) {
313 case SND_SOC_BIAS_ON:
314 case SND_SOC_BIAS_PREPARE:
315 break;
316
317 case SND_SOC_BIAS_STANDBY:
318 ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
319 PCM512x_RQST, 0);
320 if (ret != 0) {
321 dev_err(codec->dev, "Failed to remove standby: %d\n",
322 ret);
323 return ret;
324 }
325 break;
326
327 case SND_SOC_BIAS_OFF:
328 ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
329 PCM512x_RQST, PCM512x_RQST);
330 if (ret != 0) {
331 dev_err(codec->dev, "Failed to request standby: %d\n",
332 ret);
333 return ret;
334 }
335 break;
336 }
337
338 codec->dapm.bias_level = level;
339
340 return 0;
341}
342
343static struct snd_soc_dai_driver pcm512x_dai = {
344 .name = "pcm512x-hifi",
345 .playback = {
346 .stream_name = "Playback",
347 .channels_min = 2,
348 .channels_max = 2,
349 .rates = SNDRV_PCM_RATE_8000_192000,
350 .formats = SNDRV_PCM_FMTBIT_S16_LE |
351 SNDRV_PCM_FMTBIT_S24_LE |
352 SNDRV_PCM_FMTBIT_S32_LE
353 },
354};
355
356static struct snd_soc_codec_driver pcm512x_codec_driver = {
357 .set_bias_level = pcm512x_set_bias_level,
358 .idle_bias_off = true,
359
360 .controls = pcm512x_controls,
361 .num_controls = ARRAY_SIZE(pcm512x_controls),
362 .dapm_widgets = pcm512x_dapm_widgets,
363 .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets),
364 .dapm_routes = pcm512x_dapm_routes,
365 .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes),
366};
367
368static const struct regmap_range_cfg pcm512x_range = {
369 .name = "Pages", .range_min = PCM512x_VIRT_BASE,
370 .range_max = PCM512x_MAX_REGISTER,
371 .selector_reg = PCM512x_PAGE,
372 .selector_mask = 0xff,
373 .window_start = 0, .window_len = 0x100,
374};
375
376const struct regmap_config pcm512x_regmap = {
377 .reg_bits = 8,
378 .val_bits = 8,
379
380 .readable_reg = pcm512x_readable,
381 .volatile_reg = pcm512x_volatile,
382
383 .ranges = &pcm512x_range,
384 .num_ranges = 1,
385
386 .max_register = PCM512x_MAX_REGISTER,
387 .reg_defaults = pcm512x_reg_defaults,
388 .num_reg_defaults = ARRAY_SIZE(pcm512x_reg_defaults),
389 .cache_type = REGCACHE_RBTREE,
390};
391EXPORT_SYMBOL_GPL(pcm512x_regmap);
392
393int pcm512x_probe(struct device *dev, struct regmap *regmap)
394{
395 struct pcm512x_priv *pcm512x;
396 int i, ret;
397
398 pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL);
399 if (!pcm512x)
400 return -ENOMEM;
401
402 dev_set_drvdata(dev, pcm512x);
403 pcm512x->regmap = regmap;
404
405 for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++)
406 pcm512x->supplies[i].supply = pcm512x_supply_names[i];
407
408 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pcm512x->supplies),
409 pcm512x->supplies);
410 if (ret != 0) {
411 dev_err(dev, "Failed to get supplies: %d\n", ret);
412 return ret;
413 }
414
415 pcm512x->supply_nb[0].notifier_call = pcm512x_regulator_event_0;
416 pcm512x->supply_nb[1].notifier_call = pcm512x_regulator_event_1;
417 pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2;
418
419 for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) {
420 ret = regulator_register_notifier(pcm512x->supplies[i].consumer,
421 &pcm512x->supply_nb[i]);
422 if (ret != 0) {
423 dev_err(dev,
424 "Failed to register regulator notifier: %d\n",
425 ret);
426 }
427 }
428
429 ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
430 pcm512x->supplies);
431 if (ret != 0) {
432 dev_err(dev, "Failed to enable supplies: %d\n", ret);
433 return ret;
434 }
435
436 /* Reset the device, verifying I/O in the process for I2C */
437 ret = regmap_write(regmap, PCM512x_RESET,
438 PCM512x_RSTM | PCM512x_RSTR);
439 if (ret != 0) {
440 dev_err(dev, "Failed to reset device: %d\n", ret);
441 goto err;
442 }
443
444 ret = regmap_write(regmap, PCM512x_RESET, 0);
445 if (ret != 0) {
446 dev_err(dev, "Failed to reset device: %d\n", ret);
447 goto err;
448 }
449
450 pcm512x->sclk = devm_clk_get(dev, NULL);
451 if (IS_ERR(pcm512x->sclk)) {
452 if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER)
453 return -EPROBE_DEFER;
454
455 dev_info(dev, "No SCLK, using BCLK: %ld\n",
456 PTR_ERR(pcm512x->sclk));
457
458 /* Disable reporting of missing SCLK as an error */
459 regmap_update_bits(regmap, PCM512x_ERROR_DETECT,
460 PCM512x_IDCH, PCM512x_IDCH);
461
462 /* Switch PLL input to BCLK */
463 regmap_update_bits(regmap, PCM512x_PLL_REF,
464 PCM512x_SREF, PCM512x_SREF);
465 } else {
466 ret = clk_prepare_enable(pcm512x->sclk);
467 if (ret != 0) {
468 dev_err(dev, "Failed to enable SCLK: %d\n", ret);
469 return ret;
470 }
471 }
472
473 /* Default to standby mode */
474 ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
475 PCM512x_RQST, PCM512x_RQST);
476 if (ret != 0) {
477 dev_err(dev, "Failed to request standby: %d\n",
478 ret);
479 goto err_clk;
480 }
481
482 pm_runtime_set_active(dev);
483 pm_runtime_enable(dev);
484 pm_runtime_idle(dev);
485
486 ret = snd_soc_register_codec(dev, &pcm512x_codec_driver,
487 &pcm512x_dai, 1);
488 if (ret != 0) {
489 dev_err(dev, "Failed to register CODEC: %d\n", ret);
490 goto err_pm;
491 }
492
493 return 0;
494
495err_pm:
496 pm_runtime_disable(dev);
497err_clk:
498 if (!IS_ERR(pcm512x->sclk))
499 clk_disable_unprepare(pcm512x->sclk);
500err:
501 regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
502 pcm512x->supplies);
503 return ret;
504}
505EXPORT_SYMBOL_GPL(pcm512x_probe);
506
507void pcm512x_remove(struct device *dev)
508{
509 struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
510
511 snd_soc_unregister_codec(dev);
512 pm_runtime_disable(dev);
513 if (!IS_ERR(pcm512x->sclk))
514 clk_disable_unprepare(pcm512x->sclk);
515 regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
516 pcm512x->supplies);
517}
518EXPORT_SYMBOL_GPL(pcm512x_remove);
519
520static int pcm512x_suspend(struct device *dev)
521{
522 struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
523 int ret;
524
525 ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
526 PCM512x_RQPD, PCM512x_RQPD);
527 if (ret != 0) {
528 dev_err(dev, "Failed to request power down: %d\n", ret);
529 return ret;
530 }
531
532 ret = regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
533 pcm512x->supplies);
534 if (ret != 0) {
535 dev_err(dev, "Failed to disable supplies: %d\n", ret);
536 return ret;
537 }
538
539 if (!IS_ERR(pcm512x->sclk))
540 clk_disable_unprepare(pcm512x->sclk);
541
542 return 0;
543}
544
545static int pcm512x_resume(struct device *dev)
546{
547 struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
548 int ret;
549
550 if (!IS_ERR(pcm512x->sclk)) {
551 ret = clk_prepare_enable(pcm512x->sclk);
552 if (ret != 0) {
553 dev_err(dev, "Failed to enable SCLK: %d\n", ret);
554 return ret;
555 }
556 }
557
558 ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
559 pcm512x->supplies);
560 if (ret != 0) {
561 dev_err(dev, "Failed to enable supplies: %d\n", ret);
562 return ret;
563 }
564
565 regcache_cache_only(pcm512x->regmap, false);
566 ret = regcache_sync(pcm512x->regmap);
567 if (ret != 0) {
568 dev_err(dev, "Failed to sync cache: %d\n", ret);
569 return ret;
570 }
571
572 ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
573 PCM512x_RQPD, 0);
574 if (ret != 0) {
575 dev_err(dev, "Failed to remove power down: %d\n", ret);
576 return ret;
577 }
578
579 return 0;
580}
581
582const struct dev_pm_ops pcm512x_pm_ops = {
583 SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL)
584};
585EXPORT_SYMBOL_GPL(pcm512x_pm_ops);
586
587MODULE_DESCRIPTION("ASoC PCM512x codec driver");
588MODULE_AUTHOR("Mark Brown <broonie@linaro.org>");
589MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/pcm512x.h b/sound/soc/codecs/pcm512x.h
new file mode 100644
index 000000000000..6ee76aaca09a
--- /dev/null
+++ b/sound/soc/codecs/pcm512x.h
@@ -0,0 +1,171 @@
1/*
2 * Driver for the PCM512x CODECs
3 *
4 * Author: Mark Brown <broonie@linaro.org>
5 * Copyright 2014 Linaro Ltd
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17#ifndef _SND_SOC_PCM512X
18#define _SND_SOC_PCM512X
19
20#include <linux/pm.h>
21#include <linux/regmap.h>
22
23#define PCM512x_VIRT_BASE 0x100
24#define PCM512x_PAGE_LEN 0x100
25#define PCM512x_PAGE_BASE(n) (PCM512x_VIRT_BASE + (PCM512x_PAGE_LEN * n))
26
27#define PCM512x_PAGE 0
28
29#define PCM512x_RESET (PCM512x_PAGE_BASE(0) + 1)
30#define PCM512x_POWER (PCM512x_PAGE_BASE(0) + 2)
31#define PCM512x_MUTE (PCM512x_PAGE_BASE(0) + 3)
32#define PCM512x_PLL_EN (PCM512x_PAGE_BASE(0) + 4)
33#define PCM512x_SPI_MISO_FUNCTION (PCM512x_PAGE_BASE(0) + 6)
34#define PCM512x_DSP (PCM512x_PAGE_BASE(0) + 7)
35#define PCM512x_GPIO_EN (PCM512x_PAGE_BASE(0) + 8)
36#define PCM512x_BCLK_LRCLK_CFG (PCM512x_PAGE_BASE(0) + 9)
37#define PCM512x_DSP_GPIO_INPUT (PCM512x_PAGE_BASE(0) + 10)
38#define PCM512x_MASTER_MODE (PCM512x_PAGE_BASE(0) + 12)
39#define PCM512x_PLL_REF (PCM512x_PAGE_BASE(0) + 13)
40#define PCM512x_PLL_COEFF_0 (PCM512x_PAGE_BASE(0) + 20)
41#define PCM512x_PLL_COEFF_1 (PCM512x_PAGE_BASE(0) + 21)
42#define PCM512x_PLL_COEFF_2 (PCM512x_PAGE_BASE(0) + 22)
43#define PCM512x_PLL_COEFF_3 (PCM512x_PAGE_BASE(0) + 23)
44#define PCM512x_PLL_COEFF_4 (PCM512x_PAGE_BASE(0) + 24)
45#define PCM512x_DSP_CLKDIV (PCM512x_PAGE_BASE(0) + 27)
46#define PCM512x_DAC_CLKDIV (PCM512x_PAGE_BASE(0) + 28)
47#define PCM512x_NCP_CLKDIV (PCM512x_PAGE_BASE(0) + 29)
48#define PCM512x_OSR_CLKDIV (PCM512x_PAGE_BASE(0) + 30)
49#define PCM512x_MASTER_CLKDIV_1 (PCM512x_PAGE_BASE(0) + 32)
50#define PCM512x_MASTER_CLKDIV_2 (PCM512x_PAGE_BASE(0) + 33)
51#define PCM512x_FS_SPEED_MODE (PCM512x_PAGE_BASE(0) + 34)
52#define PCM512x_IDAC_1 (PCM512x_PAGE_BASE(0) + 35)
53#define PCM512x_IDAC_2 (PCM512x_PAGE_BASE(0) + 36)
54#define PCM512x_ERROR_DETECT (PCM512x_PAGE_BASE(0) + 37)
55#define PCM512x_I2S_1 (PCM512x_PAGE_BASE(0) + 40)
56#define PCM512x_I2S_2 (PCM512x_PAGE_BASE(0) + 41)
57#define PCM512x_DAC_ROUTING (PCM512x_PAGE_BASE(0) + 42)
58#define PCM512x_DSP_PROGRAM (PCM512x_PAGE_BASE(0) + 43)
59#define PCM512x_CLKDET (PCM512x_PAGE_BASE(0) + 44)
60#define PCM512x_AUTO_MUTE (PCM512x_PAGE_BASE(0) + 59)
61#define PCM512x_DIGITAL_VOLUME_1 (PCM512x_PAGE_BASE(0) + 60)
62#define PCM512x_DIGITAL_VOLUME_2 (PCM512x_PAGE_BASE(0) + 61)
63#define PCM512x_DIGITAL_VOLUME_3 (PCM512x_PAGE_BASE(0) + 62)
64#define PCM512x_DIGITAL_MUTE_1 (PCM512x_PAGE_BASE(0) + 63)
65#define PCM512x_DIGITAL_MUTE_2 (PCM512x_PAGE_BASE(0) + 64)
66#define PCM512x_DIGITAL_MUTE_3 (PCM512x_PAGE_BASE(0) + 65)
67#define PCM512x_GPIO_OUTPUT_1 (PCM512x_PAGE_BASE(0) + 80)
68#define PCM512x_GPIO_OUTPUT_2 (PCM512x_PAGE_BASE(0) + 81)
69#define PCM512x_GPIO_OUTPUT_3 (PCM512x_PAGE_BASE(0) + 82)
70#define PCM512x_GPIO_OUTPUT_4 (PCM512x_PAGE_BASE(0) + 83)
71#define PCM512x_GPIO_OUTPUT_5 (PCM512x_PAGE_BASE(0) + 84)
72#define PCM512x_GPIO_OUTPUT_6 (PCM512x_PAGE_BASE(0) + 85)
73#define PCM512x_GPIO_CONTROL_1 (PCM512x_PAGE_BASE(0) + 86)
74#define PCM512x_GPIO_CONTROL_2 (PCM512x_PAGE_BASE(0) + 87)
75#define PCM512x_OVERFLOW (PCM512x_PAGE_BASE(0) + 90)
76#define PCM512x_RATE_DET_1 (PCM512x_PAGE_BASE(0) + 91)
77#define PCM512x_RATE_DET_2 (PCM512x_PAGE_BASE(0) + 92)
78#define PCM512x_RATE_DET_3 (PCM512x_PAGE_BASE(0) + 93)
79#define PCM512x_RATE_DET_4 (PCM512x_PAGE_BASE(0) + 94)
80#define PCM512x_ANALOG_MUTE_DET (PCM512x_PAGE_BASE(0) + 108)
81#define PCM512x_GPIN (PCM512x_PAGE_BASE(0) + 119)
82#define PCM512x_DIGITAL_MUTE_DET (PCM512x_PAGE_BASE(0) + 120)
83
84#define PCM512x_OUTPUT_AMPLITUDE (PCM512x_PAGE_BASE(1) + 1)
85#define PCM512x_ANALOG_GAIN_CTRL (PCM512x_PAGE_BASE(1) + 2)
86#define PCM512x_UNDERVOLTAGE_PROT (PCM512x_PAGE_BASE(1) + 5)
87#define PCM512x_ANALOG_MUTE_CTRL (PCM512x_PAGE_BASE(1) + 6)
88#define PCM512x_ANALOG_GAIN_BOOST (PCM512x_PAGE_BASE(1) + 7)
89#define PCM512x_VCOM_CTRL_1 (PCM512x_PAGE_BASE(1) + 8)
90#define PCM512x_VCOM_CTRL_2 (PCM512x_PAGE_BASE(1) + 9)
91
92#define PCM512x_CRAM_CTRL (PCM512x_PAGE_BASE(44) + 1)
93
94#define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(44) + 1)
95
96/* Page 0, Register 1 - reset */
97#define PCM512x_RSTR (1 << 0)
98#define PCM512x_RSTM (1 << 4)
99
100/* Page 0, Register 2 - power */
101#define PCM512x_RQPD (1 << 0)
102#define PCM512x_RQPD_SHIFT 0
103#define PCM512x_RQST (1 << 4)
104#define PCM512x_RQST_SHIFT 4
105
106/* Page 0, Register 3 - mute */
107#define PCM512x_RQMR_SHIFT 0
108#define PCM512x_RQML_SHIFT 4
109
110/* Page 0, Register 4 - PLL */
111#define PCM512x_PLCE (1 << 0)
112#define PCM512x_RLCE_SHIFT 0
113#define PCM512x_PLCK (1 << 4)
114#define PCM512x_PLCK_SHIFT 4
115
116/* Page 0, Register 7 - DSP */
117#define PCM512x_SDSL (1 << 0)
118#define PCM512x_SDSL_SHIFT 0
119#define PCM512x_DEMP (1 << 4)
120#define PCM512x_DEMP_SHIFT 4
121
122/* Page 0, Register 13 - PLL reference */
123#define PCM512x_SREF (1 << 4)
124
125/* Page 0, Register 37 - Error detection */
126#define PCM512x_IPLK (1 << 0)
127#define PCM512x_DCAS (1 << 1)
128#define PCM512x_IDCM (1 << 2)
129#define PCM512x_IDCH (1 << 3)
130#define PCM512x_IDSK (1 << 4)
131#define PCM512x_IDBK (1 << 5)
132#define PCM512x_IDFS (1 << 6)
133
134/* Page 0, Register 42 - DAC routing */
135#define PCM512x_AUPR_SHIFT 0
136#define PCM512x_AUPL_SHIFT 4
137
138/* Page 0, Register 59 - auto mute */
139#define PCM512x_ATMR_SHIFT 0
140#define PCM512x_ATML_SHIFT 4
141
142/* Page 0, Register 63 - ramp rates */
143#define PCM512x_VNDF_SHIFT 6
144#define PCM512x_VNDS_SHIFT 4
145#define PCM512x_VNUF_SHIFT 2
146#define PCM512x_VNUS_SHIFT 0
147
148/* Page 0, Register 64 - emergency ramp rates */
149#define PCM512x_VEDF_SHIFT 6
150#define PCM512x_VEDS_SHIFT 4
151
152/* Page 0, Register 65 - Digital mute enables */
153#define PCM512x_ACTL_SHIFT 2
154#define PCM512x_AMLE_SHIFT 1
155#define PCM512x_AMLR_SHIFT 0
156
157/* Page 1, Register 2 - analog volume control */
158#define PCM512x_RAGN_SHIFT 0
159#define PCM512x_LAGN_SHIFT 4
160
161/* Page 1, Register 7 - analog boost control */
162#define PCM512x_AGBR_SHIFT 0
163#define PCM512x_AGBL_SHIFT 4
164
165extern const struct dev_pm_ops pcm512x_pm_ops;
166extern const struct regmap_config pcm512x_regmap;
167
168int pcm512x_probe(struct device *dev, struct regmap *regmap);
169void pcm512x_remove(struct device *dev);
170
171#endif
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
index 912c9cbc2724..ce199d375209 100644
--- a/sound/soc/codecs/rt5631.c
+++ b/sound/soc/codecs/rt5631.c
@@ -210,26 +210,22 @@ static int rt5631_dmic_put(struct snd_kcontrol *kcontrol,
210static const char *rt5631_input_mode[] = { 210static const char *rt5631_input_mode[] = {
211 "Single ended", "Differential"}; 211 "Single ended", "Differential"};
212 212
213static const SOC_ENUM_SINGLE_DECL( 213static SOC_ENUM_SINGLE_DECL(rt5631_mic1_mode_enum, RT5631_MIC_CTRL_1,
214 rt5631_mic1_mode_enum, RT5631_MIC_CTRL_1, 214 RT5631_MIC1_DIFF_INPUT_SHIFT, rt5631_input_mode);
215 RT5631_MIC1_DIFF_INPUT_SHIFT, rt5631_input_mode);
216 215
217static const SOC_ENUM_SINGLE_DECL( 216static SOC_ENUM_SINGLE_DECL(rt5631_mic2_mode_enum, RT5631_MIC_CTRL_1,
218 rt5631_mic2_mode_enum, RT5631_MIC_CTRL_1, 217 RT5631_MIC2_DIFF_INPUT_SHIFT, rt5631_input_mode);
219 RT5631_MIC2_DIFF_INPUT_SHIFT, rt5631_input_mode);
220 218
221/* MONO Input Type */ 219/* MONO Input Type */
222static const SOC_ENUM_SINGLE_DECL( 220static SOC_ENUM_SINGLE_DECL(rt5631_monoin_mode_enum, RT5631_MONO_INPUT_VOL,
223 rt5631_monoin_mode_enum, RT5631_MONO_INPUT_VOL, 221 RT5631_MONO_DIFF_INPUT_SHIFT, rt5631_input_mode);
224 RT5631_MONO_DIFF_INPUT_SHIFT, rt5631_input_mode);
225 222
226/* SPK Ratio Gain Control */ 223/* SPK Ratio Gain Control */
227static const char *rt5631_spk_ratio[] = {"1.00x", "1.09x", "1.27x", "1.44x", 224static const char *rt5631_spk_ratio[] = {"1.00x", "1.09x", "1.27x", "1.44x",
228 "1.56x", "1.68x", "1.99x", "2.34x"}; 225 "1.56x", "1.68x", "1.99x", "2.34x"};
229 226
230static const SOC_ENUM_SINGLE_DECL( 227static SOC_ENUM_SINGLE_DECL(rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG,
231 rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG, 228 RT5631_SPK_AMP_RATIO_CTRL_SHIFT, rt5631_spk_ratio);
232 RT5631_SPK_AMP_RATIO_CTRL_SHIFT, rt5631_spk_ratio);
233 229
234static const struct snd_kcontrol_new rt5631_snd_controls[] = { 230static const struct snd_kcontrol_new rt5631_snd_controls[] = {
235 /* MIC */ 231 /* MIC */
@@ -759,9 +755,8 @@ static const struct snd_kcontrol_new rt5631_monomix_mixer_controls[] = {
759/* Left SPK Volume Input */ 755/* Left SPK Volume Input */
760static const char *rt5631_spkvoll_sel[] = {"Vmid", "SPKMIXL"}; 756static const char *rt5631_spkvoll_sel[] = {"Vmid", "SPKMIXL"};
761 757
762static const SOC_ENUM_SINGLE_DECL( 758static SOC_ENUM_SINGLE_DECL(rt5631_spkvoll_enum, RT5631_SPK_OUT_VOL,
763 rt5631_spkvoll_enum, RT5631_SPK_OUT_VOL, 759 RT5631_L_EN_SHIFT, rt5631_spkvoll_sel);
764 RT5631_L_EN_SHIFT, rt5631_spkvoll_sel);
765 760
766static const struct snd_kcontrol_new rt5631_spkvoll_mux_control = 761static const struct snd_kcontrol_new rt5631_spkvoll_mux_control =
767 SOC_DAPM_ENUM("Left SPKVOL SRC", rt5631_spkvoll_enum); 762 SOC_DAPM_ENUM("Left SPKVOL SRC", rt5631_spkvoll_enum);
@@ -769,9 +764,8 @@ static const struct snd_kcontrol_new rt5631_spkvoll_mux_control =
769/* Left HP Volume Input */ 764/* Left HP Volume Input */
770static const char *rt5631_hpvoll_sel[] = {"Vmid", "OUTMIXL"}; 765static const char *rt5631_hpvoll_sel[] = {"Vmid", "OUTMIXL"};
771 766
772static const SOC_ENUM_SINGLE_DECL( 767static SOC_ENUM_SINGLE_DECL(rt5631_hpvoll_enum, RT5631_HP_OUT_VOL,
773 rt5631_hpvoll_enum, RT5631_HP_OUT_VOL, 768 RT5631_L_EN_SHIFT, rt5631_hpvoll_sel);
774 RT5631_L_EN_SHIFT, rt5631_hpvoll_sel);
775 769
776static const struct snd_kcontrol_new rt5631_hpvoll_mux_control = 770static const struct snd_kcontrol_new rt5631_hpvoll_mux_control =
777 SOC_DAPM_ENUM("Left HPVOL SRC", rt5631_hpvoll_enum); 771 SOC_DAPM_ENUM("Left HPVOL SRC", rt5631_hpvoll_enum);
@@ -779,9 +773,8 @@ static const struct snd_kcontrol_new rt5631_hpvoll_mux_control =
779/* Left Out Volume Input */ 773/* Left Out Volume Input */
780static const char *rt5631_outvoll_sel[] = {"Vmid", "OUTMIXL"}; 774static const char *rt5631_outvoll_sel[] = {"Vmid", "OUTMIXL"};
781 775
782static const SOC_ENUM_SINGLE_DECL( 776static SOC_ENUM_SINGLE_DECL(rt5631_outvoll_enum, RT5631_MONO_AXO_1_2_VOL,
783 rt5631_outvoll_enum, RT5631_MONO_AXO_1_2_VOL, 777 RT5631_L_EN_SHIFT, rt5631_outvoll_sel);
784 RT5631_L_EN_SHIFT, rt5631_outvoll_sel);
785 778
786static const struct snd_kcontrol_new rt5631_outvoll_mux_control = 779static const struct snd_kcontrol_new rt5631_outvoll_mux_control =
787 SOC_DAPM_ENUM("Left OUTVOL SRC", rt5631_outvoll_enum); 780 SOC_DAPM_ENUM("Left OUTVOL SRC", rt5631_outvoll_enum);
@@ -789,9 +782,8 @@ static const struct snd_kcontrol_new rt5631_outvoll_mux_control =
789/* Right Out Volume Input */ 782/* Right Out Volume Input */
790static const char *rt5631_outvolr_sel[] = {"Vmid", "OUTMIXR"}; 783static const char *rt5631_outvolr_sel[] = {"Vmid", "OUTMIXR"};
791 784
792static const SOC_ENUM_SINGLE_DECL( 785static SOC_ENUM_SINGLE_DECL(rt5631_outvolr_enum, RT5631_MONO_AXO_1_2_VOL,
793 rt5631_outvolr_enum, RT5631_MONO_AXO_1_2_VOL, 786 RT5631_R_EN_SHIFT, rt5631_outvolr_sel);
794 RT5631_R_EN_SHIFT, rt5631_outvolr_sel);
795 787
796static const struct snd_kcontrol_new rt5631_outvolr_mux_control = 788static const struct snd_kcontrol_new rt5631_outvolr_mux_control =
797 SOC_DAPM_ENUM("Right OUTVOL SRC", rt5631_outvolr_enum); 789 SOC_DAPM_ENUM("Right OUTVOL SRC", rt5631_outvolr_enum);
@@ -799,9 +791,8 @@ static const struct snd_kcontrol_new rt5631_outvolr_mux_control =
799/* Right HP Volume Input */ 791/* Right HP Volume Input */
800static const char *rt5631_hpvolr_sel[] = {"Vmid", "OUTMIXR"}; 792static const char *rt5631_hpvolr_sel[] = {"Vmid", "OUTMIXR"};
801 793
802static const SOC_ENUM_SINGLE_DECL( 794static SOC_ENUM_SINGLE_DECL(rt5631_hpvolr_enum, RT5631_HP_OUT_VOL,
803 rt5631_hpvolr_enum, RT5631_HP_OUT_VOL, 795 RT5631_R_EN_SHIFT, rt5631_hpvolr_sel);
804 RT5631_R_EN_SHIFT, rt5631_hpvolr_sel);
805 796
806static const struct snd_kcontrol_new rt5631_hpvolr_mux_control = 797static const struct snd_kcontrol_new rt5631_hpvolr_mux_control =
807 SOC_DAPM_ENUM("Right HPVOL SRC", rt5631_hpvolr_enum); 798 SOC_DAPM_ENUM("Right HPVOL SRC", rt5631_hpvolr_enum);
@@ -809,9 +800,8 @@ static const struct snd_kcontrol_new rt5631_hpvolr_mux_control =
809/* Right SPK Volume Input */ 800/* Right SPK Volume Input */
810static const char *rt5631_spkvolr_sel[] = {"Vmid", "SPKMIXR"}; 801static const char *rt5631_spkvolr_sel[] = {"Vmid", "SPKMIXR"};
811 802
812static const SOC_ENUM_SINGLE_DECL( 803static SOC_ENUM_SINGLE_DECL(rt5631_spkvolr_enum, RT5631_SPK_OUT_VOL,
813 rt5631_spkvolr_enum, RT5631_SPK_OUT_VOL, 804 RT5631_R_EN_SHIFT, rt5631_spkvolr_sel);
814 RT5631_R_EN_SHIFT, rt5631_spkvolr_sel);
815 805
816static const struct snd_kcontrol_new rt5631_spkvolr_mux_control = 806static const struct snd_kcontrol_new rt5631_spkvolr_mux_control =
817 SOC_DAPM_ENUM("Right SPKVOL SRC", rt5631_spkvolr_enum); 807 SOC_DAPM_ENUM("Right SPKVOL SRC", rt5631_spkvolr_enum);
@@ -820,9 +810,8 @@ static const struct snd_kcontrol_new rt5631_spkvolr_mux_control =
820static const char *rt5631_spol_src_sel[] = { 810static const char *rt5631_spol_src_sel[] = {
821 "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"}; 811 "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"};
822 812
823static const SOC_ENUM_SINGLE_DECL( 813static SOC_ENUM_SINGLE_DECL(rt5631_spol_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
824 rt5631_spol_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, 814 RT5631_SPK_L_MUX_SEL_SHIFT, rt5631_spol_src_sel);
825 RT5631_SPK_L_MUX_SEL_SHIFT, rt5631_spol_src_sel);
826 815
827static const struct snd_kcontrol_new rt5631_spol_mux_control = 816static const struct snd_kcontrol_new rt5631_spol_mux_control =
828 SOC_DAPM_ENUM("SPOL SRC", rt5631_spol_src_enum); 817 SOC_DAPM_ENUM("SPOL SRC", rt5631_spol_src_enum);
@@ -831,9 +820,8 @@ static const struct snd_kcontrol_new rt5631_spol_mux_control =
831static const char *rt5631_spor_src_sel[] = { 820static const char *rt5631_spor_src_sel[] = {
832 "SPORMIX", "MONOIN_RX", "VDAC", "DACR"}; 821 "SPORMIX", "MONOIN_RX", "VDAC", "DACR"};
833 822
834static const SOC_ENUM_SINGLE_DECL( 823static SOC_ENUM_SINGLE_DECL(rt5631_spor_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
835 rt5631_spor_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, 824 RT5631_SPK_R_MUX_SEL_SHIFT, rt5631_spor_src_sel);
836 RT5631_SPK_R_MUX_SEL_SHIFT, rt5631_spor_src_sel);
837 825
838static const struct snd_kcontrol_new rt5631_spor_mux_control = 826static const struct snd_kcontrol_new rt5631_spor_mux_control =
839 SOC_DAPM_ENUM("SPOR SRC", rt5631_spor_src_enum); 827 SOC_DAPM_ENUM("SPOR SRC", rt5631_spor_src_enum);
@@ -841,9 +829,8 @@ static const struct snd_kcontrol_new rt5631_spor_mux_control =
841/* MONO Input */ 829/* MONO Input */
842static const char *rt5631_mono_src_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"}; 830static const char *rt5631_mono_src_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"};
843 831
844static const SOC_ENUM_SINGLE_DECL( 832static SOC_ENUM_SINGLE_DECL(rt5631_mono_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
845 rt5631_mono_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, 833 RT5631_MONO_MUX_SEL_SHIFT, rt5631_mono_src_sel);
846 RT5631_MONO_MUX_SEL_SHIFT, rt5631_mono_src_sel);
847 834
848static const struct snd_kcontrol_new rt5631_mono_mux_control = 835static const struct snd_kcontrol_new rt5631_mono_mux_control =
849 SOC_DAPM_ENUM("MONO SRC", rt5631_mono_src_enum); 836 SOC_DAPM_ENUM("MONO SRC", rt5631_mono_src_enum);
@@ -851,9 +838,8 @@ static const struct snd_kcontrol_new rt5631_mono_mux_control =
851/* Left HPO Input */ 838/* Left HPO Input */
852static const char *rt5631_hpl_src_sel[] = {"Left HPVOL", "Left DAC"}; 839static const char *rt5631_hpl_src_sel[] = {"Left HPVOL", "Left DAC"};
853 840
854static const SOC_ENUM_SINGLE_DECL( 841static SOC_ENUM_SINGLE_DECL(rt5631_hpl_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
855 rt5631_hpl_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, 842 RT5631_HP_L_MUX_SEL_SHIFT, rt5631_hpl_src_sel);
856 RT5631_HP_L_MUX_SEL_SHIFT, rt5631_hpl_src_sel);
857 843
858static const struct snd_kcontrol_new rt5631_hpl_mux_control = 844static const struct snd_kcontrol_new rt5631_hpl_mux_control =
859 SOC_DAPM_ENUM("HPL SRC", rt5631_hpl_src_enum); 845 SOC_DAPM_ENUM("HPL SRC", rt5631_hpl_src_enum);
@@ -861,9 +847,8 @@ static const struct snd_kcontrol_new rt5631_hpl_mux_control =
861/* Right HPO Input */ 847/* Right HPO Input */
862static const char *rt5631_hpr_src_sel[] = {"Right HPVOL", "Right DAC"}; 848static const char *rt5631_hpr_src_sel[] = {"Right HPVOL", "Right DAC"};
863 849
864static const SOC_ENUM_SINGLE_DECL( 850static SOC_ENUM_SINGLE_DECL(rt5631_hpr_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
865 rt5631_hpr_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, 851 RT5631_HP_R_MUX_SEL_SHIFT, rt5631_hpr_src_sel);
866 RT5631_HP_R_MUX_SEL_SHIFT, rt5631_hpr_src_sel);
867 852
868static const struct snd_kcontrol_new rt5631_hpr_mux_control = 853static const struct snd_kcontrol_new rt5631_hpr_mux_control =
869 SOC_DAPM_ENUM("HPR SRC", rt5631_hpr_src_enum); 854 SOC_DAPM_ENUM("HPR SRC", rt5631_hpr_src_enum);
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index a3fb41179636..1a1e1150237d 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -361,25 +361,24 @@ static unsigned int bst_tlv[] = {
361static const char * const rt5640_data_select[] = { 361static const char * const rt5640_data_select[] = {
362 "Normal", "left copy to right", "right copy to left", "Swap"}; 362 "Normal", "left copy to right", "right copy to left", "Swap"};
363 363
364static const SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA, 364static SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA,
365 RT5640_IF1_DAC_SEL_SFT, rt5640_data_select); 365 RT5640_IF1_DAC_SEL_SFT, rt5640_data_select);
366 366
367static const SOC_ENUM_SINGLE_DECL(rt5640_if1_adc_enum, RT5640_DIG_INF_DATA, 367static SOC_ENUM_SINGLE_DECL(rt5640_if1_adc_enum, RT5640_DIG_INF_DATA,
368 RT5640_IF1_ADC_SEL_SFT, rt5640_data_select); 368 RT5640_IF1_ADC_SEL_SFT, rt5640_data_select);
369 369
370static const SOC_ENUM_SINGLE_DECL(rt5640_if2_dac_enum, RT5640_DIG_INF_DATA, 370static SOC_ENUM_SINGLE_DECL(rt5640_if2_dac_enum, RT5640_DIG_INF_DATA,
371 RT5640_IF2_DAC_SEL_SFT, rt5640_data_select); 371 RT5640_IF2_DAC_SEL_SFT, rt5640_data_select);
372 372
373static const SOC_ENUM_SINGLE_DECL(rt5640_if2_adc_enum, RT5640_DIG_INF_DATA, 373static SOC_ENUM_SINGLE_DECL(rt5640_if2_adc_enum, RT5640_DIG_INF_DATA,
374 RT5640_IF2_ADC_SEL_SFT, rt5640_data_select); 374 RT5640_IF2_ADC_SEL_SFT, rt5640_data_select);
375 375
376/* Class D speaker gain ratio */ 376/* Class D speaker gain ratio */
377static const char * const rt5640_clsd_spk_ratio[] = {"1.66x", "1.83x", "1.94x", 377static const char * const rt5640_clsd_spk_ratio[] = {"1.66x", "1.83x", "1.94x",
378 "2x", "2.11x", "2.22x", "2.33x", "2.44x", "2.55x", "2.66x", "2.77x"}; 378 "2x", "2.11x", "2.22x", "2.33x", "2.44x", "2.55x", "2.66x", "2.77x"};
379 379
380static const SOC_ENUM_SINGLE_DECL( 380static SOC_ENUM_SINGLE_DECL(rt5640_clsd_spk_ratio_enum, RT5640_CLS_D_OUT,
381 rt5640_clsd_spk_ratio_enum, RT5640_CLS_D_OUT, 381 RT5640_CLSD_RATIO_SFT, rt5640_clsd_spk_ratio);
382 RT5640_CLSD_RATIO_SFT, rt5640_clsd_spk_ratio);
383 382
384static const struct snd_kcontrol_new rt5640_snd_controls[] = { 383static const struct snd_kcontrol_new rt5640_snd_controls[] = {
385 /* Speaker Output Volume */ 384 /* Speaker Output Volume */
@@ -753,9 +752,8 @@ static const char * const rt5640_stereo_adc1_src[] = {
753 "DIG MIX", "ADC" 752 "DIG MIX", "ADC"
754}; 753};
755 754
756static const SOC_ENUM_SINGLE_DECL( 755static SOC_ENUM_SINGLE_DECL(rt5640_stereo_adc1_enum, RT5640_STO_ADC_MIXER,
757 rt5640_stereo_adc1_enum, RT5640_STO_ADC_MIXER, 756 RT5640_ADC_1_SRC_SFT, rt5640_stereo_adc1_src);
758 RT5640_ADC_1_SRC_SFT, rt5640_stereo_adc1_src);
759 757
760static const struct snd_kcontrol_new rt5640_sto_adc_1_mux = 758static const struct snd_kcontrol_new rt5640_sto_adc_1_mux =
761 SOC_DAPM_ENUM("Stereo ADC1 Mux", rt5640_stereo_adc1_enum); 759 SOC_DAPM_ENUM("Stereo ADC1 Mux", rt5640_stereo_adc1_enum);
@@ -764,9 +762,8 @@ static const char * const rt5640_stereo_adc2_src[] = {
764 "DMIC1", "DMIC2", "DIG MIX" 762 "DMIC1", "DMIC2", "DIG MIX"
765}; 763};
766 764
767static const SOC_ENUM_SINGLE_DECL( 765static SOC_ENUM_SINGLE_DECL(rt5640_stereo_adc2_enum, RT5640_STO_ADC_MIXER,
768 rt5640_stereo_adc2_enum, RT5640_STO_ADC_MIXER, 766 RT5640_ADC_2_SRC_SFT, rt5640_stereo_adc2_src);
769 RT5640_ADC_2_SRC_SFT, rt5640_stereo_adc2_src);
770 767
771static const struct snd_kcontrol_new rt5640_sto_adc_2_mux = 768static const struct snd_kcontrol_new rt5640_sto_adc_2_mux =
772 SOC_DAPM_ENUM("Stereo ADC2 Mux", rt5640_stereo_adc2_enum); 769 SOC_DAPM_ENUM("Stereo ADC2 Mux", rt5640_stereo_adc2_enum);
@@ -776,9 +773,8 @@ static const char * const rt5640_mono_adc_l1_src[] = {
776 "Mono DAC MIXL", "ADCL" 773 "Mono DAC MIXL", "ADCL"
777}; 774};
778 775
779static const SOC_ENUM_SINGLE_DECL( 776static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_l1_enum, RT5640_MONO_ADC_MIXER,
780 rt5640_mono_adc_l1_enum, RT5640_MONO_ADC_MIXER, 777 RT5640_MONO_ADC_L1_SRC_SFT, rt5640_mono_adc_l1_src);
781 RT5640_MONO_ADC_L1_SRC_SFT, rt5640_mono_adc_l1_src);
782 778
783static const struct snd_kcontrol_new rt5640_mono_adc_l1_mux = 779static const struct snd_kcontrol_new rt5640_mono_adc_l1_mux =
784 SOC_DAPM_ENUM("Mono ADC1 left source", rt5640_mono_adc_l1_enum); 780 SOC_DAPM_ENUM("Mono ADC1 left source", rt5640_mono_adc_l1_enum);
@@ -787,9 +783,8 @@ static const char * const rt5640_mono_adc_l2_src[] = {
787 "DMIC L1", "DMIC L2", "Mono DAC MIXL" 783 "DMIC L1", "DMIC L2", "Mono DAC MIXL"
788}; 784};
789 785
790static const SOC_ENUM_SINGLE_DECL( 786static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_l2_enum, RT5640_MONO_ADC_MIXER,
791 rt5640_mono_adc_l2_enum, RT5640_MONO_ADC_MIXER, 787 RT5640_MONO_ADC_L2_SRC_SFT, rt5640_mono_adc_l2_src);
792 RT5640_MONO_ADC_L2_SRC_SFT, rt5640_mono_adc_l2_src);
793 788
794static const struct snd_kcontrol_new rt5640_mono_adc_l2_mux = 789static const struct snd_kcontrol_new rt5640_mono_adc_l2_mux =
795 SOC_DAPM_ENUM("Mono ADC2 left source", rt5640_mono_adc_l2_enum); 790 SOC_DAPM_ENUM("Mono ADC2 left source", rt5640_mono_adc_l2_enum);
@@ -798,9 +793,8 @@ static const char * const rt5640_mono_adc_r1_src[] = {
798 "Mono DAC MIXR", "ADCR" 793 "Mono DAC MIXR", "ADCR"
799}; 794};
800 795
801static const SOC_ENUM_SINGLE_DECL( 796static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_r1_enum, RT5640_MONO_ADC_MIXER,
802 rt5640_mono_adc_r1_enum, RT5640_MONO_ADC_MIXER, 797 RT5640_MONO_ADC_R1_SRC_SFT, rt5640_mono_adc_r1_src);
803 RT5640_MONO_ADC_R1_SRC_SFT, rt5640_mono_adc_r1_src);
804 798
805static const struct snd_kcontrol_new rt5640_mono_adc_r1_mux = 799static const struct snd_kcontrol_new rt5640_mono_adc_r1_mux =
806 SOC_DAPM_ENUM("Mono ADC1 right source", rt5640_mono_adc_r1_enum); 800 SOC_DAPM_ENUM("Mono ADC1 right source", rt5640_mono_adc_r1_enum);
@@ -809,9 +803,8 @@ static const char * const rt5640_mono_adc_r2_src[] = {
809 "DMIC R1", "DMIC R2", "Mono DAC MIXR" 803 "DMIC R1", "DMIC R2", "Mono DAC MIXR"
810}; 804};
811 805
812static const SOC_ENUM_SINGLE_DECL( 806static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_r2_enum, RT5640_MONO_ADC_MIXER,
813 rt5640_mono_adc_r2_enum, RT5640_MONO_ADC_MIXER, 807 RT5640_MONO_ADC_R2_SRC_SFT, rt5640_mono_adc_r2_src);
814 RT5640_MONO_ADC_R2_SRC_SFT, rt5640_mono_adc_r2_src);
815 808
816static const struct snd_kcontrol_new rt5640_mono_adc_r2_mux = 809static const struct snd_kcontrol_new rt5640_mono_adc_r2_mux =
817 SOC_DAPM_ENUM("Mono ADC2 right source", rt5640_mono_adc_r2_enum); 810 SOC_DAPM_ENUM("Mono ADC2 right source", rt5640_mono_adc_r2_enum);
@@ -826,9 +819,9 @@ static int rt5640_dac_l2_values[] = {
826 3, 819 3,
827}; 820};
828 821
829static const SOC_VALUE_ENUM_SINGLE_DECL( 822static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dac_l2_enum,
830 rt5640_dac_l2_enum, RT5640_DSP_PATH2, RT5640_DAC_L2_SEL_SFT, 823 RT5640_DSP_PATH2, RT5640_DAC_L2_SEL_SFT,
831 0x3, rt5640_dac_l2_src, rt5640_dac_l2_values); 824 0x3, rt5640_dac_l2_src, rt5640_dac_l2_values);
832 825
833static const struct snd_kcontrol_new rt5640_dac_l2_mux = 826static const struct snd_kcontrol_new rt5640_dac_l2_mux =
834 SOC_DAPM_VALUE_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); 827 SOC_DAPM_VALUE_ENUM("DAC2 left channel source", rt5640_dac_l2_enum);
@@ -841,9 +834,9 @@ static int rt5640_dac_r2_values[] = {
841 0, 834 0,
842}; 835};
843 836
844static const SOC_VALUE_ENUM_SINGLE_DECL( 837static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dac_r2_enum,
845 rt5640_dac_r2_enum, RT5640_DSP_PATH2, RT5640_DAC_R2_SEL_SFT, 838 RT5640_DSP_PATH2, RT5640_DAC_R2_SEL_SFT,
846 0x3, rt5640_dac_r2_src, rt5640_dac_r2_values); 839 0x3, rt5640_dac_r2_src, rt5640_dac_r2_values);
847 840
848static const struct snd_kcontrol_new rt5640_dac_r2_mux = 841static const struct snd_kcontrol_new rt5640_dac_r2_mux =
849 SOC_DAPM_ENUM("DAC2 right channel source", rt5640_dac_r2_enum); 842 SOC_DAPM_ENUM("DAC2 right channel source", rt5640_dac_r2_enum);
@@ -860,9 +853,10 @@ static int rt5640_dai_iis_map_values[] = {
860 7, 853 7,
861}; 854};
862 855
863static const SOC_VALUE_ENUM_SINGLE_DECL( 856static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dai_iis_map_enum,
864 rt5640_dai_iis_map_enum, RT5640_I2S1_SDP, RT5640_I2S_IF_SFT, 857 RT5640_I2S1_SDP, RT5640_I2S_IF_SFT,
865 0x7, rt5640_dai_iis_map, rt5640_dai_iis_map_values); 858 0x7, rt5640_dai_iis_map,
859 rt5640_dai_iis_map_values);
866 860
867static const struct snd_kcontrol_new rt5640_dai_mux = 861static const struct snd_kcontrol_new rt5640_dai_mux =
868 SOC_DAPM_VALUE_ENUM("DAI select", rt5640_dai_iis_map_enum); 862 SOC_DAPM_VALUE_ENUM("DAI select", rt5640_dai_iis_map_enum);
@@ -872,9 +866,8 @@ static const char * const rt5640_sdi_sel[] = {
872 "IF1", "IF2" 866 "IF1", "IF2"
873}; 867};
874 868
875static const SOC_ENUM_SINGLE_DECL( 869static SOC_ENUM_SINGLE_DECL(rt5640_sdi_sel_enum, RT5640_I2S2_SDP,
876 rt5640_sdi_sel_enum, RT5640_I2S2_SDP, 870 RT5640_I2S2_SDI_SFT, rt5640_sdi_sel);
877 RT5640_I2S2_SDI_SFT, rt5640_sdi_sel);
878 871
879static const struct snd_kcontrol_new rt5640_sdi_mux = 872static const struct snd_kcontrol_new rt5640_sdi_mux =
880 SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); 873 SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum);
@@ -2093,6 +2086,7 @@ MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id);
2093#ifdef CONFIG_ACPI 2086#ifdef CONFIG_ACPI
2094static struct acpi_device_id rt5640_acpi_match[] = { 2087static struct acpi_device_id rt5640_acpi_match[] = {
2095 { "INT33CA", 0 }, 2088 { "INT33CA", 0 },
2089 { "10EC5640", 0 },
2096 { }, 2090 { },
2097}; 2091};
2098MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); 2092MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match);
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
index 52e7cb08434b..fa2b8e07f420 100644
--- a/sound/soc/codecs/si476x.c
+++ b/sound/soc/codecs/si476x.c
@@ -210,7 +210,7 @@ out:
210static int si476x_codec_probe(struct snd_soc_codec *codec) 210static int si476x_codec_probe(struct snd_soc_codec *codec)
211{ 211{
212 codec->control_data = dev_get_regmap(codec->dev->parent, NULL); 212 codec->control_data = dev_get_regmap(codec->dev->parent, NULL);
213 return 0; 213 return snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
214} 214}
215 215
216static struct snd_soc_dai_ops si476x_dai_ops = { 216static struct snd_soc_dai_ops si476x_dai_ops = {
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
index cc8debce752f..806f3d826ffb 100644
--- a/sound/soc/codecs/ssm2518.c
+++ b/sound/soc/codecs/ssm2518.c
@@ -169,19 +169,19 @@ static const char * const ssm2518_drc_hold_time_text[] = {
169 "682.24 ms", "1364 ms", 169 "682.24 ms", "1364 ms",
170}; 170};
171 171
172static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum, 172static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum,
173 SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text); 173 SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text);
174static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum, 174static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum,
175 SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text); 175 SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text);
176static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum, 176static SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum,
177 SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text); 177 SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text);
178static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum, 178static SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum,
179 SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text); 179 SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text);
180static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum, 180static SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum,
181 SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text); 181 SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text);
182static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum, 182static SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum,
183 SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text); 183 SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text);
184static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum, 184static SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum,
185 SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text); 185 SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text);
186 186
187static const struct snd_kcontrol_new ssm2518_snd_controls[] = { 187static const struct snd_kcontrol_new ssm2518_snd_controls[] = {
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index 06edb396e733..2735361a4c3c 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -187,42 +187,42 @@ static const unsigned int sta32x_limiter_drc_release_tlv[] = {
187 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), 187 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0),
188}; 188};
189 189
190static const struct soc_enum sta32x_drc_ac_enum = 190static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum,
191 SOC_ENUM_SINGLE(STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, 191 STA32X_CONFD, STA32X_CONFD_DRC_SHIFT,
192 2, sta32x_drc_ac); 192 sta32x_drc_ac);
193static const struct soc_enum sta32x_auto_eq_enum = 193static SOC_ENUM_SINGLE_DECL(sta32x_auto_eq_enum,
194 SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT, 194 STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT,
195 3, sta32x_auto_eq_mode); 195 sta32x_auto_eq_mode);
196static const struct soc_enum sta32x_auto_gc_enum = 196static SOC_ENUM_SINGLE_DECL(sta32x_auto_gc_enum,
197 SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT, 197 STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT,
198 4, sta32x_auto_gc_mode); 198 sta32x_auto_gc_mode);
199static const struct soc_enum sta32x_auto_xo_enum = 199static SOC_ENUM_SINGLE_DECL(sta32x_auto_xo_enum,
200 SOC_ENUM_SINGLE(STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT, 200 STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT,
201 16, sta32x_auto_xo_mode); 201 sta32x_auto_xo_mode);
202static const struct soc_enum sta32x_preset_eq_enum = 202static SOC_ENUM_SINGLE_DECL(sta32x_preset_eq_enum,
203 SOC_ENUM_SINGLE(STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT, 203 STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT,
204 32, sta32x_preset_eq_mode); 204 sta32x_preset_eq_mode);
205static const struct soc_enum sta32x_limiter_ch1_enum = 205static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch1_enum,
206 SOC_ENUM_SINGLE(STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT, 206 STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT,
207 3, sta32x_limiter_select); 207 sta32x_limiter_select);
208static const struct soc_enum sta32x_limiter_ch2_enum = 208static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch2_enum,
209 SOC_ENUM_SINGLE(STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT, 209 STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT,
210 3, sta32x_limiter_select); 210 sta32x_limiter_select);
211static const struct soc_enum sta32x_limiter_ch3_enum = 211static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch3_enum,
212 SOC_ENUM_SINGLE(STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT, 212 STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT,
213 3, sta32x_limiter_select); 213 sta32x_limiter_select);
214static const struct soc_enum sta32x_limiter1_attack_rate_enum = 214static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_attack_rate_enum,
215 SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxA_SHIFT, 215 STA32X_L1AR, STA32X_LxA_SHIFT,
216 16, sta32x_limiter_attack_rate); 216 sta32x_limiter_attack_rate);
217static const struct soc_enum sta32x_limiter2_attack_rate_enum = 217static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_attack_rate_enum,
218 SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxA_SHIFT, 218 STA32X_L2AR, STA32X_LxA_SHIFT,
219 16, sta32x_limiter_attack_rate); 219 sta32x_limiter_attack_rate);
220static const struct soc_enum sta32x_limiter1_release_rate_enum = 220static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_release_rate_enum,
221 SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxR_SHIFT, 221 STA32X_L1AR, STA32X_LxR_SHIFT,
222 16, sta32x_limiter_release_rate); 222 sta32x_limiter_release_rate);
223static const struct soc_enum sta32x_limiter2_release_rate_enum = 223static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_release_rate_enum,
224 SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxR_SHIFT, 224 STA32X_L2AR, STA32X_LxR_SHIFT,
225 16, sta32x_limiter_release_rate); 225 sta32x_limiter_release_rate);
226 226
227/* byte array controls for setting biquad, mixer, scaling coefficients; 227/* byte array controls for setting biquad, mixer, scaling coefficients;
228 * for biquads all five coefficients need to be set in one go, 228 * for biquads all five coefficients need to be set in one go,
@@ -331,7 +331,7 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
331 331
332static int sta32x_cache_sync(struct snd_soc_codec *codec) 332static int sta32x_cache_sync(struct snd_soc_codec *codec)
333{ 333{
334 struct sta32x_priv *sta32x = codec->control_data; 334 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
335 unsigned int mute; 335 unsigned int mute;
336 int rc; 336 int rc;
337 337
@@ -434,7 +434,7 @@ SOC_SINGLE_TLV("Treble Tone Control", STA32X_TONE, STA32X_TONE_TTC_SHIFT, 15, 0,
434SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum), 434SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum),
435SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum), 435SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum),
436SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), 436SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum),
437SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), 437SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter2_release_rate_enum),
438 438
439/* depending on mode, the attack/release thresholds have 439/* depending on mode, the attack/release thresholds have
440 * two different enum definitions; provide both 440 * two different enum definitions; provide both
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index 40c07be9b581..f15b0e37274c 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -141,7 +141,7 @@ static const char *pwm_mode_text[] = { "Binary", "Headphone", "Ternary",
141 141
142static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -9150, 50, 0); 142static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -9150, 50, 0);
143static const DECLARE_TLV_DB_SCALE(master_vol_tlv, -12750, 50, 0); 143static const DECLARE_TLV_DB_SCALE(master_vol_tlv, -12750, 50, 0);
144static const SOC_ENUM_SINGLE_DECL(pwm_src, STA529_FFXCFG1, 4, pwm_mode_text); 144static SOC_ENUM_SINGLE_DECL(pwm_src, STA529_FFXCFG1, 4, pwm_mode_text);
145 145
146static const struct snd_kcontrol_new sta529_snd_controls[] = { 146static const struct snd_kcontrol_new sta529_snd_controls[] = {
147 SOC_DOUBLE_R_TLV("Digital Playback Volume", STA529_LVOL, STA529_RVOL, 0, 147 SOC_DOUBLE_R_TLV("Digital Playback Volume", STA529_LVOL, STA529_RVOL, 0,
diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c
new file mode 100644
index 000000000000..20fc46092c2c
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23-i2c.c
@@ -0,0 +1,59 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver I2C interface
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
6 *
7 * Based on sound/soc/codecs/wm8731.c by Richard Purdie
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/i2c.h>
15#include <linux/module.h>
16#include <linux/regmap.h>
17#include <sound/soc.h>
18
19#include "tlv320aic23.h"
20
21static int tlv320aic23_i2c_probe(struct i2c_client *i2c,
22 const struct i2c_device_id *i2c_id)
23{
24 struct regmap *regmap;
25
26 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
27 return -EINVAL;
28
29 regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap);
30 return tlv320aic23_probe(&i2c->dev, regmap);
31}
32
33static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
34{
35 snd_soc_unregister_codec(&i2c->dev);
36 return 0;
37}
38
39static const struct i2c_device_id tlv320aic23_id[] = {
40 {"tlv320aic23", 0},
41 {}
42};
43
44MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
45
46static struct i2c_driver tlv320aic23_i2c_driver = {
47 .driver = {
48 .name = "tlv320aic23-codec",
49 },
50 .probe = tlv320aic23_i2c_probe,
51 .remove = __exit_p(tlv320aic23_i2c_remove),
52 .id_table = tlv320aic23_id,
53};
54
55module_i2c_driver(tlv320aic23_i2c_driver);
56
57MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver I2C");
58MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
59MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23-spi.c b/sound/soc/codecs/tlv320aic23-spi.c
new file mode 100644
index 000000000000..585aea436c6a
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23-spi.c
@@ -0,0 +1,57 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver SPI interface
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
6 *
7 * Based on sound/soc/codecs/wm8731.c by Richard Purdie
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/regmap.h>
16#include <linux/spi/spi.h>
17#include <sound/soc.h>
18
19#include "tlv320aic23.h"
20
21static int aic23_spi_probe(struct spi_device *spi)
22{
23 int ret;
24 struct regmap *regmap;
25
26 dev_dbg(&spi->dev, "probing tlv320aic23 spi device\n");
27
28 spi->bits_per_word = 16;
29 spi->mode = SPI_MODE_0;
30 ret = spi_setup(spi);
31 if (ret < 0)
32 return ret;
33
34 regmap = devm_regmap_init_spi(spi, &tlv320aic23_regmap);
35 return tlv320aic23_probe(&spi->dev, regmap);
36}
37
38static int aic23_spi_remove(struct spi_device *spi)
39{
40 snd_soc_unregister_codec(&spi->dev);
41 return 0;
42}
43
44static struct spi_driver aic23_spi = {
45 .driver = {
46 .name = "tlv320aic23",
47 .owner = THIS_MODULE,
48 },
49 .probe = aic23_spi_probe,
50 .remove = aic23_spi_remove,
51};
52
53module_spi_driver(aic23_spi);
54
55MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver SPI");
56MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
57MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 5d430cc56f51..27261e4b27c7 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -23,7 +23,6 @@
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/pm.h> 25#include <linux/pm.h>
26#include <linux/i2c.h>
27#include <linux/regmap.h> 26#include <linux/regmap.h>
28#include <linux/slab.h> 27#include <linux/slab.h>
29#include <sound/core.h> 28#include <sound/core.h>
@@ -51,7 +50,7 @@ static const struct reg_default tlv320aic23_reg[] = {
51 { 9, 0x0000 }, 50 { 9, 0x0000 },
52}; 51};
53 52
54static const struct regmap_config tlv320aic23_regmap = { 53const struct regmap_config tlv320aic23_regmap = {
55 .reg_bits = 7, 54 .reg_bits = 7,
56 .val_bits = 9, 55 .val_bits = 9,
57 56
@@ -64,16 +63,16 @@ static const struct regmap_config tlv320aic23_regmap = {
64static const char *rec_src_text[] = { "Line", "Mic" }; 63static const char *rec_src_text[] = { "Line", "Mic" };
65static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 64static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
66 65
67static const struct soc_enum rec_src_enum = 66static SOC_ENUM_SINGLE_DECL(rec_src_enum,
68 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); 67 TLV320AIC23_ANLG, 2, rec_src_text);
69 68
70static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls = 69static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
71SOC_DAPM_ENUM("Input Select", rec_src_enum); 70SOC_DAPM_ENUM("Input Select", rec_src_enum);
72 71
73static const struct soc_enum tlv320aic23_rec_src = 72static SOC_ENUM_SINGLE_DECL(tlv320aic23_rec_src,
74 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); 73 TLV320AIC23_ANLG, 2, rec_src_text);
75static const struct soc_enum tlv320aic23_deemph = 74static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph,
76 SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text); 75 TLV320AIC23_DIGT, 1, deemph_text);
77 76
78static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0); 77static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
79static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0); 78static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
@@ -400,7 +399,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
400 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); 399 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
401 400
402 /* deactivate */ 401 /* deactivate */
403 if (!codec->active) { 402 if (!snd_soc_codec_is_active(codec)) {
404 udelay(50); 403 udelay(50);
405 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); 404 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
406 } 405 }
@@ -557,7 +556,7 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec)
557 return 0; 556 return 0;
558} 557}
559 558
560static int tlv320aic23_probe(struct snd_soc_codec *codec) 559static int tlv320aic23_codec_probe(struct snd_soc_codec *codec)
561{ 560{
562 int ret; 561 int ret;
563 562
@@ -604,7 +603,7 @@ static int tlv320aic23_remove(struct snd_soc_codec *codec)
604} 603}
605 604
606static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { 605static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
607 .probe = tlv320aic23_probe, 606 .probe = tlv320aic23_codec_probe,
608 .remove = tlv320aic23_remove, 607 .remove = tlv320aic23_remove,
609 .suspend = tlv320aic23_suspend, 608 .suspend = tlv320aic23_suspend,
610 .resume = tlv320aic23_resume, 609 .resume = tlv320aic23_resume,
@@ -617,57 +616,25 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
617 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), 616 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
618}; 617};
619 618
620/* 619int tlv320aic23_probe(struct device *dev, struct regmap *regmap)
621 * If the i2c layer weren't so broken, we could pass this kind of data
622 * around
623 */
624static int tlv320aic23_codec_probe(struct i2c_client *i2c,
625 const struct i2c_device_id *i2c_id)
626{ 620{
627 struct aic23 *aic23; 621 struct aic23 *aic23;
628 int ret;
629 622
630 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 623 if (IS_ERR(regmap))
631 return -EINVAL; 624 return PTR_ERR(regmap);
632 625
633 aic23 = devm_kzalloc(&i2c->dev, sizeof(struct aic23), GFP_KERNEL); 626 aic23 = devm_kzalloc(dev, sizeof(struct aic23), GFP_KERNEL);
634 if (aic23 == NULL) 627 if (aic23 == NULL)
635 return -ENOMEM; 628 return -ENOMEM;
636 629
637 aic23->regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap); 630 aic23->regmap = regmap;
638 if (IS_ERR(aic23->regmap))
639 return PTR_ERR(aic23->regmap);
640 631
641 i2c_set_clientdata(i2c, aic23); 632 dev_set_drvdata(dev, aic23);
642 633
643 ret = snd_soc_register_codec(&i2c->dev, 634 return snd_soc_register_codec(dev, &soc_codec_dev_tlv320aic23,
644 &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1); 635 &tlv320aic23_dai, 1);
645 return ret;
646}
647static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
648{
649 snd_soc_unregister_codec(&i2c->dev);
650 return 0;
651} 636}
652 637
653static const struct i2c_device_id tlv320aic23_id[] = {
654 {"tlv320aic23", 0},
655 {}
656};
657
658MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
659
660static struct i2c_driver tlv320aic23_i2c_driver = {
661 .driver = {
662 .name = "tlv320aic23-codec",
663 },
664 .probe = tlv320aic23_codec_probe,
665 .remove = __exit_p(tlv320aic23_i2c_remove),
666 .id_table = tlv320aic23_id,
667};
668
669module_i2c_driver(tlv320aic23_i2c_driver);
670
671MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver"); 638MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
672MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); 639MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
673MODULE_LICENSE("GPL"); 640MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.h b/sound/soc/codecs/tlv320aic23.h
index e804120bd3da..3a7235a04a89 100644
--- a/sound/soc/codecs/tlv320aic23.h
+++ b/sound/soc/codecs/tlv320aic23.h
@@ -12,6 +12,12 @@
12#ifndef _TLV320AIC23_H 12#ifndef _TLV320AIC23_H
13#define _TLV320AIC23_H 13#define _TLV320AIC23_H
14 14
15struct device;
16struct regmap_config;
17
18extern const struct regmap_config tlv320aic23_regmap;
19int tlv320aic23_probe(struct device *dev, struct regmap *regmap);
20
15/* Codec TLV320AIC23 */ 21/* Codec TLV320AIC23 */
16#define TLV320AIC23_LINVOL 0x00 22#define TLV320AIC23_LINVOL 0x00
17#define TLV320AIC23_RINVOL 0x01 23#define TLV320AIC23_RINVOL 0x01
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 4f358393d6d6..35b2d244e42e 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -461,7 +461,7 @@ static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
461 if (dac33->fifo_mode == ucontrol->value.integer.value[0]) 461 if (dac33->fifo_mode == ucontrol->value.integer.value[0])
462 return 0; 462 return 0;
463 /* Do not allow changes while stream is running*/ 463 /* Do not allow changes while stream is running*/
464 if (codec->active) 464 if (snd_soc_codec_is_active(codec))
465 return -EPERM; 465 return -EPERM;
466 466
467 if (ucontrol->value.integer.value[0] < 0 || 467 if (ucontrol->value.integer.value[0] < 0 ||
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 00665ada23e2..682e4ac88939 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -965,9 +965,6 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
965{ 965{
966 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 966 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
967 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 967 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
968 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
969 unsigned short val;
970 unsigned short mask;
971 968
972 if (twl4030->configured) { 969 if (twl4030->configured) {
973 dev_err(codec->dev, 970 dev_err(codec->dev,
@@ -975,19 +972,7 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
975 return -EBUSY; 972 return -EBUSY;
976 } 973 }
977 974
978 if (ucontrol->value.enumerated.item[0] > e->max - 1) 975 return snd_soc_put_enum_double(kcontrol, ucontrol);
979 return -EINVAL;
980
981 val = ucontrol->value.enumerated.item[0] << e->shift_l;
982 mask = e->mask << e->shift_l;
983 if (e->shift_l != e->shift_r) {
984 if (ucontrol->value.enumerated.item[1] > e->max - 1)
985 return -EINVAL;
986 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
987 mask |= e->mask << e->shift_r;
988 }
989
990 return snd_soc_update_bits(codec, e->reg, mask, val);
991} 976}
992 977
993/* 978/*
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 726df6d43c2b..8e3940dcff20 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -108,7 +108,7 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
108 /* the interpolator & decimator regs must only be written when the 108 /* the interpolator & decimator regs must only be written when the
109 * codec DAI is active. 109 * codec DAI is active.
110 */ 110 */
111 if (!codec->active && (reg >= UDA1380_MVOL)) 111 if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL))
112 return 0; 112 return 0;
113 pr_debug("uda1380: hw write %x val %x\n", reg, value); 113 pr_debug("uda1380: hw write %x val %x\n", reg, value);
114 if (codec->hw_write(codec->control_data, data, 3) == 3) { 114 if (codec->hw_write(codec->control_data, data, 3) == 3) {
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index b7ab2ef567c8..47e96ff30064 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -197,7 +197,7 @@ static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
197 return 0; 197 return 0;
198 198
199 /* Do not allow changes while stream is running */ 199 /* Do not allow changes while stream is running */
200 if (codec->active) 200 if (snd_soc_codec_is_active(codec))
201 return -EPERM; 201 return -EPERM;
202 202
203 if (ucontrol->value.integer.value[0] < 0 || 203 if (ucontrol->value.integer.value[0] < 0 ||
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 4e3e31aaf509..492fe846ae68 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -2100,6 +2100,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2100int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) 2100int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2101{ 2101{
2102 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); 2102 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2103 struct snd_soc_dapm_context *dapm = &codec->dapm;
2103 2104
2104 if (jack) { 2105 if (jack) {
2105 wm5100->jack = jack; 2106 wm5100->jack = jack;
@@ -2117,9 +2118,14 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2117 WM5100_ACCDET_RATE_MASK); 2118 WM5100_ACCDET_RATE_MASK);
2118 2119
2119 /* We need the charge pump to power MICBIAS */ 2120 /* We need the charge pump to power MICBIAS */
2120 snd_soc_dapm_force_enable_pin(&codec->dapm, "CP2"); 2121 snd_soc_dapm_mutex_lock(dapm);
2121 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); 2122
2122 snd_soc_dapm_sync(&codec->dapm); 2123 snd_soc_dapm_force_enable_pin_unlocked(dapm, "CP2");
2124 snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK");
2125
2126 snd_soc_dapm_sync_unlocked(dapm);
2127
2128 snd_soc_dapm_mutex_unlock(dapm);
2123 2129
2124 /* We start off just enabling microphone detection - even a 2130 /* We start off just enabling microphone detection - even a
2125 * plain headphone will trigger detection. 2131 * plain headphone will trigger detection.
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index ce9c8e14d4bd..34109050ceed 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -582,7 +582,7 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
582{ 582{
583 struct snd_soc_codec *codec = w->codec; 583 struct snd_soc_codec *codec = w->codec;
584 struct arizona *arizona = dev_get_drvdata(codec->dev->parent); 584 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
585 struct regmap *regmap = codec->control_data; 585 struct regmap *regmap = arizona->regmap;
586 const struct reg_default *patch = NULL; 586 const struct reg_default *patch = NULL;
587 int i, patch_size; 587 int i, patch_size;
588 588
@@ -622,13 +622,16 @@ static const unsigned int wm5102_osr_val[] = {
622 622
623static const struct soc_enum wm5102_hpout_osr[] = { 623static const struct soc_enum wm5102_hpout_osr[] = {
624 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, 624 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
625 ARIZONA_OUT1_OSR_SHIFT, 0x7, 3, 625 ARIZONA_OUT1_OSR_SHIFT, 0x7,
626 ARRAY_SIZE(wm5102_osr_text),
626 wm5102_osr_text, wm5102_osr_val), 627 wm5102_osr_text, wm5102_osr_val),
627 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L, 628 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
628 ARIZONA_OUT2_OSR_SHIFT, 0x7, 3, 629 ARIZONA_OUT2_OSR_SHIFT, 0x7,
630 ARRAY_SIZE(wm5102_osr_text),
629 wm5102_osr_text, wm5102_osr_val), 631 wm5102_osr_text, wm5102_osr_val),
630 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, 632 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
631 ARIZONA_OUT3_OSR_SHIFT, 0x7, 3, 633 ARIZONA_OUT3_OSR_SHIFT, 0x7,
634 ARRAY_SIZE(wm5102_osr_text),
632 wm5102_osr_text, wm5102_osr_val), 635 wm5102_osr_text, wm5102_osr_val),
633}; 636};
634 637
@@ -685,15 +688,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
685ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), 688ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
686ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), 689ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
687 690
688SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21, 691SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19),
689 ARIZONA_EQ1_ENA_MASK), 692SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0),
690SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21,
691 ARIZONA_EQ2_ENA_MASK),
692SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21,
693 ARIZONA_EQ3_ENA_MASK),
694SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21,
695 ARIZONA_EQ4_ENA_MASK),
696
697SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, 693SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
698 24, 0, eq_tlv), 694 24, 0, eq_tlv),
699SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, 695SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
@@ -705,6 +701,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
705SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, 701SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
706 24, 0, eq_tlv), 702 24, 0, eq_tlv),
707 703
704SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19),
705SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0),
708SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, 706SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
709 24, 0, eq_tlv), 707 24, 0, eq_tlv),
710SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, 708SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
@@ -716,6 +714,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
716SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, 714SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
717 24, 0, eq_tlv), 715 24, 0, eq_tlv),
718 716
717SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19),
718SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0),
719SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, 719SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
720 24, 0, eq_tlv), 720 24, 0, eq_tlv),
721SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, 721SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
@@ -727,6 +727,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
727SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, 727SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
728 24, 0, eq_tlv), 728 24, 0, eq_tlv),
729 729
730SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19),
731SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0),
730SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, 732SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
731 24, 0, eq_tlv), 733 24, 0, eq_tlv),
732SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, 734SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 2c3c962d9a85..d7bf8848174a 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -136,7 +136,7 @@ static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w,
136{ 136{
137 struct snd_soc_codec *codec = w->codec; 137 struct snd_soc_codec *codec = w->codec;
138 struct arizona *arizona = dev_get_drvdata(codec->dev->parent); 138 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
139 struct regmap *regmap = codec->control_data; 139 struct regmap *regmap = arizona->regmap;
140 const struct reg_default *patch = NULL; 140 const struct reg_default *patch = NULL;
141 int i, patch_size; 141 int i, patch_size;
142 142
@@ -247,15 +247,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
247ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), 247ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
248ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), 248ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
249 249
250SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21, 250SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19),
251 ARIZONA_EQ1_ENA_MASK), 251SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0),
252SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21,
253 ARIZONA_EQ2_ENA_MASK),
254SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21,
255 ARIZONA_EQ3_ENA_MASK),
256SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21,
257 ARIZONA_EQ4_ENA_MASK),
258
259SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, 252SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
260 24, 0, eq_tlv), 253 24, 0, eq_tlv),
261SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, 254SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
@@ -267,6 +260,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
267SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, 260SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
268 24, 0, eq_tlv), 261 24, 0, eq_tlv),
269 262
263SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19),
264SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0),
270SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, 265SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
271 24, 0, eq_tlv), 266 24, 0, eq_tlv),
272SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, 267SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
@@ -278,6 +273,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
278SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, 273SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
279 24, 0, eq_tlv), 274 24, 0, eq_tlv),
280 275
276SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19),
277SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0),
281SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, 278SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
282 24, 0, eq_tlv), 279 24, 0, eq_tlv),
283SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, 280SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
@@ -289,6 +286,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
289SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, 286SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
290 24, 0, eq_tlv), 287 24, 0, eq_tlv),
291 288
289SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19),
290SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0),
292SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, 291SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
293 24, 0, eq_tlv), 292 24, 0, eq_tlv),
294SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, 293SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 48dc7d2fee36..6d684d934f4d 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -117,19 +117,23 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
117static const char *wm8400_digital_sidetone[] = 117static const char *wm8400_digital_sidetone[] =
118 {"None", "Left ADC", "Right ADC", "Reserved"}; 118 {"None", "Left ADC", "Right ADC", "Reserved"};
119 119
120static const struct soc_enum wm8400_left_digital_sidetone_enum = 120static SOC_ENUM_SINGLE_DECL(wm8400_left_digital_sidetone_enum,
121SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, 121 WM8400_DIGITAL_SIDE_TONE,
122 WM8400_ADC_TO_DACL_SHIFT, 2, wm8400_digital_sidetone); 122 WM8400_ADC_TO_DACL_SHIFT,
123 wm8400_digital_sidetone);
123 124
124static const struct soc_enum wm8400_right_digital_sidetone_enum = 125static SOC_ENUM_SINGLE_DECL(wm8400_right_digital_sidetone_enum,
125SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, 126 WM8400_DIGITAL_SIDE_TONE,
126 WM8400_ADC_TO_DACR_SHIFT, 2, wm8400_digital_sidetone); 127 WM8400_ADC_TO_DACR_SHIFT,
128 wm8400_digital_sidetone);
127 129
128static const char *wm8400_adcmode[] = 130static const char *wm8400_adcmode[] =
129 {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; 131 {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
130 132
131static const struct soc_enum wm8400_right_adcmode_enum = 133static SOC_ENUM_SINGLE_DECL(wm8400_right_adcmode_enum,
132SOC_ENUM_SINGLE(WM8400_ADC_CTRL, WM8400_ADC_HPF_CUT_SHIFT, 3, wm8400_adcmode); 134 WM8400_ADC_CTRL,
135 WM8400_ADC_HPF_CUT_SHIFT,
136 wm8400_adcmode);
133 137
134static const struct snd_kcontrol_new wm8400_snd_controls[] = { 138static const struct snd_kcontrol_new wm8400_snd_controls[] = {
135/* INMIXL */ 139/* INMIXL */
@@ -422,9 +426,10 @@ SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT,
422static const char *wm8400_ainlmux[] = 426static const char *wm8400_ainlmux[] =
423 {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; 427 {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
424 428
425static const struct soc_enum wm8400_ainlmux_enum = 429static SOC_ENUM_SINGLE_DECL(wm8400_ainlmux_enum,
426SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINLMODE_SHIFT, 430 WM8400_INPUT_MIXER1,
427 ARRAY_SIZE(wm8400_ainlmux), wm8400_ainlmux); 431 WM8400_AINLMODE_SHIFT,
432 wm8400_ainlmux);
428 433
429static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls = 434static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls =
430SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); 435SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum);
@@ -435,9 +440,10 @@ SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum);
435static const char *wm8400_ainrmux[] = 440static const char *wm8400_ainrmux[] =
436 {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; 441 {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
437 442
438static const struct soc_enum wm8400_ainrmux_enum = 443static SOC_ENUM_SINGLE_DECL(wm8400_ainrmux_enum,
439SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINRMODE_SHIFT, 444 WM8400_INPUT_MIXER1,
440 ARRAY_SIZE(wm8400_ainrmux), wm8400_ainrmux); 445 WM8400_AINRMODE_SHIFT,
446 wm8400_ainrmux);
441 447
442static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = 448static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls =
443SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); 449SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum);
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index d99f948c513c..6efcc40a7cb3 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -201,7 +201,7 @@ static void wm8711_shutdown(struct snd_pcm_substream *substream,
201 struct snd_soc_codec *codec = dai->codec; 201 struct snd_soc_codec *codec = dai->codec;
202 202
203 /* deactivate */ 203 /* deactivate */
204 if (!codec->active) { 204 if (!snd_soc_codec_is_active(codec)) {
205 udelay(50); 205 udelay(50);
206 snd_soc_write(codec, WM8711_ACTIVE, 0x0); 206 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
207 } 207 }
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index be85da93a268..5cf4bebc5d89 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -251,7 +251,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
251 if (wm8753->dai_func == ucontrol->value.integer.value[0]) 251 if (wm8753->dai_func == ucontrol->value.integer.value[0])
252 return 0; 252 return 0;
253 253
254 if (codec->active) 254 if (snd_soc_codec_is_active(codec))
255 return -EBUSY; 255 return -EBUSY;
256 256
257 ioctl = snd_soc_read(codec, WM8753_IOCTL); 257 ioctl = snd_soc_read(codec, WM8753_IOCTL);
@@ -1314,7 +1314,7 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1314 /* the digital mute covers the HiFi and Voice DAC's on the WM8753. 1314 /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
1315 * make sure we check if they are not both active when we mute */ 1315 * make sure we check if they are not both active when we mute */
1316 if (mute && wm8753->dai_func == 1) { 1316 if (mute && wm8753->dai_func == 1) {
1317 if (!codec->active) 1317 if (!snd_soc_codec_is_active(codec))
1318 snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8); 1318 snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
1319 } else { 1319 } else {
1320 if (mute) 1320 if (mute)
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index 89a18d82f303..5bce21013485 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -196,8 +196,8 @@ static const char *ain_text[] = {
196 "AIN5", "AIN6", "AIN7", "AIN8" 196 "AIN5", "AIN6", "AIN7", "AIN8"
197}; 197};
198 198
199static const struct soc_enum ain_enum = 199static SOC_ENUM_DOUBLE_DECL(ain_enum,
200 SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text); 200 WM8770_ADCMUX, 0, 4, ain_text);
201 201
202static const struct snd_kcontrol_new ain_mux = 202static const struct snd_kcontrol_new ain_mux =
203 SOC_DAPM_ENUM("Capture Mux", ain_enum); 203 SOC_DAPM_ENUM("Capture Mux", ain_enum);
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 9bc8206a6807..72d12bbe1a56 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -92,7 +92,7 @@ WM8804_REGULATOR_EVENT(0)
92WM8804_REGULATOR_EVENT(1) 92WM8804_REGULATOR_EVENT(1)
93 93
94static const char *txsrc_text[] = { "S/PDIF RX", "AIF" }; 94static const char *txsrc_text[] = { "S/PDIF RX", "AIF" };
95static const SOC_ENUM_SINGLE_EXT_DECL(txsrc, txsrc_text); 95static SOC_ENUM_SINGLE_EXT_DECL(txsrc, txsrc_text);
96 96
97static const struct snd_kcontrol_new wm8804_snd_controls[] = { 97static const struct snd_kcontrol_new wm8804_snd_controls[] = {
98 SOC_ENUM_EXT("Input Source", txsrc, txsrc_get, txsrc_put), 98 SOC_ENUM_EXT("Input Source", txsrc, txsrc_get, txsrc_put),
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index e98bc7038a08..43c2201cb901 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -304,53 +304,53 @@ static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1);
304 304
305static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" }; 305static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" };
306 306
307static const struct soc_enum mic_bias_level = 307static SOC_ENUM_SINGLE_DECL(mic_bias_level,
308SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt); 308 WM8900_REG_INCTL, 8, mic_bias_level_txt);
309 309
310static const char *dac_mute_rate_txt[] = { "Fast", "Slow" }; 310static const char *dac_mute_rate_txt[] = { "Fast", "Slow" };
311 311
312static const struct soc_enum dac_mute_rate = 312static SOC_ENUM_SINGLE_DECL(dac_mute_rate,
313SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt); 313 WM8900_REG_DACCTRL, 7, dac_mute_rate_txt);
314 314
315static const char *dac_deemphasis_txt[] = { 315static const char *dac_deemphasis_txt[] = {
316 "Disabled", "32kHz", "44.1kHz", "48kHz" 316 "Disabled", "32kHz", "44.1kHz", "48kHz"
317}; 317};
318 318
319static const struct soc_enum dac_deemphasis = 319static SOC_ENUM_SINGLE_DECL(dac_deemphasis,
320SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt); 320 WM8900_REG_DACCTRL, 4, dac_deemphasis_txt);
321 321
322static const char *adc_hpf_cut_txt[] = { 322static const char *adc_hpf_cut_txt[] = {
323 "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3" 323 "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"
324}; 324};
325 325
326static const struct soc_enum adc_hpf_cut = 326static SOC_ENUM_SINGLE_DECL(adc_hpf_cut,
327SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt); 327 WM8900_REG_ADCCTRL, 5, adc_hpf_cut_txt);
328 328
329static const char *lr_txt[] = { 329static const char *lr_txt[] = {
330 "Left", "Right" 330 "Left", "Right"
331}; 331};
332 332
333static const struct soc_enum aifl_src = 333static SOC_ENUM_SINGLE_DECL(aifl_src,
334SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt); 334 WM8900_REG_AUDIO1, 15, lr_txt);
335 335
336static const struct soc_enum aifr_src = 336static SOC_ENUM_SINGLE_DECL(aifr_src,
337SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt); 337 WM8900_REG_AUDIO1, 14, lr_txt);
338 338
339static const struct soc_enum dacl_src = 339static SOC_ENUM_SINGLE_DECL(dacl_src,
340SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt); 340 WM8900_REG_AUDIO2, 15, lr_txt);
341 341
342static const struct soc_enum dacr_src = 342static SOC_ENUM_SINGLE_DECL(dacr_src,
343SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt); 343 WM8900_REG_AUDIO2, 14, lr_txt);
344 344
345static const char *sidetone_txt[] = { 345static const char *sidetone_txt[] = {
346 "Disabled", "Left ADC", "Right ADC" 346 "Disabled", "Left ADC", "Right ADC"
347}; 347};
348 348
349static const struct soc_enum dacl_sidetone = 349static SOC_ENUM_SINGLE_DECL(dacl_sidetone,
350SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt); 350 WM8900_REG_SIDETONE, 2, sidetone_txt);
351 351
352static const struct soc_enum dacr_sidetone = 352static SOC_ENUM_SINGLE_DECL(dacr_sidetone,
353SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt); 353 WM8900_REG_SIDETONE, 0, sidetone_txt);
354 354
355static const struct snd_kcontrol_new wm8900_snd_controls[] = { 355static const struct snd_kcontrol_new wm8900_snd_controls[] = {
356SOC_ENUM("Mic Bias Level", mic_bias_level), 356SOC_ENUM("Mic Bias Level", mic_bias_level),
@@ -496,8 +496,8 @@ SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0),
496 496
497static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" }; 497static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" };
498 498
499static const struct soc_enum wm8900_lineout2_lp_mux = 499static SOC_ENUM_SINGLE_DECL(wm8900_lineout2_lp_mux,
500SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm8900_lp_mux); 500 WM8900_REG_LOUTMIXCTL1, 1, wm8900_lp_mux);
501 501
502static const struct snd_kcontrol_new wm8900_lineout2_lp = 502static const struct snd_kcontrol_new wm8900_lineout2_lp =
503SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux); 503SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux);
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 53bbfac6a83a..b2664ec901b9 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -1981,7 +1981,7 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
1981 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", 1981 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
1982 wm8904->num_retune_mobile_texts); 1982 wm8904->num_retune_mobile_texts);
1983 1983
1984 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; 1984 wm8904->retune_mobile_enum.items = wm8904->num_retune_mobile_texts;
1985 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; 1985 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
1986 1986
1987 ret = snd_soc_add_codec_controls(codec, &control, 1); 1987 ret = snd_soc_add_codec_controls(codec, &control, 1);
@@ -2022,7 +2022,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2022 for (i = 0; i < pdata->num_drc_cfgs; i++) 2022 for (i = 0; i < pdata->num_drc_cfgs; i++)
2023 wm8904->drc_texts[i] = pdata->drc_cfgs[i].name; 2023 wm8904->drc_texts[i] = pdata->drc_cfgs[i].name;
2024 2024
2025 wm8904->drc_enum.max = pdata->num_drc_cfgs; 2025 wm8904->drc_enum.items = pdata->num_drc_cfgs;
2026 wm8904->drc_enum.texts = wm8904->drc_texts; 2026 wm8904->drc_enum.texts = wm8904->drc_texts;
2027 2027
2028 ret = snd_soc_add_codec_controls(codec, &control, 1); 2028 ret = snd_soc_add_codec_controls(codec, &control, 1);
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
index b7488f190d2b..7ac2e511403c 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -153,7 +153,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
153 153
154 data32 &= 0xffffff; 154 data32 &= 0xffffff;
155 155
156 wm8994_bulk_write(codec->control_data, 156 wm8994_bulk_write(wm8994->wm8994,
157 data32 & 0xffffff, 157 data32 & 0xffffff,
158 block_len / 2, 158 block_len / 2,
159 (void *)(data + 8)); 159 (void *)(data + 8));
@@ -944,7 +944,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
944 for (i = 0; i < pdata->num_mbc_cfgs; i++) 944 for (i = 0; i < pdata->num_mbc_cfgs; i++)
945 wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name; 945 wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
946 946
947 wm8994->mbc_enum.max = pdata->num_mbc_cfgs; 947 wm8994->mbc_enum.items = pdata->num_mbc_cfgs;
948 wm8994->mbc_enum.texts = wm8994->mbc_texts; 948 wm8994->mbc_enum.texts = wm8994->mbc_texts;
949 949
950 ret = snd_soc_add_codec_controls(wm8994->hubs.codec, 950 ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
@@ -973,7 +973,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
973 for (i = 0; i < pdata->num_vss_cfgs; i++) 973 for (i = 0; i < pdata->num_vss_cfgs; i++)
974 wm8994->vss_texts[i] = pdata->vss_cfgs[i].name; 974 wm8994->vss_texts[i] = pdata->vss_cfgs[i].name;
975 975
976 wm8994->vss_enum.max = pdata->num_vss_cfgs; 976 wm8994->vss_enum.items = pdata->num_vss_cfgs;
977 wm8994->vss_enum.texts = wm8994->vss_texts; 977 wm8994->vss_enum.texts = wm8994->vss_texts;
978 978
979 ret = snd_soc_add_codec_controls(wm8994->hubs.codec, 979 ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
@@ -1003,7 +1003,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
1003 for (i = 0; i < pdata->num_vss_hpf_cfgs; i++) 1003 for (i = 0; i < pdata->num_vss_hpf_cfgs; i++)
1004 wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name; 1004 wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name;
1005 1005
1006 wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; 1006 wm8994->vss_hpf_enum.items = pdata->num_vss_hpf_cfgs;
1007 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; 1007 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
1008 1008
1009 ret = snd_soc_add_codec_controls(wm8994->hubs.codec, 1009 ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
@@ -1034,7 +1034,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
1034 for (i = 0; i < pdata->num_enh_eq_cfgs; i++) 1034 for (i = 0; i < pdata->num_enh_eq_cfgs; i++)
1035 wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name; 1035 wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name;
1036 1036
1037 wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; 1037 wm8994->enh_eq_enum.items = pdata->num_enh_eq_cfgs;
1038 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; 1038 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
1039 1039
1040 ret = snd_soc_add_codec_controls(wm8994->hubs.codec, 1040 ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 97db3b45b411..9e6233633c44 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3089,6 +3089,7 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3089int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) 3089int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
3090{ 3090{
3091 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3091 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3092 struct snd_soc_dapm_context *dapm = &codec->dapm;
3092 int irq_mask, enable; 3093 int irq_mask, enable;
3093 3094
3094 wm8962->jack = jack; 3095 wm8962->jack = jack;
@@ -3109,14 +3110,18 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
3109 snd_soc_jack_report(wm8962->jack, 0, 3110 snd_soc_jack_report(wm8962->jack, 0,
3110 SND_JACK_MICROPHONE | SND_JACK_BTN_0); 3111 SND_JACK_MICROPHONE | SND_JACK_BTN_0);
3111 3112
3113 snd_soc_dapm_mutex_lock(dapm);
3114
3112 if (jack) { 3115 if (jack) {
3113 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); 3116 snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK");
3114 snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS"); 3117 snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS");
3115 } else { 3118 } else {
3116 snd_soc_dapm_disable_pin(&codec->dapm, "SYSCLK"); 3119 snd_soc_dapm_disable_pin_unlocked(dapm, "SYSCLK");
3117 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS"); 3120 snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS");
3118 } 3121 }
3119 3122
3123 snd_soc_dapm_mutex_unlock(dapm);
3124
3120 return 0; 3125 return 0;
3121} 3126}
3122EXPORT_SYMBOL_GPL(wm8962_mic_detect); 3127EXPORT_SYMBOL_GPL(wm8962_mic_detect);
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index d8fc531c0e59..a9e2f465c331 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -117,21 +117,21 @@ static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"};
117static const char *wm8978_alc3[] = {"ALC", "Limiter"}; 117static const char *wm8978_alc3[] = {"ALC", "Limiter"};
118static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"}; 118static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"};
119 119
120static const SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1, 120static SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1,
121 wm8978_companding); 121 wm8978_companding);
122static const SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3, 122static SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3,
123 wm8978_companding); 123 wm8978_companding);
124static const SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode); 124static SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode);
125static const SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1); 125static SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1);
126static const SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw); 126static SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw);
127static const SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2); 127static SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2);
128static const SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw); 128static SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw);
129static const SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3); 129static SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3);
130static const SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw); 130static SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw);
131static const SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4); 131static SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4);
132static const SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5); 132static SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5);
133static const SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3); 133static SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3);
134static const SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1); 134static SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1);
135 135
136static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); 136static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
137static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 137static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index aa41ba0dfff4..770e5a705851 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -205,49 +205,44 @@ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
205static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); 205static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0);
206 206
207static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; 207static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" };
208static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8983_ALC_CONTROL_1, 7, 208static SOC_ENUM_SINGLE_DECL(alc_sel, WM8983_ALC_CONTROL_1, 7, alc_sel_text);
209 alc_sel_text);
210 209
211static const char *alc_mode_text[] = { "ALC", "Limiter" }; 210static const char *alc_mode_text[] = { "ALC", "Limiter" };
212static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8983_ALC_CONTROL_3, 8, 211static SOC_ENUM_SINGLE_DECL(alc_mode, WM8983_ALC_CONTROL_3, 8, alc_mode_text);
213 alc_mode_text);
214 212
215static const char *filter_mode_text[] = { "Audio", "Application" }; 213static const char *filter_mode_text[] = { "Audio", "Application" };
216static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8983_ADC_CONTROL, 7, 214static SOC_ENUM_SINGLE_DECL(filter_mode, WM8983_ADC_CONTROL, 7,
217 filter_mode_text); 215 filter_mode_text);
218 216
219static const char *eq_bw_text[] = { "Narrow", "Wide" }; 217static const char *eq_bw_text[] = { "Narrow", "Wide" };
220static const char *eqmode_text[] = { "Capture", "Playback" }; 218static const char *eqmode_text[] = { "Capture", "Playback" };
221static const SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text); 219static SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text);
222 220
223static const char *eq1_cutoff_text[] = { 221static const char *eq1_cutoff_text[] = {
224 "80Hz", "105Hz", "135Hz", "175Hz" 222 "80Hz", "105Hz", "135Hz", "175Hz"
225}; 223};
226static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8983_EQ1_LOW_SHELF, 5, 224static SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8983_EQ1_LOW_SHELF, 5,
227 eq1_cutoff_text); 225 eq1_cutoff_text);
228static const char *eq2_cutoff_text[] = { 226static const char *eq2_cutoff_text[] = {
229 "230Hz", "300Hz", "385Hz", "500Hz" 227 "230Hz", "300Hz", "385Hz", "500Hz"
230}; 228};
231static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8983_EQ2_PEAK_1, 8, eq_bw_text); 229static SOC_ENUM_SINGLE_DECL(eq2_bw, WM8983_EQ2_PEAK_1, 8, eq_bw_text);
232static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8983_EQ2_PEAK_1, 5, 230static SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8983_EQ2_PEAK_1, 5, eq2_cutoff_text);
233 eq2_cutoff_text);
234static const char *eq3_cutoff_text[] = { 231static const char *eq3_cutoff_text[] = {
235 "650Hz", "850Hz", "1.1kHz", "1.4kHz" 232 "650Hz", "850Hz", "1.1kHz", "1.4kHz"
236}; 233};
237static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8983_EQ3_PEAK_2, 8, eq_bw_text); 234static SOC_ENUM_SINGLE_DECL(eq3_bw, WM8983_EQ3_PEAK_2, 8, eq_bw_text);
238static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8983_EQ3_PEAK_2, 5, 235static SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8983_EQ3_PEAK_2, 5, eq3_cutoff_text);
239 eq3_cutoff_text);
240static const char *eq4_cutoff_text[] = { 236static const char *eq4_cutoff_text[] = {
241 "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" 237 "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"
242}; 238};
243static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8983_EQ4_PEAK_3, 8, eq_bw_text); 239static SOC_ENUM_SINGLE_DECL(eq4_bw, WM8983_EQ4_PEAK_3, 8, eq_bw_text);
244static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8983_EQ4_PEAK_3, 5, 240static SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8983_EQ4_PEAK_3, 5, eq4_cutoff_text);
245 eq4_cutoff_text);
246static const char *eq5_cutoff_text[] = { 241static const char *eq5_cutoff_text[] = {
247 "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" 242 "5.3kHz", "6.9kHz", "9kHz", "11.7kHz"
248}; 243};
249static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5, 244static SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5,
250 eq5_cutoff_text); 245 eq5_cutoff_text);
251 246
252static const char *depth_3d_text[] = { 247static const char *depth_3d_text[] = {
253 "Off", 248 "Off",
@@ -267,8 +262,8 @@ static const char *depth_3d_text[] = {
267 "93.3%", 262 "93.3%",
268 "100%" 263 "100%"
269}; 264};
270static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8983_3D_CONTROL, 0, 265static SOC_ENUM_SINGLE_DECL(depth_3d, WM8983_3D_CONTROL, 0,
271 depth_3d_text); 266 depth_3d_text);
272 267
273static const struct snd_kcontrol_new wm8983_snd_controls[] = { 268static const struct snd_kcontrol_new wm8983_snd_controls[] = {
274 SOC_SINGLE("Digital Loopback Switch", WM8983_COMPANDING_CONTROL, 269 SOC_SINGLE("Digital Loopback Switch", WM8983_COMPANDING_CONTROL,
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index 271b517911a4..d786f2b39764 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -226,52 +226,48 @@ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
226static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); 226static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0);
227 227
228static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; 228static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" };
229static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8985_ALC_CONTROL_1, 7, 229static SOC_ENUM_SINGLE_DECL(alc_sel, WM8985_ALC_CONTROL_1, 7, alc_sel_text);
230 alc_sel_text);
231 230
232static const char *alc_mode_text[] = { "ALC", "Limiter" }; 231static const char *alc_mode_text[] = { "ALC", "Limiter" };
233static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8985_ALC_CONTROL_3, 8, 232static SOC_ENUM_SINGLE_DECL(alc_mode, WM8985_ALC_CONTROL_3, 8, alc_mode_text);
234 alc_mode_text);
235 233
236static const char *filter_mode_text[] = { "Audio", "Application" }; 234static const char *filter_mode_text[] = { "Audio", "Application" };
237static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8985_ADC_CONTROL, 7, 235static SOC_ENUM_SINGLE_DECL(filter_mode, WM8985_ADC_CONTROL, 7,
238 filter_mode_text); 236 filter_mode_text);
239 237
240static const char *eq_bw_text[] = { "Narrow", "Wide" }; 238static const char *eq_bw_text[] = { "Narrow", "Wide" };
241static const char *eqmode_text[] = { "Capture", "Playback" }; 239static const char *eqmode_text[] = { "Capture", "Playback" };
242static const SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text); 240static SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text);
243 241
244static const char *eq1_cutoff_text[] = { 242static const char *eq1_cutoff_text[] = {
245 "80Hz", "105Hz", "135Hz", "175Hz" 243 "80Hz", "105Hz", "135Hz", "175Hz"
246}; 244};
247static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8985_EQ1_LOW_SHELF, 5, 245static SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8985_EQ1_LOW_SHELF, 5,
248 eq1_cutoff_text); 246 eq1_cutoff_text);
249static const char *eq2_cutoff_text[] = { 247static const char *eq2_cutoff_text[] = {
250 "230Hz", "300Hz", "385Hz", "500Hz" 248 "230Hz", "300Hz", "385Hz", "500Hz"
251}; 249};
252static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8985_EQ2_PEAK_1, 8, eq_bw_text); 250static SOC_ENUM_SINGLE_DECL(eq2_bw, WM8985_EQ2_PEAK_1, 8, eq_bw_text);
253static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8985_EQ2_PEAK_1, 5, 251static SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8985_EQ2_PEAK_1, 5, eq2_cutoff_text);
254 eq2_cutoff_text);
255static const char *eq3_cutoff_text[] = { 252static const char *eq3_cutoff_text[] = {
256 "650Hz", "850Hz", "1.1kHz", "1.4kHz" 253 "650Hz", "850Hz", "1.1kHz", "1.4kHz"
257}; 254};
258static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8985_EQ3_PEAK_2, 8, eq_bw_text); 255static SOC_ENUM_SINGLE_DECL(eq3_bw, WM8985_EQ3_PEAK_2, 8, eq_bw_text);
259static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8985_EQ3_PEAK_2, 5, 256static SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8985_EQ3_PEAK_2, 5,
260 eq3_cutoff_text); 257 eq3_cutoff_text);
261static const char *eq4_cutoff_text[] = { 258static const char *eq4_cutoff_text[] = {
262 "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" 259 "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"
263}; 260};
264static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8985_EQ4_PEAK_3, 8, eq_bw_text); 261static SOC_ENUM_SINGLE_DECL(eq4_bw, WM8985_EQ4_PEAK_3, 8, eq_bw_text);
265static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8985_EQ4_PEAK_3, 5, 262static SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8985_EQ4_PEAK_3, 5, eq4_cutoff_text);
266 eq4_cutoff_text);
267static const char *eq5_cutoff_text[] = { 263static const char *eq5_cutoff_text[] = {
268 "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" 264 "5.3kHz", "6.9kHz", "9kHz", "11.7kHz"
269}; 265};
270static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8985_EQ5_HIGH_SHELF, 5, 266static SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8985_EQ5_HIGH_SHELF, 5,
271 eq5_cutoff_text); 267 eq5_cutoff_text);
272 268
273static const char *speaker_mode_text[] = { "Class A/B", "Class D" }; 269static const char *speaker_mode_text[] = { "Class A/B", "Class D" };
274static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text); 270static SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text);
275 271
276static const char *depth_3d_text[] = { 272static const char *depth_3d_text[] = {
277 "Off", 273 "Off",
@@ -291,8 +287,7 @@ static const char *depth_3d_text[] = {
291 "93.3%", 287 "93.3%",
292 "100%" 288 "100%"
293}; 289};
294static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0, 290static SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0, depth_3d_text);
295 depth_3d_text);
296 291
297static const struct snd_kcontrol_new wm8985_snd_controls[] = { 292static const struct snd_kcontrol_new wm8985_snd_controls[] = {
298 SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL, 293 SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL,
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 433d59a0f3ef..2ee23a39622c 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1562,7 +1562,6 @@ static int wm8993_remove(struct snd_soc_codec *codec)
1562 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 1562 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1563 1563
1564 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); 1564 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1565 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1566 return 0; 1565 return 0;
1567} 1566}
1568 1567
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index b9be9cbc4603..79854cb7feb6 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -265,21 +265,21 @@ static const char *sidetone_hpf_text[] = {
265 "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz" 265 "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz"
266}; 266};
267 267
268static const struct soc_enum sidetone_hpf = 268static SOC_ENUM_SINGLE_DECL(sidetone_hpf,
269 SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text); 269 WM8994_SIDETONE, 7, sidetone_hpf_text);
270 270
271static const char *adc_hpf_text[] = { 271static const char *adc_hpf_text[] = {
272 "HiFi", "Voice 1", "Voice 2", "Voice 3" 272 "HiFi", "Voice 1", "Voice 2", "Voice 3"
273}; 273};
274 274
275static const struct soc_enum aif1adc1_hpf = 275static SOC_ENUM_SINGLE_DECL(aif1adc1_hpf,
276 SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text); 276 WM8994_AIF1_ADC1_FILTERS, 13, adc_hpf_text);
277 277
278static const struct soc_enum aif1adc2_hpf = 278static SOC_ENUM_SINGLE_DECL(aif1adc2_hpf,
279 SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text); 279 WM8994_AIF1_ADC2_FILTERS, 13, adc_hpf_text);
280 280
281static const struct soc_enum aif2adc_hpf = 281static SOC_ENUM_SINGLE_DECL(aif2adc_hpf,
282 SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text); 282 WM8994_AIF2_ADC_FILTERS, 13, adc_hpf_text);
283 283
284static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); 284static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
285static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); 285static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
@@ -501,39 +501,39 @@ static const char *aif_chan_src_text[] = {
501 "Left", "Right" 501 "Left", "Right"
502}; 502};
503 503
504static const struct soc_enum aif1adcl_src = 504static SOC_ENUM_SINGLE_DECL(aif1adcl_src,
505 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text); 505 WM8994_AIF1_CONTROL_1, 15, aif_chan_src_text);
506 506
507static const struct soc_enum aif1adcr_src = 507static SOC_ENUM_SINGLE_DECL(aif1adcr_src,
508 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text); 508 WM8994_AIF1_CONTROL_1, 14, aif_chan_src_text);
509 509
510static const struct soc_enum aif2adcl_src = 510static SOC_ENUM_SINGLE_DECL(aif2adcl_src,
511 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text); 511 WM8994_AIF2_CONTROL_1, 15, aif_chan_src_text);
512 512
513static const struct soc_enum aif2adcr_src = 513static SOC_ENUM_SINGLE_DECL(aif2adcr_src,
514 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text); 514 WM8994_AIF2_CONTROL_1, 14, aif_chan_src_text);
515 515
516static const struct soc_enum aif1dacl_src = 516static SOC_ENUM_SINGLE_DECL(aif1dacl_src,
517 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text); 517 WM8994_AIF1_CONTROL_2, 15, aif_chan_src_text);
518 518
519static const struct soc_enum aif1dacr_src = 519static SOC_ENUM_SINGLE_DECL(aif1dacr_src,
520 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text); 520 WM8994_AIF1_CONTROL_2, 14, aif_chan_src_text);
521 521
522static const struct soc_enum aif2dacl_src = 522static SOC_ENUM_SINGLE_DECL(aif2dacl_src,
523 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text); 523 WM8994_AIF2_CONTROL_2, 15, aif_chan_src_text);
524 524
525static const struct soc_enum aif2dacr_src = 525static SOC_ENUM_SINGLE_DECL(aif2dacr_src,
526 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text); 526 WM8994_AIF2_CONTROL_2, 14, aif_chan_src_text);
527 527
528static const char *osr_text[] = { 528static const char *osr_text[] = {
529 "Low Power", "High Performance", 529 "Low Power", "High Performance",
530}; 530};
531 531
532static const struct soc_enum dac_osr = 532static SOC_ENUM_SINGLE_DECL(dac_osr,
533 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text); 533 WM8994_OVERSAMPLING, 0, osr_text);
534 534
535static const struct soc_enum adc_osr = 535static SOC_ENUM_SINGLE_DECL(adc_osr,
536 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text); 536 WM8994_OVERSAMPLING, 1, osr_text);
537 537
538static const struct snd_kcontrol_new wm8994_snd_controls[] = { 538static const struct snd_kcontrol_new wm8994_snd_controls[] = {
539SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, 539SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
@@ -690,17 +690,20 @@ static const char *wm8958_ng_text[] = {
690 "30ms", "125ms", "250ms", "500ms", 690 "30ms", "125ms", "250ms", "500ms",
691}; 691};
692 692
693static const struct soc_enum wm8958_aif1dac1_ng_hold = 693static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac1_ng_hold,
694 SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE, 694 WM8958_AIF1_DAC1_NOISE_GATE,
695 WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text); 695 WM8958_AIF1DAC1_NG_THR_SHIFT,
696 wm8958_ng_text);
696 697
697static const struct soc_enum wm8958_aif1dac2_ng_hold = 698static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac2_ng_hold,
698 SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE, 699 WM8958_AIF1_DAC2_NOISE_GATE,
699 WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text); 700 WM8958_AIF1DAC2_NG_THR_SHIFT,
701 wm8958_ng_text);
700 702
701static const struct soc_enum wm8958_aif2dac_ng_hold = 703static SOC_ENUM_SINGLE_DECL(wm8958_aif2dac_ng_hold,
702 SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE, 704 WM8958_AIF2_DAC_NOISE_GATE,
703 WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text); 705 WM8958_AIF2DAC_NG_THR_SHIFT,
706 wm8958_ng_text);
704 707
705static const struct snd_kcontrol_new wm8958_snd_controls[] = { 708static const struct snd_kcontrol_new wm8958_snd_controls[] = {
706SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), 709SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
@@ -1341,8 +1344,7 @@ static const char *adc_mux_text[] = {
1341 "DMIC", 1344 "DMIC",
1342}; 1345};
1343 1346
1344static const struct soc_enum adc_enum = 1347static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text);
1345 SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
1346 1348
1347static const struct snd_kcontrol_new adcl_mux = 1349static const struct snd_kcontrol_new adcl_mux =
1348 SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); 1350 SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
@@ -1478,14 +1480,14 @@ static const char *sidetone_text[] = {
1478 "ADC/DMIC1", "DMIC2", 1480 "ADC/DMIC1", "DMIC2",
1479}; 1481};
1480 1482
1481static const struct soc_enum sidetone1_enum = 1483static SOC_ENUM_SINGLE_DECL(sidetone1_enum,
1482 SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text); 1484 WM8994_SIDETONE, 0, sidetone_text);
1483 1485
1484static const struct snd_kcontrol_new sidetone1_mux = 1486static const struct snd_kcontrol_new sidetone1_mux =
1485 SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); 1487 SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
1486 1488
1487static const struct soc_enum sidetone2_enum = 1489static SOC_ENUM_SINGLE_DECL(sidetone2_enum,
1488 SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text); 1490 WM8994_SIDETONE, 1, sidetone_text);
1489 1491
1490static const struct snd_kcontrol_new sidetone2_mux = 1492static const struct snd_kcontrol_new sidetone2_mux =
1491 SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); 1493 SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
@@ -1498,22 +1500,24 @@ static const char *loopback_text[] = {
1498 "None", "ADCDAT", 1500 "None", "ADCDAT",
1499}; 1501};
1500 1502
1501static const struct soc_enum aif1_loopback_enum = 1503static SOC_ENUM_SINGLE_DECL(aif1_loopback_enum,
1502 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, WM8994_AIF1_LOOPBACK_SHIFT, 2, 1504 WM8994_AIF1_CONTROL_2,
1503 loopback_text); 1505 WM8994_AIF1_LOOPBACK_SHIFT,
1506 loopback_text);
1504 1507
1505static const struct snd_kcontrol_new aif1_loopback = 1508static const struct snd_kcontrol_new aif1_loopback =
1506 SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum); 1509 SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum);
1507 1510
1508static const struct soc_enum aif2_loopback_enum = 1511static SOC_ENUM_SINGLE_DECL(aif2_loopback_enum,
1509 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, WM8994_AIF2_LOOPBACK_SHIFT, 2, 1512 WM8994_AIF2_CONTROL_2,
1510 loopback_text); 1513 WM8994_AIF2_LOOPBACK_SHIFT,
1514 loopback_text);
1511 1515
1512static const struct snd_kcontrol_new aif2_loopback = 1516static const struct snd_kcontrol_new aif2_loopback =
1513 SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum); 1517 SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum);
1514 1518
1515static const struct soc_enum aif1dac_enum = 1519static SOC_ENUM_SINGLE_DECL(aif1dac_enum,
1516 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text); 1520 WM8994_POWER_MANAGEMENT_6, 0, aif1dac_text);
1517 1521
1518static const struct snd_kcontrol_new aif1dac_mux = 1522static const struct snd_kcontrol_new aif1dac_mux =
1519 SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum); 1523 SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum);
@@ -1522,8 +1526,8 @@ static const char *aif2dac_text[] = {
1522 "AIF2DACDAT", "AIF3DACDAT", 1526 "AIF2DACDAT", "AIF3DACDAT",
1523}; 1527};
1524 1528
1525static const struct soc_enum aif2dac_enum = 1529static SOC_ENUM_SINGLE_DECL(aif2dac_enum,
1526 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text); 1530 WM8994_POWER_MANAGEMENT_6, 1, aif2dac_text);
1527 1531
1528static const struct snd_kcontrol_new aif2dac_mux = 1532static const struct snd_kcontrol_new aif2dac_mux =
1529 SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum); 1533 SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum);
@@ -1532,8 +1536,8 @@ static const char *aif2adc_text[] = {
1532 "AIF2ADCDAT", "AIF3DACDAT", 1536 "AIF2ADCDAT", "AIF3DACDAT",
1533}; 1537};
1534 1538
1535static const struct soc_enum aif2adc_enum = 1539static SOC_ENUM_SINGLE_DECL(aif2adc_enum,
1536 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text); 1540 WM8994_POWER_MANAGEMENT_6, 2, aif2adc_text);
1537 1541
1538static const struct snd_kcontrol_new aif2adc_mux = 1542static const struct snd_kcontrol_new aif2adc_mux =
1539 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); 1543 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
@@ -1542,14 +1546,14 @@ static const char *aif3adc_text[] = {
1542 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM", 1546 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM",
1543}; 1547};
1544 1548
1545static const struct soc_enum wm8994_aif3adc_enum = 1549static SOC_ENUM_SINGLE_DECL(wm8994_aif3adc_enum,
1546 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text); 1550 WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text);
1547 1551
1548static const struct snd_kcontrol_new wm8994_aif3adc_mux = 1552static const struct snd_kcontrol_new wm8994_aif3adc_mux =
1549 SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum); 1553 SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum);
1550 1554
1551static const struct soc_enum wm8958_aif3adc_enum = 1555static SOC_ENUM_SINGLE_DECL(wm8958_aif3adc_enum,
1552 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text); 1556 WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text);
1553 1557
1554static const struct snd_kcontrol_new wm8958_aif3adc_mux = 1558static const struct snd_kcontrol_new wm8958_aif3adc_mux =
1555 SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); 1559 SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum);
@@ -1558,8 +1562,8 @@ static const char *mono_pcm_out_text[] = {
1558 "None", "AIF2ADCL", "AIF2ADCR", 1562 "None", "AIF2ADCL", "AIF2ADCR",
1559}; 1563};
1560 1564
1561static const struct soc_enum mono_pcm_out_enum = 1565static SOC_ENUM_SINGLE_DECL(mono_pcm_out_enum,
1562 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text); 1566 WM8994_POWER_MANAGEMENT_6, 9, mono_pcm_out_text);
1563 1567
1564static const struct snd_kcontrol_new mono_pcm_out_mux = 1568static const struct snd_kcontrol_new mono_pcm_out_mux =
1565 SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum); 1569 SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum);
@@ -1569,14 +1573,14 @@ static const char *aif2dac_src_text[] = {
1569}; 1573};
1570 1574
1571/* Note that these two control shouldn't be simultaneously switched to AIF3 */ 1575/* Note that these two control shouldn't be simultaneously switched to AIF3 */
1572static const struct soc_enum aif2dacl_src_enum = 1576static SOC_ENUM_SINGLE_DECL(aif2dacl_src_enum,
1573 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text); 1577 WM8994_POWER_MANAGEMENT_6, 7, aif2dac_src_text);
1574 1578
1575static const struct snd_kcontrol_new aif2dacl_src_mux = 1579static const struct snd_kcontrol_new aif2dacl_src_mux =
1576 SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum); 1580 SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum);
1577 1581
1578static const struct soc_enum aif2dacr_src_enum = 1582static SOC_ENUM_SINGLE_DECL(aif2dacr_src_enum,
1579 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text); 1583 WM8994_POWER_MANAGEMENT_6, 8, aif2dac_src_text);
1580 1584
1581static const struct snd_kcontrol_new aif2dacr_src_mux = 1585static const struct snd_kcontrol_new aif2dacr_src_mux =
1582 SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); 1586 SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
@@ -2549,43 +2553,52 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2549int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode) 2553int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode)
2550{ 2554{
2551 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2555 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2556 struct snd_soc_dapm_context *dapm = &codec->dapm;
2552 2557
2553 switch (mode) { 2558 switch (mode) {
2554 case WM8994_VMID_NORMAL: 2559 case WM8994_VMID_NORMAL:
2560 snd_soc_dapm_mutex_lock(dapm);
2561
2555 if (wm8994->hubs.lineout1_se) { 2562 if (wm8994->hubs.lineout1_se) {
2556 snd_soc_dapm_disable_pin(&codec->dapm, 2563 snd_soc_dapm_disable_pin_unlocked(dapm,
2557 "LINEOUT1N Driver"); 2564 "LINEOUT1N Driver");
2558 snd_soc_dapm_disable_pin(&codec->dapm, 2565 snd_soc_dapm_disable_pin_unlocked(dapm,
2559 "LINEOUT1P Driver"); 2566 "LINEOUT1P Driver");
2560 } 2567 }
2561 if (wm8994->hubs.lineout2_se) { 2568 if (wm8994->hubs.lineout2_se) {
2562 snd_soc_dapm_disable_pin(&codec->dapm, 2569 snd_soc_dapm_disable_pin_unlocked(dapm,
2563 "LINEOUT2N Driver"); 2570 "LINEOUT2N Driver");
2564 snd_soc_dapm_disable_pin(&codec->dapm, 2571 snd_soc_dapm_disable_pin_unlocked(dapm,
2565 "LINEOUT2P Driver"); 2572 "LINEOUT2P Driver");
2566 } 2573 }
2567 2574
2568 /* Do the sync with the old mode to allow it to clean up */ 2575 /* Do the sync with the old mode to allow it to clean up */
2569 snd_soc_dapm_sync(&codec->dapm); 2576 snd_soc_dapm_sync_unlocked(dapm);
2570 wm8994->vmid_mode = mode; 2577 wm8994->vmid_mode = mode;
2578
2579 snd_soc_dapm_mutex_unlock(dapm);
2571 break; 2580 break;
2572 2581
2573 case WM8994_VMID_FORCE: 2582 case WM8994_VMID_FORCE:
2583 snd_soc_dapm_mutex_lock(dapm);
2584
2574 if (wm8994->hubs.lineout1_se) { 2585 if (wm8994->hubs.lineout1_se) {
2575 snd_soc_dapm_force_enable_pin(&codec->dapm, 2586 snd_soc_dapm_force_enable_pin_unlocked(dapm,
2576 "LINEOUT1N Driver"); 2587 "LINEOUT1N Driver");
2577 snd_soc_dapm_force_enable_pin(&codec->dapm, 2588 snd_soc_dapm_force_enable_pin_unlocked(dapm,
2578 "LINEOUT1P Driver"); 2589 "LINEOUT1P Driver");
2579 } 2590 }
2580 if (wm8994->hubs.lineout2_se) { 2591 if (wm8994->hubs.lineout2_se) {
2581 snd_soc_dapm_force_enable_pin(&codec->dapm, 2592 snd_soc_dapm_force_enable_pin_unlocked(dapm,
2582 "LINEOUT2N Driver"); 2593 "LINEOUT2N Driver");
2583 snd_soc_dapm_force_enable_pin(&codec->dapm, 2594 snd_soc_dapm_force_enable_pin_unlocked(dapm,
2584 "LINEOUT2P Driver"); 2595 "LINEOUT2P Driver");
2585 } 2596 }
2586 2597
2587 wm8994->vmid_mode = mode; 2598 wm8994->vmid_mode = mode;
2588 snd_soc_dapm_sync(&codec->dapm); 2599 snd_soc_dapm_sync_unlocked(dapm);
2600
2601 snd_soc_dapm_mutex_unlock(dapm);
2589 break; 2602 break;
2590 2603
2591 default: 2604 default:
@@ -3237,7 +3250,7 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3237 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", 3250 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
3238 wm8994->num_retune_mobile_texts); 3251 wm8994->num_retune_mobile_texts);
3239 3252
3240 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; 3253 wm8994->retune_mobile_enum.items = wm8994->num_retune_mobile_texts;
3241 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; 3254 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
3242 3255
3243 ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, 3256 ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls,
@@ -3293,7 +3306,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3293 for (i = 0; i < pdata->num_drc_cfgs; i++) 3306 for (i = 0; i < pdata->num_drc_cfgs; i++)
3294 wm8994->drc_texts[i] = pdata->drc_cfgs[i].name; 3307 wm8994->drc_texts[i] = pdata->drc_cfgs[i].name;
3295 3308
3296 wm8994->drc_enum.max = pdata->num_drc_cfgs; 3309 wm8994->drc_enum.items = pdata->num_drc_cfgs;
3297 wm8994->drc_enum.texts = wm8994->drc_texts; 3310 wm8994->drc_enum.texts = wm8994->drc_texts;
3298 3311
3299 ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, 3312 ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls,
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 4300caff1783..ddb197dc1d53 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -423,24 +423,24 @@ static const char *in1l_text[] = {
423 "Differential", "Single-ended IN1LN", "Single-ended IN1LP" 423 "Differential", "Single-ended IN1LN", "Single-ended IN1LP"
424}; 424};
425 425
426static const SOC_ENUM_SINGLE_DECL(in1l_enum, WM8995_LEFT_LINE_INPUT_CONTROL, 426static SOC_ENUM_SINGLE_DECL(in1l_enum, WM8995_LEFT_LINE_INPUT_CONTROL,
427 2, in1l_text); 427 2, in1l_text);
428 428
429static const char *in1r_text[] = { 429static const char *in1r_text[] = {
430 "Differential", "Single-ended IN1RN", "Single-ended IN1RP" 430 "Differential", "Single-ended IN1RN", "Single-ended IN1RP"
431}; 431};
432 432
433static const SOC_ENUM_SINGLE_DECL(in1r_enum, WM8995_LEFT_LINE_INPUT_CONTROL, 433static SOC_ENUM_SINGLE_DECL(in1r_enum, WM8995_LEFT_LINE_INPUT_CONTROL,
434 0, in1r_text); 434 0, in1r_text);
435 435
436static const char *dmic_src_text[] = { 436static const char *dmic_src_text[] = {
437 "DMICDAT1", "DMICDAT2", "DMICDAT3" 437 "DMICDAT1", "DMICDAT2", "DMICDAT3"
438}; 438};
439 439
440static const SOC_ENUM_SINGLE_DECL(dmic_src1_enum, WM8995_POWER_MANAGEMENT_5, 440static SOC_ENUM_SINGLE_DECL(dmic_src1_enum, WM8995_POWER_MANAGEMENT_5,
441 8, dmic_src_text); 441 8, dmic_src_text);
442static const SOC_ENUM_SINGLE_DECL(dmic_src2_enum, WM8995_POWER_MANAGEMENT_5, 442static SOC_ENUM_SINGLE_DECL(dmic_src2_enum, WM8995_POWER_MANAGEMENT_5,
443 6, dmic_src_text); 443 6, dmic_src_text);
444 444
445static const struct snd_kcontrol_new wm8995_snd_controls[] = { 445static const struct snd_kcontrol_new wm8995_snd_controls[] = {
446 SOC_DOUBLE_R_TLV("DAC1 Volume", WM8995_DAC1_LEFT_VOLUME, 446 SOC_DOUBLE_R_TLV("DAC1 Volume", WM8995_DAC1_LEFT_VOLUME,
@@ -561,10 +561,8 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w,
561 struct snd_kcontrol *kcontrol, int event) 561 struct snd_kcontrol *kcontrol, int event)
562{ 562{
563 struct snd_soc_codec *codec; 563 struct snd_soc_codec *codec;
564 struct wm8995_priv *wm8995;
565 564
566 codec = w->codec; 565 codec = w->codec;
567 wm8995 = snd_soc_codec_get_drvdata(codec);
568 566
569 switch (event) { 567 switch (event) {
570 case SND_SOC_DAPM_PRE_PMU: 568 case SND_SOC_DAPM_PRE_PMU:
@@ -783,14 +781,12 @@ static const char *sidetone_text[] = {
783 "ADC/DMIC1", "DMIC2", 781 "ADC/DMIC1", "DMIC2",
784}; 782};
785 783
786static const struct soc_enum sidetone1_enum = 784static SOC_ENUM_SINGLE_DECL(sidetone1_enum, WM8995_SIDETONE, 0, sidetone_text);
787 SOC_ENUM_SINGLE(WM8995_SIDETONE, 0, 2, sidetone_text);
788 785
789static const struct snd_kcontrol_new sidetone1_mux = 786static const struct snd_kcontrol_new sidetone1_mux =
790 SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); 787 SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
791 788
792static const struct soc_enum sidetone2_enum = 789static SOC_ENUM_SINGLE_DECL(sidetone2_enum, WM8995_SIDETONE, 1, sidetone_text);
793 SOC_ENUM_SINGLE(WM8995_SIDETONE, 1, 2, sidetone_text);
794 790
795static const struct snd_kcontrol_new sidetone2_mux = 791static const struct snd_kcontrol_new sidetone2_mux =
796 SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); 792 SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
@@ -886,8 +882,7 @@ static const char *adc_mux_text[] = {
886 "DMIC", 882 "DMIC",
887}; 883};
888 884
889static const struct soc_enum adc_enum = 885static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text);
890 SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
891 886
892static const struct snd_kcontrol_new adcl_mux = 887static const struct snd_kcontrol_new adcl_mux =
893 SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); 888 SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
@@ -899,14 +894,14 @@ static const char *spk_src_text[] = {
899 "DAC1L", "DAC1R", "DAC2L", "DAC2R" 894 "DAC1L", "DAC1R", "DAC2L", "DAC2R"
900}; 895};
901 896
902static const SOC_ENUM_SINGLE_DECL(spk1l_src_enum, WM8995_LEFT_PDM_SPEAKER_1, 897static SOC_ENUM_SINGLE_DECL(spk1l_src_enum, WM8995_LEFT_PDM_SPEAKER_1,
903 0, spk_src_text); 898 0, spk_src_text);
904static const SOC_ENUM_SINGLE_DECL(spk1r_src_enum, WM8995_RIGHT_PDM_SPEAKER_1, 899static SOC_ENUM_SINGLE_DECL(spk1r_src_enum, WM8995_RIGHT_PDM_SPEAKER_1,
905 0, spk_src_text); 900 0, spk_src_text);
906static const SOC_ENUM_SINGLE_DECL(spk2l_src_enum, WM8995_LEFT_PDM_SPEAKER_2, 901static SOC_ENUM_SINGLE_DECL(spk2l_src_enum, WM8995_LEFT_PDM_SPEAKER_2,
907 0, spk_src_text); 902 0, spk_src_text);
908static const SOC_ENUM_SINGLE_DECL(spk2r_src_enum, WM8995_RIGHT_PDM_SPEAKER_2, 903static SOC_ENUM_SINGLE_DECL(spk2r_src_enum, WM8995_RIGHT_PDM_SPEAKER_2,
909 0, spk_src_text); 904 0, spk_src_text);
910 905
911static const struct snd_kcontrol_new spk1l_mux = 906static const struct snd_kcontrol_new spk1l_mux =
912 SOC_DAPM_ENUM("SPK1L SRC", spk1l_src_enum); 907 SOC_DAPM_ENUM("SPK1L SRC", spk1l_src_enum);
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 1a7655b0aa22..0330165079a4 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -2251,6 +2251,7 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2251 wm8996_polarity_fn polarity_cb) 2251 wm8996_polarity_fn polarity_cb)
2252{ 2252{
2253 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2253 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2254 struct snd_soc_dapm_context *dapm = &codec->dapm;
2254 2255
2255 wm8996->jack = jack; 2256 wm8996->jack = jack;
2256 wm8996->detecting = true; 2257 wm8996->detecting = true;
@@ -2267,8 +2268,12 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2267 WM8996_MICB2_DISCH, 0); 2268 WM8996_MICB2_DISCH, 0);
2268 2269
2269 /* LDO2 powers the microphones, SYSCLK clocks detection */ 2270 /* LDO2 powers the microphones, SYSCLK clocks detection */
2270 snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); 2271 snd_soc_dapm_mutex_lock(dapm);
2271 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); 2272
2273 snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO2");
2274 snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK");
2275
2276 snd_soc_dapm_mutex_unlock(dapm);
2272 2277
2273 /* We start off just enabling microphone detection - even a 2278 /* We start off just enabling microphone detection - even a
2274 * plain headphone will trigger detection. 2279 * plain headphone will trigger detection.
@@ -2595,7 +2600,7 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec)
2595 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", 2600 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
2596 wm8996->num_retune_mobile_texts); 2601 wm8996->num_retune_mobile_texts);
2597 2602
2598 wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts; 2603 wm8996->retune_mobile_enum.items = wm8996->num_retune_mobile_texts;
2599 wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts; 2604 wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts;
2600 2605
2601 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); 2606 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
index 555115ee2159..e10f44d7fdb7 100644
--- a/sound/soc/codecs/wm8997.c
+++ b/sound/soc/codecs/wm8997.c
@@ -86,7 +86,7 @@ static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w,
86{ 86{
87 struct snd_soc_codec *codec = w->codec; 87 struct snd_soc_codec *codec = w->codec;
88 struct arizona *arizona = dev_get_drvdata(codec->dev->parent); 88 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
89 struct regmap *regmap = codec->control_data; 89 struct regmap *regmap = arizona->regmap;
90 const struct reg_default *patch = NULL; 90 const struct reg_default *patch = NULL;
91 int i, patch_size; 91 int i, patch_size;
92 92
@@ -123,10 +123,12 @@ static const unsigned int wm8997_osr_val[] = {
123 123
124static const struct soc_enum wm8997_hpout_osr[] = { 124static const struct soc_enum wm8997_hpout_osr[] = {
125 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, 125 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
126 ARIZONA_OUT1_OSR_SHIFT, 0x7, 3, 126 ARIZONA_OUT1_OSR_SHIFT, 0x7,
127 ARRAY_SIZE(wm8997_osr_text),
127 wm8997_osr_text, wm8997_osr_val), 128 wm8997_osr_text, wm8997_osr_val),
128 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, 129 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
129 ARIZONA_OUT3_OSR_SHIFT, 0x7, 3, 130 ARIZONA_OUT3_OSR_SHIFT, 0x7,
131 ARRAY_SIZE(wm8997_osr_text),
130 wm8997_osr_text, wm8997_osr_val), 132 wm8997_osr_text, wm8997_osr_val),
131}; 133};
132 134
@@ -170,15 +172,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
170ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), 172ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
171ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), 173ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
172 174
173SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21, 175SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19),
174 ARIZONA_EQ1_ENA_MASK), 176SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0),
175SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21,
176 ARIZONA_EQ2_ENA_MASK),
177SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21,
178 ARIZONA_EQ3_ENA_MASK),
179SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21,
180 ARIZONA_EQ4_ENA_MASK),
181
182SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, 177SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
183 24, 0, eq_tlv), 178 24, 0, eq_tlv),
184SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, 179SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
@@ -190,6 +185,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
190SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, 185SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
191 24, 0, eq_tlv), 186 24, 0, eq_tlv),
192 187
188SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19),
189SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0),
193SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, 190SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
194 24, 0, eq_tlv), 191 24, 0, eq_tlv),
195SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, 192SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
@@ -201,6 +198,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
201SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, 198SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
202 24, 0, eq_tlv), 199 24, 0, eq_tlv),
203 200
201SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19),
202SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0),
204SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, 203SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
205 24, 0, eq_tlv), 204 24, 0, eq_tlv),
206SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, 205SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
@@ -212,6 +211,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
212SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, 211SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
213 24, 0, eq_tlv), 212 24, 0, eq_tlv),
214 213
214SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19),
215SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0),
215SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, 216SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
216 24, 0, eq_tlv), 217 24, 0, eq_tlv),
217SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, 218SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 444626fcab40..bb5f7b4e3ebb 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -684,24 +684,38 @@ static int wm_adsp_load(struct wm_adsp *dsp)
684 } 684 }
685 685
686 if (reg) { 686 if (reg) {
687 buf = wm_adsp_buf_alloc(region->data, 687 size_t to_write = PAGE_SIZE;
688 le32_to_cpu(region->len), 688 size_t remain = le32_to_cpu(region->len);
689 &buf_list); 689 const u8 *data = region->data;
690 if (!buf) { 690
691 adsp_err(dsp, "Out of memory\n"); 691 while (remain > 0) {
692 ret = -ENOMEM; 692 if (remain < PAGE_SIZE)
693 goto out_fw; 693 to_write = remain;
694 } 694
695 buf = wm_adsp_buf_alloc(data,
696 to_write,
697 &buf_list);
698 if (!buf) {
699 adsp_err(dsp, "Out of memory\n");
700 ret = -ENOMEM;
701 goto out_fw;
702 }
695 703
696 ret = regmap_raw_write_async(regmap, reg, buf->buf, 704 ret = regmap_raw_write_async(regmap, reg,
697 le32_to_cpu(region->len)); 705 buf->buf,
698 if (ret != 0) { 706 to_write);
699 adsp_err(dsp, 707 if (ret != 0) {
700 "%s.%d: Failed to write %d bytes at %d in %s: %d\n", 708 adsp_err(dsp,
701 file, regions, 709 "%s.%d: Failed to write %zd bytes at %d in %s: %d\n",
702 le32_to_cpu(region->len), offset, 710 file, regions,
703 region_name, ret); 711 to_write, offset,
704 goto out_fw; 712 region_name, ret);
713 goto out_fw;
714 }
715
716 data += to_write;
717 reg += to_write / 2;
718 remain -= to_write;
705 } 719 }
706 } 720 }
707 721
@@ -1679,6 +1693,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1679 list_del(&alg_region->list); 1693 list_del(&alg_region->list);
1680 kfree(alg_region); 1694 kfree(alg_region);
1681 } 1695 }
1696
1697 adsp_dbg(dsp, "Shutdown complete\n");
1682 break; 1698 break;
1683 1699
1684 default: 1700 default:
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 70ff3772079f..621e9a997d4c 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -17,6 +17,7 @@
17#include <linux/platform_data/edma.h> 17#include <linux/platform_data/edma.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/of_platform.h> 19#include <linux/of_platform.h>
20#include <linux/clk.h>
20#include <sound/core.h> 21#include <sound/core.h>
21#include <sound/pcm.h> 22#include <sound/pcm.h>
22#include <sound/soc.h> 23#include <sound/soc.h>
@@ -30,9 +31,34 @@
30#include "davinci-i2s.h" 31#include "davinci-i2s.h"
31 32
32struct snd_soc_card_drvdata_davinci { 33struct snd_soc_card_drvdata_davinci {
34 struct clk *mclk;
33 unsigned sysclk; 35 unsigned sysclk;
34}; 36};
35 37
38static int evm_startup(struct snd_pcm_substream *substream)
39{
40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
41 struct snd_soc_card *soc_card = rtd->codec->card;
42 struct snd_soc_card_drvdata_davinci *drvdata =
43 snd_soc_card_get_drvdata(soc_card);
44
45 if (drvdata->mclk)
46 return clk_prepare_enable(drvdata->mclk);
47
48 return 0;
49}
50
51static void evm_shutdown(struct snd_pcm_substream *substream)
52{
53 struct snd_soc_pcm_runtime *rtd = substream->private_data;
54 struct snd_soc_card *soc_card = rtd->codec->card;
55 struct snd_soc_card_drvdata_davinci *drvdata =
56 snd_soc_card_get_drvdata(soc_card);
57
58 if (drvdata->mclk)
59 clk_disable_unprepare(drvdata->mclk);
60}
61
36static int evm_hw_params(struct snd_pcm_substream *substream, 62static int evm_hw_params(struct snd_pcm_substream *substream,
37 struct snd_pcm_hw_params *params) 63 struct snd_pcm_hw_params *params)
38{ 64{
@@ -59,6 +85,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
59} 85}
60 86
61static struct snd_soc_ops evm_ops = { 87static struct snd_soc_ops evm_ops = {
88 .startup = evm_startup,
89 .shutdown = evm_shutdown,
62 .hw_params = evm_hw_params, 90 .hw_params = evm_hw_params,
63}; 91};
64 92
@@ -348,6 +376,7 @@ static int davinci_evm_probe(struct platform_device *pdev)
348 of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev); 376 of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev);
349 struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data; 377 struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data;
350 struct snd_soc_card_drvdata_davinci *drvdata = NULL; 378 struct snd_soc_card_drvdata_davinci *drvdata = NULL;
379 struct clk *mclk;
351 int ret = 0; 380 int ret = 0;
352 381
353 evm_soc_card.dai_link = dai; 382 evm_soc_card.dai_link = dai;
@@ -367,13 +396,38 @@ static int davinci_evm_probe(struct platform_device *pdev)
367 if (ret) 396 if (ret)
368 return ret; 397 return ret;
369 398
399 mclk = devm_clk_get(&pdev->dev, "mclk");
400 if (PTR_ERR(mclk) == -EPROBE_DEFER) {
401 return -EPROBE_DEFER;
402 } else if (IS_ERR(mclk)) {
403 dev_dbg(&pdev->dev, "mclk not found.\n");
404 mclk = NULL;
405 }
406
370 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 407 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
371 if (!drvdata) 408 if (!drvdata)
372 return -ENOMEM; 409 return -ENOMEM;
373 410
411 drvdata->mclk = mclk;
412
374 ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk); 413 ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk);
375 if (ret < 0) 414
376 return -EINVAL; 415 if (ret < 0) {
416 if (!drvdata->mclk) {
417 dev_err(&pdev->dev,
418 "No clock or clock rate defined.\n");
419 return -EINVAL;
420 }
421 drvdata->sysclk = clk_get_rate(drvdata->mclk);
422 } else if (drvdata->mclk) {
423 unsigned int requestd_rate = drvdata->sysclk;
424 clk_set_rate(drvdata->mclk, drvdata->sysclk);
425 drvdata->sysclk = clk_get_rate(drvdata->mclk);
426 if (drvdata->sysclk != requestd_rate)
427 dev_warn(&pdev->dev,
428 "Could not get requested rate %u using %u.\n",
429 requestd_rate, drvdata->sysclk);
430 }
377 431
378 snd_soc_card_set_drvdata(&evm_soc_card, drvdata); 432 snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
379 ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card); 433 ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card);
@@ -399,6 +453,7 @@ static struct platform_driver davinci_evm_driver = {
399 .driver = { 453 .driver = {
400 .name = "davinci_evm", 454 .name = "davinci_evm",
401 .owner = THIS_MODULE, 455 .owner = THIS_MODULE,
456 .pm = &snd_soc_pm_ops,
402 .of_match_table = of_match_ptr(davinci_evm_dt_ids), 457 .of_match_table = of_match_ptr(davinci_evm_dt_ids),
403 }, 458 },
404}; 459};
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index b7858bfa0295..b0ae0677f023 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -37,6 +37,16 @@
37#include "davinci-pcm.h" 37#include "davinci-pcm.h"
38#include "davinci-mcasp.h" 38#include "davinci-mcasp.h"
39 39
40struct davinci_mcasp_context {
41 u32 txfmtctl;
42 u32 rxfmtctl;
43 u32 txfmt;
44 u32 rxfmt;
45 u32 aclkxctl;
46 u32 aclkrctl;
47 u32 pdir;
48};
49
40struct davinci_mcasp { 50struct davinci_mcasp {
41 struct davinci_pcm_dma_params dma_params[2]; 51 struct davinci_pcm_dma_params dma_params[2];
42 struct snd_dmaengine_dai_dma_data dma_data[2]; 52 struct snd_dmaengine_dai_dma_data dma_data[2];
@@ -53,6 +63,9 @@ struct davinci_mcasp {
53 u16 bclk_lrclk_ratio; 63 u16 bclk_lrclk_ratio;
54 int streams; 64 int streams;
55 65
66 int sysclk_freq;
67 bool bclk_master;
68
56 /* McASP FIFO related */ 69 /* McASP FIFO related */
57 u8 txnumevt; 70 u8 txnumevt;
58 u8 rxnumevt; 71 u8 rxnumevt;
@@ -60,15 +73,7 @@ struct davinci_mcasp {
60 bool dat_port; 73 bool dat_port;
61 74
62#ifdef CONFIG_PM_SLEEP 75#ifdef CONFIG_PM_SLEEP
63 struct { 76 struct davinci_mcasp_context context;
64 u32 txfmtctl;
65 u32 rxfmtctl;
66 u32 txfmt;
67 u32 rxfmt;
68 u32 aclkxctl;
69 u32 aclkrctl;
70 u32 pdir;
71 } context;
72#endif 77#endif
73}; 78};
74 79
@@ -263,7 +268,9 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
263 unsigned int fmt) 268 unsigned int fmt)
264{ 269{
265 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); 270 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
271 int ret = 0;
266 272
273 pm_runtime_get_sync(mcasp->dev);
267 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 274 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
268 case SND_SOC_DAIFMT_DSP_B: 275 case SND_SOC_DAIFMT_DSP_B:
269 case SND_SOC_DAIFMT_AC97: 276 case SND_SOC_DAIFMT_AC97:
@@ -292,6 +299,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
292 299
293 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR); 300 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR);
294 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR); 301 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR);
302 mcasp->bclk_master = 1;
295 break; 303 break;
296 case SND_SOC_DAIFMT_CBM_CFS: 304 case SND_SOC_DAIFMT_CBM_CFS:
297 /* codec is clock master and frame slave */ 305 /* codec is clock master and frame slave */
@@ -303,6 +311,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
303 311
304 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR); 312 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR);
305 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR); 313 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR);
314 mcasp->bclk_master = 0;
306 break; 315 break;
307 case SND_SOC_DAIFMT_CBM_CFM: 316 case SND_SOC_DAIFMT_CBM_CFM:
308 /* codec is clock and frame master */ 317 /* codec is clock and frame master */
@@ -314,10 +323,12 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
314 323
315 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, 324 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG,
316 ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR); 325 ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR);
326 mcasp->bclk_master = 0;
317 break; 327 break;
318 328
319 default: 329 default:
320 return -EINVAL; 330 ret = -EINVAL;
331 goto out;
321 } 332 }
322 333
323 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 334 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -354,10 +365,12 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
354 break; 365 break;
355 366
356 default: 367 default:
357 return -EINVAL; 368 ret = -EINVAL;
369 break;
358 } 370 }
359 371out:
360 return 0; 372 pm_runtime_put_sync(mcasp->dev);
373 return ret;
361} 374}
362 375
363static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) 376static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
@@ -405,6 +418,8 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
405 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX); 418 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX);
406 } 419 }
407 420
421 mcasp->sysclk_freq = freq;
422
408 return 0; 423 return 0;
409} 424}
410 425
@@ -448,7 +463,7 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
448 return 0; 463 return 0;
449} 464}
450 465
451static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, 466static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
452 int channels) 467 int channels)
453{ 468{
454 int i; 469 int i;
@@ -524,12 +539,18 @@ static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream,
524 return 0; 539 return 0;
525} 540}
526 541
527static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream) 542static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream)
528{ 543{
529 int i, active_slots; 544 int i, active_slots;
530 u32 mask = 0; 545 u32 mask = 0;
531 u32 busel = 0; 546 u32 busel = 0;
532 547
548 if ((mcasp->tdm_slots < 2) || (mcasp->tdm_slots > 32)) {
549 dev_err(mcasp->dev, "tdm slot %d not supported\n",
550 mcasp->tdm_slots);
551 return -EINVAL;
552 }
553
533 active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; 554 active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots;
534 for (i = 0; i < active_slots; i++) 555 for (i = 0; i < active_slots; i++)
535 mask |= (1 << i); 556 mask |= (1 << i);
@@ -539,35 +560,21 @@ static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream)
539 if (!mcasp->dat_port) 560 if (!mcasp->dat_port)
540 busel = TXSEL; 561 busel = TXSEL;
541 562
542 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 563 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask);
543 /* bit stream is MSB first with no delay */ 564 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);
544 /* DSP_B mode */ 565 mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
545 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); 566 FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF));
546 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); 567
547 568 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);
548 if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) 569 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
549 mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, 570 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,
550 FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); 571 FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF));
551 else 572
552 printk(KERN_ERR "playback tdm slot %d not supported\n", 573 return 0;
553 mcasp->tdm_slots);
554 } else {
555 /* bit stream is MSB first with no delay */
556 /* DSP_B mode */
557 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
558 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);
559
560 if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32))
561 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,
562 FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF));
563 else
564 printk(KERN_ERR "capture tdm slot %d not supported\n",
565 mcasp->tdm_slots);
566 }
567} 574}
568 575
569/* S/PDIF */ 576/* S/PDIF */
570static void davinci_hw_dit_param(struct davinci_mcasp *mcasp) 577static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
571{ 578{
572 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 579 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
573 and LSB first */ 580 and LSB first */
@@ -589,6 +596,8 @@ static void davinci_hw_dit_param(struct davinci_mcasp *mcasp)
589 596
590 /* Enable the DIT */ 597 /* Enable the DIT */
591 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); 598 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
599
600 return 0;
592} 601}
593 602
594static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, 603static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
@@ -604,24 +613,31 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
604 u8 fifo_level; 613 u8 fifo_level;
605 u8 slots = mcasp->tdm_slots; 614 u8 slots = mcasp->tdm_slots;
606 u8 active_serializers; 615 u8 active_serializers;
607 int channels; 616 int channels = params_channels(params);
608 struct snd_interval *pcm_channels = hw_param_interval(params, 617 int ret;
609 SNDRV_PCM_HW_PARAM_CHANNELS);
610 channels = pcm_channels->min;
611 618
612 active_serializers = (channels + slots - 1) / slots; 619 /* If mcasp is BCLK master we need to set BCLK divider */
620 if (mcasp->bclk_master) {
621 unsigned int bclk_freq = snd_soc_params_to_bclk(params);
622 if (mcasp->sysclk_freq % bclk_freq != 0) {
623 dev_err(mcasp->dev, "Can't produce requred BCLK\n");
624 return -EINVAL;
625 }
626 davinci_mcasp_set_clkdiv(
627 cpu_dai, 1, mcasp->sysclk_freq / bclk_freq);
628 }
613 629
614 if (davinci_hw_common_param(mcasp, substream->stream, channels) == -EINVAL) 630 ret = mcasp_common_hw_param(mcasp, substream->stream, channels);
615 return -EINVAL; 631 if (ret)
616 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 632 return ret;
617 fifo_level = mcasp->txnumevt * active_serializers;
618 else
619 fifo_level = mcasp->rxnumevt * active_serializers;
620 633
621 if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) 634 if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
622 davinci_hw_dit_param(mcasp); 635 ret = mcasp_dit_hw_param(mcasp);
623 else 636 else
624 davinci_hw_param(mcasp, substream->stream); 637 ret = mcasp_i2s_hw_param(mcasp, substream->stream);
638
639 if (ret)
640 return ret;
625 641
626 switch (params_format(params)) { 642 switch (params_format(params)) {
627 case SNDRV_PCM_FORMAT_U8: 643 case SNDRV_PCM_FORMAT_U8:
@@ -655,6 +671,13 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
655 return -EINVAL; 671 return -EINVAL;
656 } 672 }
657 673
674 /* Calculate FIFO level */
675 active_serializers = (channels + slots - 1) / slots;
676 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
677 fifo_level = mcasp->txnumevt * active_serializers;
678 else
679 fifo_level = mcasp->rxnumevt * active_serializers;
680
658 if (mcasp->version == MCASP_VERSION_2 && !fifo_level) 681 if (mcasp->version == MCASP_VERSION_2 && !fifo_level)
659 dma_params->acnt = 4; 682 dma_params->acnt = 4;
660 else 683 else
@@ -678,19 +701,9 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
678 case SNDRV_PCM_TRIGGER_RESUME: 701 case SNDRV_PCM_TRIGGER_RESUME:
679 case SNDRV_PCM_TRIGGER_START: 702 case SNDRV_PCM_TRIGGER_START:
680 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 703 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
681 ret = pm_runtime_get_sync(mcasp->dev);
682 if (IS_ERR_VALUE(ret))
683 dev_err(mcasp->dev, "pm_runtime_get_sync() failed\n");
684 davinci_mcasp_start(mcasp, substream->stream); 704 davinci_mcasp_start(mcasp, substream->stream);
685 break; 705 break;
686
687 case SNDRV_PCM_TRIGGER_SUSPEND: 706 case SNDRV_PCM_TRIGGER_SUSPEND:
688 davinci_mcasp_stop(mcasp, substream->stream);
689 ret = pm_runtime_put_sync(mcasp->dev);
690 if (IS_ERR_VALUE(ret))
691 dev_err(mcasp->dev, "pm_runtime_put_sync() failed\n");
692 break;
693
694 case SNDRV_PCM_TRIGGER_STOP: 707 case SNDRV_PCM_TRIGGER_STOP:
695 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 708 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
696 davinci_mcasp_stop(mcasp, substream->stream); 709 davinci_mcasp_stop(mcasp, substream->stream);
@@ -726,6 +739,43 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
726 .set_sysclk = davinci_mcasp_set_sysclk, 739 .set_sysclk = davinci_mcasp_set_sysclk,
727}; 740};
728 741
742#ifdef CONFIG_PM_SLEEP
743static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
744{
745 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
746 struct davinci_mcasp_context *context = &mcasp->context;
747
748 context->txfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG);
749 context->rxfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG);
750 context->txfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMT_REG);
751 context->rxfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMT_REG);
752 context->aclkxctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG);
753 context->aclkrctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG);
754 context->pdir = mcasp_get_reg(mcasp, DAVINCI_MCASP_PDIR_REG);
755
756 return 0;
757}
758
759static int davinci_mcasp_resume(struct snd_soc_dai *dai)
760{
761 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
762 struct davinci_mcasp_context *context = &mcasp->context;
763
764 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG, context->txfmtctl);
765 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG, context->rxfmtctl);
766 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMT_REG, context->txfmt);
767 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMT_REG, context->rxfmt);
768 mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, context->aclkxctl);
769 mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, context->aclkrctl);
770 mcasp_set_reg(mcasp, DAVINCI_MCASP_PDIR_REG, context->pdir);
771
772 return 0;
773}
774#else
775#define davinci_mcasp_suspend NULL
776#define davinci_mcasp_resume NULL
777#endif
778
729#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_192000 779#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_192000
730 780
731#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \ 781#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
@@ -742,6 +792,8 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
742static struct snd_soc_dai_driver davinci_mcasp_dai[] = { 792static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
743 { 793 {
744 .name = "davinci-mcasp.0", 794 .name = "davinci-mcasp.0",
795 .suspend = davinci_mcasp_suspend,
796 .resume = davinci_mcasp_resume,
745 .playback = { 797 .playback = {
746 .channels_min = 2, 798 .channels_min = 2,
747 .channels_max = 32 * 16, 799 .channels_max = 32 * 16,
@@ -775,28 +827,28 @@ static const struct snd_soc_component_driver davinci_mcasp_component = {
775}; 827};
776 828
777/* Some HW specific values and defaults. The rest is filled in from DT. */ 829/* Some HW specific values and defaults. The rest is filled in from DT. */
778static struct snd_platform_data dm646x_mcasp_pdata = { 830static struct davinci_mcasp_pdata dm646x_mcasp_pdata = {
779 .tx_dma_offset = 0x400, 831 .tx_dma_offset = 0x400,
780 .rx_dma_offset = 0x400, 832 .rx_dma_offset = 0x400,
781 .asp_chan_q = EVENTQ_0, 833 .asp_chan_q = EVENTQ_0,
782 .version = MCASP_VERSION_1, 834 .version = MCASP_VERSION_1,
783}; 835};
784 836
785static struct snd_platform_data da830_mcasp_pdata = { 837static struct davinci_mcasp_pdata da830_mcasp_pdata = {
786 .tx_dma_offset = 0x2000, 838 .tx_dma_offset = 0x2000,
787 .rx_dma_offset = 0x2000, 839 .rx_dma_offset = 0x2000,
788 .asp_chan_q = EVENTQ_0, 840 .asp_chan_q = EVENTQ_0,
789 .version = MCASP_VERSION_2, 841 .version = MCASP_VERSION_2,
790}; 842};
791 843
792static struct snd_platform_data am33xx_mcasp_pdata = { 844static struct davinci_mcasp_pdata am33xx_mcasp_pdata = {
793 .tx_dma_offset = 0, 845 .tx_dma_offset = 0,
794 .rx_dma_offset = 0, 846 .rx_dma_offset = 0,
795 .asp_chan_q = EVENTQ_0, 847 .asp_chan_q = EVENTQ_0,
796 .version = MCASP_VERSION_3, 848 .version = MCASP_VERSION_3,
797}; 849};
798 850
799static struct snd_platform_data dra7_mcasp_pdata = { 851static struct davinci_mcasp_pdata dra7_mcasp_pdata = {
800 .tx_dma_offset = 0x200, 852 .tx_dma_offset = 0x200,
801 .rx_dma_offset = 0x284, 853 .rx_dma_offset = 0x284,
802 .asp_chan_q = EVENTQ_0, 854 .asp_chan_q = EVENTQ_0,
@@ -864,11 +916,11 @@ err1:
864 return ret; 916 return ret;
865} 917}
866 918
867static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( 919static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of(
868 struct platform_device *pdev) 920 struct platform_device *pdev)
869{ 921{
870 struct device_node *np = pdev->dev.of_node; 922 struct device_node *np = pdev->dev.of_node;
871 struct snd_platform_data *pdata = NULL; 923 struct davinci_mcasp_pdata *pdata = NULL;
872 const struct of_device_id *match = 924 const struct of_device_id *match =
873 of_match_device(mcasp_dt_ids, &pdev->dev); 925 of_match_device(mcasp_dt_ids, &pdev->dev);
874 struct of_phandle_args dma_spec; 926 struct of_phandle_args dma_spec;
@@ -881,7 +933,7 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
881 pdata = pdev->dev.platform_data; 933 pdata = pdev->dev.platform_data;
882 return pdata; 934 return pdata;
883 } else if (match) { 935 } else if (match) {
884 pdata = (struct snd_platform_data *) match->data; 936 pdata = (struct davinci_mcasp_pdata*) match->data;
885 } else { 937 } else {
886 /* control shouldn't reach here. something is wrong */ 938 /* control shouldn't reach here. something is wrong */
887 ret = -EINVAL; 939 ret = -EINVAL;
@@ -973,9 +1025,9 @@ nodata:
973 1025
974static int davinci_mcasp_probe(struct platform_device *pdev) 1026static int davinci_mcasp_probe(struct platform_device *pdev)
975{ 1027{
976 struct davinci_pcm_dma_params *dma_data; 1028 struct davinci_pcm_dma_params *dma_params;
977 struct resource *mem, *ioarea, *res, *dat; 1029 struct resource *mem, *ioarea, *res, *dat;
978 struct snd_platform_data *pdata; 1030 struct davinci_mcasp_pdata *pdata;
979 struct davinci_mcasp *mcasp; 1031 struct davinci_mcasp *mcasp;
980 int ret; 1032 int ret;
981 1033
@@ -1042,41 +1094,41 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1042 if (dat) 1094 if (dat)
1043 mcasp->dat_port = true; 1095 mcasp->dat_port = true;
1044 1096
1045 dma_data = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; 1097 dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
1046 dma_data->asp_chan_q = pdata->asp_chan_q; 1098 dma_params->asp_chan_q = pdata->asp_chan_q;
1047 dma_data->ram_chan_q = pdata->ram_chan_q; 1099 dma_params->ram_chan_q = pdata->ram_chan_q;
1048 dma_data->sram_pool = pdata->sram_pool; 1100 dma_params->sram_pool = pdata->sram_pool;
1049 dma_data->sram_size = pdata->sram_size_playback; 1101 dma_params->sram_size = pdata->sram_size_playback;
1050 if (dat) 1102 if (dat)
1051 dma_data->dma_addr = dat->start; 1103 dma_params->dma_addr = dat->start;
1052 else 1104 else
1053 dma_data->dma_addr = mem->start + pdata->tx_dma_offset; 1105 dma_params->dma_addr = mem->start + pdata->tx_dma_offset;
1054 1106
1055 /* Unconditional dmaengine stuff */ 1107 /* Unconditional dmaengine stuff */
1056 mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = dma_data->dma_addr; 1108 mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = dma_params->dma_addr;
1057 1109
1058 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 1110 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1059 if (res) 1111 if (res)
1060 dma_data->channel = res->start; 1112 dma_params->channel = res->start;
1061 else 1113 else
1062 dma_data->channel = pdata->tx_dma_channel; 1114 dma_params->channel = pdata->tx_dma_channel;
1063 1115
1064 dma_data = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE]; 1116 dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE];
1065 dma_data->asp_chan_q = pdata->asp_chan_q; 1117 dma_params->asp_chan_q = pdata->asp_chan_q;
1066 dma_data->ram_chan_q = pdata->ram_chan_q; 1118 dma_params->ram_chan_q = pdata->ram_chan_q;
1067 dma_data->sram_pool = pdata->sram_pool; 1119 dma_params->sram_pool = pdata->sram_pool;
1068 dma_data->sram_size = pdata->sram_size_capture; 1120 dma_params->sram_size = pdata->sram_size_capture;
1069 if (dat) 1121 if (dat)
1070 dma_data->dma_addr = dat->start; 1122 dma_params->dma_addr = dat->start;
1071 else 1123 else
1072 dma_data->dma_addr = mem->start + pdata->rx_dma_offset; 1124 dma_params->dma_addr = mem->start + pdata->rx_dma_offset;
1073 1125
1074 /* Unconditional dmaengine stuff */ 1126 /* Unconditional dmaengine stuff */
1075 mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = dma_data->dma_addr; 1127 mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = dma_params->dma_addr;
1076 1128
1077 if (mcasp->version < MCASP_VERSION_3) { 1129 if (mcasp->version < MCASP_VERSION_3) {
1078 mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE; 1130 mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE;
1079 /* dma_data->dma_addr is pointing to the data port address */ 1131 /* dma_params->dma_addr is pointing to the data port address */
1080 mcasp->dat_port = true; 1132 mcasp->dat_port = true;
1081 } else { 1133 } else {
1082 mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE; 1134 mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE;
@@ -1084,9 +1136,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1084 1136
1085 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 1137 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
1086 if (res) 1138 if (res)
1087 dma_data->channel = res->start; 1139 dma_params->channel = res->start;
1088 else 1140 else
1089 dma_data->channel = pdata->rx_dma_channel; 1141 dma_params->channel = pdata->rx_dma_channel;
1090 1142
1091 /* Unconditional dmaengine stuff */ 1143 /* Unconditional dmaengine stuff */
1092 mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = "tx"; 1144 mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = "tx";
@@ -1134,49 +1186,12 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
1134 return 0; 1186 return 0;
1135} 1187}
1136 1188
1137#ifdef CONFIG_PM_SLEEP
1138static int davinci_mcasp_suspend(struct device *dev)
1139{
1140 struct davinci_mcasp *mcasp = dev_get_drvdata(dev);
1141
1142 mcasp->context.txfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG);
1143 mcasp->context.rxfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG);
1144 mcasp->context.txfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMT_REG);
1145 mcasp->context.rxfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMT_REG);
1146 mcasp->context.aclkxctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG);
1147 mcasp->context.aclkrctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG);
1148 mcasp->context.pdir = mcasp_get_reg(mcasp, DAVINCI_MCASP_PDIR_REG);
1149
1150 return 0;
1151}
1152
1153static int davinci_mcasp_resume(struct device *dev)
1154{
1155 struct davinci_mcasp *mcasp = dev_get_drvdata(dev);
1156
1157 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG, mcasp->context.txfmtctl);
1158 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG, mcasp->context.rxfmtctl);
1159 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMT_REG, mcasp->context.txfmt);
1160 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMT_REG, mcasp->context.rxfmt);
1161 mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, mcasp->context.aclkxctl);
1162 mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, mcasp->context.aclkrctl);
1163 mcasp_set_reg(mcasp, DAVINCI_MCASP_PDIR_REG, mcasp->context.pdir);
1164
1165 return 0;
1166}
1167#endif
1168
1169SIMPLE_DEV_PM_OPS(davinci_mcasp_pm_ops,
1170 davinci_mcasp_suspend,
1171 davinci_mcasp_resume);
1172
1173static struct platform_driver davinci_mcasp_driver = { 1189static struct platform_driver davinci_mcasp_driver = {
1174 .probe = davinci_mcasp_probe, 1190 .probe = davinci_mcasp_probe,
1175 .remove = davinci_mcasp_remove, 1191 .remove = davinci_mcasp_remove,
1176 .driver = { 1192 .driver = {
1177 .name = "davinci-mcasp", 1193 .name = "davinci-mcasp",
1178 .owner = THIS_MODULE, 1194 .owner = THIS_MODULE,
1179 .pm = &davinci_mcasp_pm_ops,
1180 .of_match_table = mcasp_dt_ids, 1195 .of_match_table = mcasp_dt_ids,
1181 }, 1196 },
1182}; 1197};
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 07f8f141727d..597962ec28fa 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -1,5 +1,6 @@
1config SND_SOC_FSL_SAI 1config SND_SOC_FSL_SAI
2 tristate 2 tristate
3 select REGMAP_MMIO
3 select SND_SOC_GENERIC_DMAENGINE_PCM 4 select SND_SOC_GENERIC_DMAENGINE_PCM
4 5
5config SND_SOC_FSL_SSI 6config SND_SOC_FSL_SSI
@@ -7,9 +8,11 @@ config SND_SOC_FSL_SSI
7 8
8config SND_SOC_FSL_SPDIF 9config SND_SOC_FSL_SPDIF
9 tristate 10 tristate
11 select REGMAP_MMIO
10 12
11config SND_SOC_FSL_ESAI 13config SND_SOC_FSL_ESAI
12 tristate 14 tristate
15 select REGMAP_MMIO
13 16
14config SND_SOC_FSL_UTILS 17config SND_SOC_FSL_UTILS
15 tristate 18 tristate
@@ -168,12 +171,14 @@ config SND_SOC_EUKREA_TLV320
168 depends on MACH_EUKREA_MBIMX27_BASEBOARD \ 171 depends on MACH_EUKREA_MBIMX27_BASEBOARD \
169 || MACH_EUKREA_MBIMXSD25_BASEBOARD \ 172 || MACH_EUKREA_MBIMXSD25_BASEBOARD \
170 || MACH_EUKREA_MBIMXSD35_BASEBOARD \ 173 || MACH_EUKREA_MBIMXSD35_BASEBOARD \
171 || MACH_EUKREA_MBIMXSD51_BASEBOARD 174 || MACH_EUKREA_MBIMXSD51_BASEBOARD \
175 || (OF && ARM)
172 depends on I2C 176 depends on I2C
173 select SND_SOC_TLV320AIC23 177 select SND_SOC_TLV320AIC23_I2C
174 select SND_SOC_IMX_PCM_FIQ
175 select SND_SOC_IMX_AUDMUX 178 select SND_SOC_IMX_AUDMUX
176 select SND_SOC_IMX_SSI 179 select SND_SOC_IMX_SSI
180 select SND_SOC_FSL_SSI
181 select SND_SOC_IMX_PCM_DMA
177 help 182 help
178 Enable I2S based access to the TLV320AIC23B codec attached 183 Enable I2S based access to the TLV320AIC23B codec attached
179 to the SSI interface 184 to the SSI interface
@@ -204,7 +209,6 @@ config SND_SOC_IMX_SPDIF
204 tristate "SoC Audio support for i.MX boards with S/PDIF" 209 tristate "SoC Audio support for i.MX boards with S/PDIF"
205 select SND_SOC_IMX_PCM_DMA 210 select SND_SOC_IMX_PCM_DMA
206 select SND_SOC_FSL_SPDIF 211 select SND_SOC_FSL_SPDIF
207 select REGMAP_MMIO
208 help 212 help
209 SoC Audio support for i.MX boards with S/PDIF 213 SoC Audio support for i.MX boards with S/PDIF
210 Say Y if you want to add support for SoC audio on an i.MX board with 214 Say Y if you want to add support for SoC audio on an i.MX board with
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index 5983740be123..eb093d5b85c4 100644
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -15,8 +15,11 @@
15 * 15 *
16 */ 16 */
17 17
18#include <linux/errno.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
21#include <linux/of.h>
22#include <linux/of_platform.h>
20#include <linux/device.h> 23#include <linux/device.h>
21#include <linux/i2c.h> 24#include <linux/i2c.h>
22#include <sound/core.h> 25#include <sound/core.h>
@@ -26,6 +29,7 @@
26 29
27#include "../codecs/tlv320aic23.h" 30#include "../codecs/tlv320aic23.h"
28#include "imx-ssi.h" 31#include "imx-ssi.h"
32#include "fsl_ssi.h"
29#include "imx-audmux.h" 33#include "imx-audmux.h"
30 34
31#define CODEC_CLOCK 12000000 35#define CODEC_CLOCK 12000000
@@ -41,7 +45,8 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
41 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | 45 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
42 SND_SOC_DAIFMT_NB_NF | 46 SND_SOC_DAIFMT_NB_NF |
43 SND_SOC_DAIFMT_CBM_CFM); 47 SND_SOC_DAIFMT_CBM_CFM);
44 if (ret) { 48 /* fsl_ssi lacks the set_fmt ops. */
49 if (ret && ret != -ENOTSUPP) {
45 dev_err(cpu_dai->dev, 50 dev_err(cpu_dai->dev,
46 "Failed to set the cpu dai format.\n"); 51 "Failed to set the cpu dai format.\n");
47 return ret; 52 return ret;
@@ -63,11 +68,13 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
63 "Failed to set the codec sysclk.\n"); 68 "Failed to set the codec sysclk.\n");
64 return ret; 69 return ret;
65 } 70 }
71
66 snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0); 72 snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
67 73
68 ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, 74 ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
69 SND_SOC_CLOCK_IN); 75 SND_SOC_CLOCK_IN);
70 if (ret) { 76 /* fsl_ssi lacks the set_sysclk ops */
77 if (ret && ret != -EINVAL) {
71 dev_err(cpu_dai->dev, 78 dev_err(cpu_dai->dev,
72 "Can't set the IMX_SSP_SYS_CLK CPU system clock.\n"); 79 "Can't set the IMX_SSP_SYS_CLK CPU system clock.\n");
73 return ret; 80 return ret;
@@ -84,14 +91,10 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = {
84 .name = "tlv320aic23", 91 .name = "tlv320aic23",
85 .stream_name = "TLV320AIC23", 92 .stream_name = "TLV320AIC23",
86 .codec_dai_name = "tlv320aic23-hifi", 93 .codec_dai_name = "tlv320aic23-hifi",
87 .platform_name = "imx-ssi.0",
88 .codec_name = "tlv320aic23-codec.0-001a",
89 .cpu_dai_name = "imx-ssi.0",
90 .ops = &eukrea_tlv320_snd_ops, 94 .ops = &eukrea_tlv320_snd_ops,
91}; 95};
92 96
93static struct snd_soc_card eukrea_tlv320 = { 97static struct snd_soc_card eukrea_tlv320 = {
94 .name = "cpuimx-audio",
95 .owner = THIS_MODULE, 98 .owner = THIS_MODULE,
96 .dai_link = &eukrea_tlv320_dai, 99 .dai_link = &eukrea_tlv320_dai,
97 .num_links = 1, 100 .num_links = 1,
@@ -101,8 +104,65 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
101{ 104{
102 int ret; 105 int ret;
103 int int_port = 0, ext_port; 106 int int_port = 0, ext_port;
107 struct device_node *np = pdev->dev.of_node;
108 struct device_node *ssi_np, *codec_np;
104 109
105 if (machine_is_eukrea_cpuimx27()) { 110 eukrea_tlv320.dev = &pdev->dev;
111 if (np) {
112 ret = snd_soc_of_parse_card_name(&eukrea_tlv320,
113 "eukrea,model");
114 if (ret) {
115 dev_err(&pdev->dev,
116 "eukrea,model node missing or invalid.\n");
117 goto err;
118 }
119
120 ssi_np = of_parse_phandle(pdev->dev.of_node,
121 "ssi-controller", 0);
122 if (!ssi_np) {
123 dev_err(&pdev->dev,
124 "ssi-controller missing or invalid.\n");
125 ret = -ENODEV;
126 goto err;
127 }
128
129 codec_np = of_parse_phandle(ssi_np, "codec-handle", 0);
130 if (codec_np)
131 eukrea_tlv320_dai.codec_of_node = codec_np;
132 else
133 dev_err(&pdev->dev, "codec-handle node missing or invalid.\n");
134
135 ret = of_property_read_u32(np, "fsl,mux-int-port", &int_port);
136 if (ret) {
137 dev_err(&pdev->dev,
138 "fsl,mux-int-port node missing or invalid.\n");
139 return ret;
140 }
141 ret = of_property_read_u32(np, "fsl,mux-ext-port", &ext_port);
142 if (ret) {
143 dev_err(&pdev->dev,
144 "fsl,mux-ext-port node missing or invalid.\n");
145 return ret;
146 }
147
148 /*
149 * The port numbering in the hardware manual starts at 1, while
150 * the audmux API expects it starts at 0.
151 */
152 int_port--;
153 ext_port--;
154
155 eukrea_tlv320_dai.cpu_of_node = ssi_np;
156 eukrea_tlv320_dai.platform_of_node = ssi_np;
157 } else {
158 eukrea_tlv320_dai.cpu_dai_name = "imx-ssi.0";
159 eukrea_tlv320_dai.platform_name = "imx-ssi.0";
160 eukrea_tlv320_dai.codec_name = "tlv320aic23-codec.0-001a";
161 eukrea_tlv320.name = "cpuimx-audio";
162 }
163
164 if (machine_is_eukrea_cpuimx27() ||
165 of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux")) {
106 imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, 166 imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
107 IMX_AUDMUX_V1_PCR_SYN | 167 IMX_AUDMUX_V1_PCR_SYN |
108 IMX_AUDMUX_V1_PCR_TFSDIR | 168 IMX_AUDMUX_V1_PCR_TFSDIR |
@@ -119,8 +179,12 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
119 ); 179 );
120 } else if (machine_is_eukrea_cpuimx25sd() || 180 } else if (machine_is_eukrea_cpuimx25sd() ||
121 machine_is_eukrea_cpuimx35sd() || 181 machine_is_eukrea_cpuimx35sd() ||
122 machine_is_eukrea_cpuimx51sd()) { 182 machine_is_eukrea_cpuimx51sd() ||
123 ext_port = machine_is_eukrea_cpuimx25sd() ? 4 : 3; 183 of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux")) {
184 if (!np)
185 ext_port = machine_is_eukrea_cpuimx25sd() ?
186 4 : 3;
187
124 imx_audmux_v2_configure_port(int_port, 188 imx_audmux_v2_configure_port(int_port,
125 IMX_AUDMUX_V2_PTCR_SYN | 189 IMX_AUDMUX_V2_PTCR_SYN |
126 IMX_AUDMUX_V2_PTCR_TFSDIR | 190 IMX_AUDMUX_V2_PTCR_TFSDIR |
@@ -134,14 +198,27 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
134 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port) 198 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)
135 ); 199 );
136 } else { 200 } else {
137 /* return happy. We might run on a totally different machine */ 201 if (np) {
138 return 0; 202 /* The eukrea,asoc-tlv320 driver was explicitely
203 * requested (through the device tree).
204 */
205 dev_err(&pdev->dev,
206 "Missing or invalid audmux DT node.\n");
207 return -ENODEV;
208 } else {
209 /* Return happy.
210 * We might run on a totally different machine.
211 */
212 return 0;
213 }
139 } 214 }
140 215
141 eukrea_tlv320.dev = &pdev->dev;
142 ret = snd_soc_register_card(&eukrea_tlv320); 216 ret = snd_soc_register_card(&eukrea_tlv320);
217err:
143 if (ret) 218 if (ret)
144 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); 219 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
220 if (np)
221 of_node_put(ssi_np);
145 222
146 return ret; 223 return ret;
147} 224}
@@ -153,10 +230,17 @@ static int eukrea_tlv320_remove(struct platform_device *pdev)
153 return 0; 230 return 0;
154} 231}
155 232
233static const struct of_device_id imx_tlv320_dt_ids[] = {
234 { .compatible = "eukrea,asoc-tlv320"},
235 { /* sentinel */ }
236};
237MODULE_DEVICE_TABLE(of, imx_tlv320_dt_ids);
238
156static struct platform_driver eukrea_tlv320_driver = { 239static struct platform_driver eukrea_tlv320_driver = {
157 .driver = { 240 .driver = {
158 .name = "eukrea_tlv320", 241 .name = "eukrea_tlv320",
159 .owner = THIS_MODULE, 242 .owner = THIS_MODULE,
243 .of_match_table = imx_tlv320_dt_ids,
160 }, 244 },
161 .probe = eukrea_tlv320_probe, 245 .probe = eukrea_tlv320_probe,
162 .remove = eukrea_tlv320_remove, 246 .remove = eukrea_tlv320_remove,
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index d0c72ed261e7..0ba37005ab04 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -326,7 +326,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
326 regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, 326 regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA,
327 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); 327 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask));
328 regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, 328 regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB,
329 ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(tx_mask)); 329 ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask));
330 330
331 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, 331 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
332 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); 332 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
@@ -334,7 +334,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
334 regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, 334 regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA,
335 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); 335 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask));
336 regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, 336 regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB,
337 ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(rx_mask)); 337 ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask));
338 338
339 esai_priv->slot_width = slot_width; 339 esai_priv->slot_width = slot_width;
340 340
@@ -431,17 +431,26 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
431static int fsl_esai_startup(struct snd_pcm_substream *substream, 431static int fsl_esai_startup(struct snd_pcm_substream *substream,
432 struct snd_soc_dai *dai) 432 struct snd_soc_dai *dai)
433{ 433{
434 int ret;
434 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 435 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
435 436
436 /* 437 /*
437 * Some platforms might use the same bit to gate all three or two of 438 * Some platforms might use the same bit to gate all three or two of
438 * clocks, so keep all clocks open/close at the same time for safety 439 * clocks, so keep all clocks open/close at the same time for safety
439 */ 440 */
440 clk_prepare_enable(esai_priv->coreclk); 441 ret = clk_prepare_enable(esai_priv->coreclk);
441 if (!IS_ERR(esai_priv->extalclk)) 442 if (ret)
442 clk_prepare_enable(esai_priv->extalclk); 443 return ret;
443 if (!IS_ERR(esai_priv->fsysclk)) 444 if (!IS_ERR(esai_priv->extalclk)) {
444 clk_prepare_enable(esai_priv->fsysclk); 445 ret = clk_prepare_enable(esai_priv->extalclk);
446 if (ret)
447 goto err_extalck;
448 }
449 if (!IS_ERR(esai_priv->fsysclk)) {
450 ret = clk_prepare_enable(esai_priv->fsysclk);
451 if (ret)
452 goto err_fsysclk;
453 }
445 454
446 if (!dai->active) { 455 if (!dai->active) {
447 /* Reset Port C */ 456 /* Reset Port C */
@@ -463,6 +472,14 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
463 } 472 }
464 473
465 return 0; 474 return 0;
475
476err_fsysclk:
477 if (!IS_ERR(esai_priv->extalclk))
478 clk_disable_unprepare(esai_priv->extalclk);
479err_extalck:
480 clk_disable_unprepare(esai_priv->coreclk);
481
482 return ret;
466} 483}
467 484
468static int fsl_esai_hw_params(struct snd_pcm_substream *substream, 485static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
@@ -661,7 +678,7 @@ static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
661 } 678 }
662} 679}
663 680
664static const struct regmap_config fsl_esai_regmap_config = { 681static struct regmap_config fsl_esai_regmap_config = {
665 .reg_bits = 32, 682 .reg_bits = 32,
666 .reg_stride = 4, 683 .reg_stride = 4,
667 .val_bits = 32, 684 .val_bits = 32,
@@ -687,6 +704,9 @@ static int fsl_esai_probe(struct platform_device *pdev)
687 esai_priv->pdev = pdev; 704 esai_priv->pdev = pdev;
688 strcpy(esai_priv->name, np->name); 705 strcpy(esai_priv->name, np->name);
689 706
707 if (of_property_read_bool(np, "big-endian"))
708 fsl_esai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
709
690 /* Get the addresses and IRQ */ 710 /* Get the addresses and IRQ */
691 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 711 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
692 regs = devm_ioremap_resource(&pdev->dev, res); 712 regs = devm_ioremap_resource(&pdev->dev, res);
diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h
index 9c9f957fcae1..75e14033e8d8 100644
--- a/sound/soc/fsl/fsl_esai.h
+++ b/sound/soc/fsl/fsl_esai.h
@@ -322,7 +322,7 @@
322#define ESAI_xSMB_xS_SHIFT 0 322#define ESAI_xSMB_xS_SHIFT 0
323#define ESAI_xSMB_xS_WIDTH 16 323#define ESAI_xSMB_xS_WIDTH 16
324#define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT) 324#define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT)
325#define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMA_xS_MASK) 325#define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMB_xS_MASK)
326 326
327/* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */ 327/* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */
328#define ESAI_PRRC_PDC_SHIFT 0 328#define ESAI_PRRC_PDC_SHIFT 0
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index cdd3fa830704..c4a423111673 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -15,6 +15,7 @@
15#include <linux/dmaengine.h> 15#include <linux/dmaengine.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/of_address.h> 17#include <linux/of_address.h>
18#include <linux/regmap.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/dmaengine_pcm.h> 21#include <sound/dmaengine_pcm.h>
@@ -22,34 +23,6 @@
22 23
23#include "fsl_sai.h" 24#include "fsl_sai.h"
24 25
25static inline u32 sai_readl(struct fsl_sai *sai,
26 const void __iomem *addr)
27{
28 u32 val;
29
30 val = __raw_readl(addr);
31
32 if (likely(sai->big_endian_regs))
33 val = be32_to_cpu(val);
34 else
35 val = le32_to_cpu(val);
36 rmb();
37
38 return val;
39}
40
41static inline void sai_writel(struct fsl_sai *sai,
42 u32 val, void __iomem *addr)
43{
44 wmb();
45 if (likely(sai->big_endian_regs))
46 val = cpu_to_be32(val);
47 else
48 val = cpu_to_le32(val);
49
50 __raw_writel(val, addr);
51}
52
53static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, 26static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
54 int clk_id, unsigned int freq, int fsl_dir) 27 int clk_id, unsigned int freq, int fsl_dir)
55{ 28{
@@ -61,7 +34,8 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
61 else 34 else
62 reg_cr2 = FSL_SAI_RCR2; 35 reg_cr2 = FSL_SAI_RCR2;
63 36
64 val_cr2 = sai_readl(sai, sai->base + reg_cr2); 37 regmap_read(sai->regmap, reg_cr2, &val_cr2);
38
65 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK; 39 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
66 40
67 switch (clk_id) { 41 switch (clk_id) {
@@ -81,7 +55,7 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
81 return -EINVAL; 55 return -EINVAL;
82 } 56 }
83 57
84 sai_writel(sai, val_cr2, sai->base + reg_cr2); 58 regmap_write(sai->regmap, reg_cr2, val_cr2);
85 59
86 return 0; 60 return 0;
87} 61}
@@ -89,32 +63,22 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
89static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, 63static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
90 int clk_id, unsigned int freq, int dir) 64 int clk_id, unsigned int freq, int dir)
91{ 65{
92 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
93 int ret; 66 int ret;
94 67
95 if (dir == SND_SOC_CLOCK_IN) 68 if (dir == SND_SOC_CLOCK_IN)
96 return 0; 69 return 0;
97 70
98 ret = clk_prepare_enable(sai->clk);
99 if (ret)
100 return ret;
101
102 ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, 71 ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
103 FSL_FMT_TRANSMITTER); 72 FSL_FMT_TRANSMITTER);
104 if (ret) { 73 if (ret) {
105 dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret); 74 dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret);
106 goto err_clk; 75 return ret;
107 } 76 }
108 77
109 ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, 78 ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
110 FSL_FMT_RECEIVER); 79 FSL_FMT_RECEIVER);
111 if (ret) { 80 if (ret)
112 dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret); 81 dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret);
113 goto err_clk;
114 }
115
116err_clk:
117 clk_disable_unprepare(sai->clk);
118 82
119 return ret; 83 return ret;
120} 84}
@@ -133,43 +97,84 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
133 reg_cr4 = FSL_SAI_RCR4; 97 reg_cr4 = FSL_SAI_RCR4;
134 } 98 }
135 99
136 val_cr2 = sai_readl(sai, sai->base + reg_cr2); 100 regmap_read(sai->regmap, reg_cr2, &val_cr2);
137 val_cr4 = sai_readl(sai, sai->base + reg_cr4); 101 regmap_read(sai->regmap, reg_cr4, &val_cr4);
138 102
139 if (sai->big_endian_data) 103 if (sai->big_endian_data)
140 val_cr4 &= ~FSL_SAI_CR4_MF; 104 val_cr4 &= ~FSL_SAI_CR4_MF;
141 else 105 else
142 val_cr4 |= FSL_SAI_CR4_MF; 106 val_cr4 |= FSL_SAI_CR4_MF;
143 107
108 /* DAI mode */
144 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 109 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
145 case SND_SOC_DAIFMT_I2S: 110 case SND_SOC_DAIFMT_I2S:
111 /*
112 * Frame low, 1clk before data, one word length for frame sync,
113 * frame sync starts one serial clock cycle earlier,
114 * that is, together with the last bit of the previous
115 * data word.
116 */
117 val_cr2 &= ~FSL_SAI_CR2_BCP;
118 val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP;
119 break;
120 case SND_SOC_DAIFMT_LEFT_J:
121 /*
122 * Frame high, one word length for frame sync,
123 * frame sync asserts with the first bit of the frame.
124 */
125 val_cr2 &= ~FSL_SAI_CR2_BCP;
126 val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP);
127 break;
128 case SND_SOC_DAIFMT_DSP_A:
129 /*
130 * Frame high, 1clk before data, one bit for frame sync,
131 * frame sync starts one serial clock cycle earlier,
132 * that is, together with the last bit of the previous
133 * data word.
134 */
135 val_cr2 &= ~FSL_SAI_CR2_BCP;
136 val_cr4 &= ~FSL_SAI_CR4_FSP;
146 val_cr4 |= FSL_SAI_CR4_FSE; 137 val_cr4 |= FSL_SAI_CR4_FSE;
138 sai->is_dsp_mode = true;
139 break;
140 case SND_SOC_DAIFMT_DSP_B:
141 /*
142 * Frame high, one bit for frame sync,
143 * frame sync asserts with the first bit of the frame.
144 */
145 val_cr2 &= ~FSL_SAI_CR2_BCP;
146 val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP);
147 sai->is_dsp_mode = true;
147 break; 148 break;
149 case SND_SOC_DAIFMT_RIGHT_J:
150 /* To be done */
148 default: 151 default:
149 return -EINVAL; 152 return -EINVAL;
150 } 153 }
151 154
155 /* DAI clock inversion */
152 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 156 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
153 case SND_SOC_DAIFMT_IB_IF: 157 case SND_SOC_DAIFMT_IB_IF:
154 val_cr4 |= FSL_SAI_CR4_FSP; 158 /* Invert both clocks */
155 val_cr2 &= ~FSL_SAI_CR2_BCP; 159 val_cr2 ^= FSL_SAI_CR2_BCP;
160 val_cr4 ^= FSL_SAI_CR4_FSP;
156 break; 161 break;
157 case SND_SOC_DAIFMT_IB_NF: 162 case SND_SOC_DAIFMT_IB_NF:
158 val_cr4 &= ~FSL_SAI_CR4_FSP; 163 /* Invert bit clock */
159 val_cr2 &= ~FSL_SAI_CR2_BCP; 164 val_cr2 ^= FSL_SAI_CR2_BCP;
160 break; 165 break;
161 case SND_SOC_DAIFMT_NB_IF: 166 case SND_SOC_DAIFMT_NB_IF:
162 val_cr4 |= FSL_SAI_CR4_FSP; 167 /* Invert frame clock */
163 val_cr2 |= FSL_SAI_CR2_BCP; 168 val_cr4 ^= FSL_SAI_CR4_FSP;
164 break; 169 break;
165 case SND_SOC_DAIFMT_NB_NF: 170 case SND_SOC_DAIFMT_NB_NF:
166 val_cr4 &= ~FSL_SAI_CR4_FSP; 171 /* Nothing to do for both normal cases */
167 val_cr2 |= FSL_SAI_CR2_BCP;
168 break; 172 break;
169 default: 173 default:
170 return -EINVAL; 174 return -EINVAL;
171 } 175 }
172 176
177 /* DAI clock master masks */
173 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 178 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
174 case SND_SOC_DAIFMT_CBS_CFS: 179 case SND_SOC_DAIFMT_CBS_CFS:
175 val_cr2 |= FSL_SAI_CR2_BCD_MSTR; 180 val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
@@ -179,39 +184,37 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
179 val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; 184 val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR;
180 val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; 185 val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR;
181 break; 186 break;
187 case SND_SOC_DAIFMT_CBS_CFM:
188 val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
189 val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR;
190 break;
191 case SND_SOC_DAIFMT_CBM_CFS:
192 val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR;
193 val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
194 break;
182 default: 195 default:
183 return -EINVAL; 196 return -EINVAL;
184 } 197 }
185 198
186 sai_writel(sai, val_cr2, sai->base + reg_cr2); 199 regmap_write(sai->regmap, reg_cr2, val_cr2);
187 sai_writel(sai, val_cr4, sai->base + reg_cr4); 200 regmap_write(sai->regmap, reg_cr4, val_cr4);
188 201
189 return 0; 202 return 0;
190} 203}
191 204
192static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) 205static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
193{ 206{
194 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
195 int ret; 207 int ret;
196 208
197 ret = clk_prepare_enable(sai->clk);
198 if (ret)
199 return ret;
200
201 ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER); 209 ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER);
202 if (ret) { 210 if (ret) {
203 dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret); 211 dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret);
204 goto err_clk; 212 return ret;
205 } 213 }
206 214
207 ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER); 215 ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER);
208 if (ret) { 216 if (ret)
209 dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret); 217 dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret);
210 goto err_clk;
211 }
212
213err_clk:
214 clk_disable_unprepare(sai->clk);
215 218
216 return ret; 219 return ret;
217} 220}
@@ -235,16 +238,19 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
235 reg_mr = FSL_SAI_RMR; 238 reg_mr = FSL_SAI_RMR;
236 } 239 }
237 240
238 val_cr4 = sai_readl(sai, sai->base + reg_cr4); 241 regmap_read(sai->regmap, reg_cr4, &val_cr4);
242 regmap_read(sai->regmap, reg_cr4, &val_cr5);
243
239 val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK; 244 val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK;
240 val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK; 245 val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK;
241 246
242 val_cr5 = sai_readl(sai, sai->base + reg_cr5);
243 val_cr5 &= ~FSL_SAI_CR5_WNW_MASK; 247 val_cr5 &= ~FSL_SAI_CR5_WNW_MASK;
244 val_cr5 &= ~FSL_SAI_CR5_W0W_MASK; 248 val_cr5 &= ~FSL_SAI_CR5_W0W_MASK;
245 val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; 249 val_cr5 &= ~FSL_SAI_CR5_FBT_MASK;
246 250
247 val_cr4 |= FSL_SAI_CR4_SYWD(word_width); 251 if (!sai->is_dsp_mode)
252 val_cr4 |= FSL_SAI_CR4_SYWD(word_width);
253
248 val_cr5 |= FSL_SAI_CR5_WNW(word_width); 254 val_cr5 |= FSL_SAI_CR5_WNW(word_width);
249 val_cr5 |= FSL_SAI_CR5_W0W(word_width); 255 val_cr5 |= FSL_SAI_CR5_W0W(word_width);
250 256
@@ -257,9 +263,9 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
257 val_cr4 |= FSL_SAI_CR4_FRSZ(channels); 263 val_cr4 |= FSL_SAI_CR4_FRSZ(channels);
258 val_mr = ~0UL - ((1 << channels) - 1); 264 val_mr = ~0UL - ((1 << channels) - 1);
259 265
260 sai_writel(sai, val_cr4, sai->base + reg_cr4); 266 regmap_write(sai->regmap, reg_cr4, val_cr4);
261 sai_writel(sai, val_cr5, sai->base + reg_cr5); 267 regmap_write(sai->regmap, reg_cr5, val_cr5);
262 sai_writel(sai, val_mr, sai->base + reg_mr); 268 regmap_write(sai->regmap, reg_mr, val_mr);
263 269
264 return 0; 270 return 0;
265} 271}
@@ -268,44 +274,42 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
268 struct snd_soc_dai *cpu_dai) 274 struct snd_soc_dai *cpu_dai)
269{ 275{
270 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 276 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
271 u32 tcsr, rcsr, val_cr2, val_cr3, reg_cr3; 277 u32 tcsr, rcsr;
272
273 val_cr2 = sai_readl(sai, sai->base + FSL_SAI_TCR2);
274 val_cr2 &= ~FSL_SAI_CR2_SYNC;
275 sai_writel(sai, val_cr2, sai->base + FSL_SAI_TCR2);
276 278
277 val_cr2 = sai_readl(sai, sai->base + FSL_SAI_RCR2); 279 /*
278 val_cr2 |= FSL_SAI_CR2_SYNC; 280 * The transmitter bit clock and frame sync are to be
279 sai_writel(sai, val_cr2, sai->base + FSL_SAI_RCR2); 281 * used by both the transmitter and receiver.
282 */
283 regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC,
284 ~FSL_SAI_CR2_SYNC);
285 regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
286 FSL_SAI_CR2_SYNC);
280 287
281 tcsr = sai_readl(sai, sai->base + FSL_SAI_TCSR); 288 regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr);
282 rcsr = sai_readl(sai, sai->base + FSL_SAI_RCSR); 289 regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr);
283 290
284 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 291 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
285 tcsr |= FSL_SAI_CSR_FRDE; 292 tcsr |= FSL_SAI_CSR_FRDE;
286 rcsr &= ~FSL_SAI_CSR_FRDE; 293 rcsr &= ~FSL_SAI_CSR_FRDE;
287 reg_cr3 = FSL_SAI_TCR3;
288 } else { 294 } else {
289 rcsr |= FSL_SAI_CSR_FRDE; 295 rcsr |= FSL_SAI_CSR_FRDE;
290 tcsr &= ~FSL_SAI_CSR_FRDE; 296 tcsr &= ~FSL_SAI_CSR_FRDE;
291 reg_cr3 = FSL_SAI_RCR3;
292 } 297 }
293 298
294 val_cr3 = sai_readl(sai, sai->base + reg_cr3); 299 /*
295 300 * It is recommended that the transmitter is the last enabled
301 * and the first disabled.
302 */
296 switch (cmd) { 303 switch (cmd) {
297 case SNDRV_PCM_TRIGGER_START: 304 case SNDRV_PCM_TRIGGER_START:
298 case SNDRV_PCM_TRIGGER_RESUME: 305 case SNDRV_PCM_TRIGGER_RESUME:
299 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 306 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
300 tcsr |= FSL_SAI_CSR_TERE; 307 tcsr |= FSL_SAI_CSR_TERE;
301 rcsr |= FSL_SAI_CSR_TERE; 308 rcsr |= FSL_SAI_CSR_TERE;
302 val_cr3 |= FSL_SAI_CR3_TRCE;
303 309
304 sai_writel(sai, val_cr3, sai->base + reg_cr3); 310 regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr);
305 sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR); 311 regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr);
306 sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR);
307 break; 312 break;
308
309 case SNDRV_PCM_TRIGGER_STOP: 313 case SNDRV_PCM_TRIGGER_STOP:
310 case SNDRV_PCM_TRIGGER_SUSPEND: 314 case SNDRV_PCM_TRIGGER_SUSPEND:
311 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 315 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -314,11 +318,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
314 rcsr &= ~FSL_SAI_CSR_TERE; 318 rcsr &= ~FSL_SAI_CSR_TERE;
315 } 319 }
316 320
317 val_cr3 &= ~FSL_SAI_CR3_TRCE; 321 regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr);
318 322 regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr);
319 sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR);
320 sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR);
321 sai_writel(sai, val_cr3, sai->base + reg_cr3);
322 break; 323 break;
323 default: 324 default:
324 return -EINVAL; 325 return -EINVAL;
@@ -331,16 +332,32 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
331 struct snd_soc_dai *cpu_dai) 332 struct snd_soc_dai *cpu_dai)
332{ 333{
333 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 334 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
335 u32 reg;
336
337 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
338 reg = FSL_SAI_TCR3;
339 else
340 reg = FSL_SAI_RCR3;
341
342 regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE,
343 FSL_SAI_CR3_TRCE);
334 344
335 return clk_prepare_enable(sai->clk); 345 return 0;
336} 346}
337 347
338static void fsl_sai_shutdown(struct snd_pcm_substream *substream, 348static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
339 struct snd_soc_dai *cpu_dai) 349 struct snd_soc_dai *cpu_dai)
340{ 350{
341 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 351 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
352 u32 reg;
353
354 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
355 reg = FSL_SAI_TCR3;
356 else
357 reg = FSL_SAI_RCR3;
342 358
343 clk_disable_unprepare(sai->clk); 359 regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE,
360 ~FSL_SAI_CR3_TRCE);
344} 361}
345 362
346static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { 363static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
@@ -355,18 +372,13 @@ static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
355static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) 372static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
356{ 373{
357 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); 374 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
358 int ret;
359 375
360 ret = clk_prepare_enable(sai->clk); 376 regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0);
361 if (ret) 377 regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0);
362 return ret; 378 regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
363 379 FSL_SAI_MAXBURST_TX * 2);
364 sai_writel(sai, 0x0, sai->base + FSL_SAI_RCSR); 380 regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
365 sai_writel(sai, 0x0, sai->base + FSL_SAI_TCSR); 381 FSL_SAI_MAXBURST_RX - 1);
366 sai_writel(sai, FSL_SAI_MAXBURST_TX * 2, sai->base + FSL_SAI_TCR1);
367 sai_writel(sai, FSL_SAI_MAXBURST_RX - 1, sai->base + FSL_SAI_RCR1);
368
369 clk_disable_unprepare(sai->clk);
370 382
371 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, 383 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
372 &sai->dma_params_rx); 384 &sai->dma_params_rx);
@@ -397,26 +409,109 @@ static const struct snd_soc_component_driver fsl_component = {
397 .name = "fsl-sai", 409 .name = "fsl-sai",
398}; 410};
399 411
412static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
413{
414 switch (reg) {
415 case FSL_SAI_TCSR:
416 case FSL_SAI_TCR1:
417 case FSL_SAI_TCR2:
418 case FSL_SAI_TCR3:
419 case FSL_SAI_TCR4:
420 case FSL_SAI_TCR5:
421 case FSL_SAI_TFR:
422 case FSL_SAI_TMR:
423 case FSL_SAI_RCSR:
424 case FSL_SAI_RCR1:
425 case FSL_SAI_RCR2:
426 case FSL_SAI_RCR3:
427 case FSL_SAI_RCR4:
428 case FSL_SAI_RCR5:
429 case FSL_SAI_RDR:
430 case FSL_SAI_RFR:
431 case FSL_SAI_RMR:
432 return true;
433 default:
434 return false;
435 }
436}
437
438static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
439{
440 switch (reg) {
441 case FSL_SAI_TFR:
442 case FSL_SAI_RFR:
443 case FSL_SAI_TDR:
444 case FSL_SAI_RDR:
445 return true;
446 default:
447 return false;
448 }
449
450}
451
452static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
453{
454 switch (reg) {
455 case FSL_SAI_TCSR:
456 case FSL_SAI_TCR1:
457 case FSL_SAI_TCR2:
458 case FSL_SAI_TCR3:
459 case FSL_SAI_TCR4:
460 case FSL_SAI_TCR5:
461 case FSL_SAI_TDR:
462 case FSL_SAI_TMR:
463 case FSL_SAI_RCSR:
464 case FSL_SAI_RCR1:
465 case FSL_SAI_RCR2:
466 case FSL_SAI_RCR3:
467 case FSL_SAI_RCR4:
468 case FSL_SAI_RCR5:
469 case FSL_SAI_RMR:
470 return true;
471 default:
472 return false;
473 }
474}
475
476static struct regmap_config fsl_sai_regmap_config = {
477 .reg_bits = 32,
478 .reg_stride = 4,
479 .val_bits = 32,
480
481 .max_register = FSL_SAI_RMR,
482 .readable_reg = fsl_sai_readable_reg,
483 .volatile_reg = fsl_sai_volatile_reg,
484 .writeable_reg = fsl_sai_writeable_reg,
485};
486
400static int fsl_sai_probe(struct platform_device *pdev) 487static int fsl_sai_probe(struct platform_device *pdev)
401{ 488{
402 struct device_node *np = pdev->dev.of_node; 489 struct device_node *np = pdev->dev.of_node;
403 struct fsl_sai *sai; 490 struct fsl_sai *sai;
404 struct resource *res; 491 struct resource *res;
492 void __iomem *base;
405 int ret; 493 int ret;
406 494
407 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); 495 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
408 if (!sai) 496 if (!sai)
409 return -ENOMEM; 497 return -ENOMEM;
410 498
499 sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
500 if (sai->big_endian_regs)
501 fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
502
503 sai->big_endian_data = of_property_read_bool(np, "big-endian-data");
504
411 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 505 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
412 sai->base = devm_ioremap_resource(&pdev->dev, res); 506 base = devm_ioremap_resource(&pdev->dev, res);
413 if (IS_ERR(sai->base)) 507 if (IS_ERR(base))
414 return PTR_ERR(sai->base); 508 return PTR_ERR(base);
415 509
416 sai->clk = devm_clk_get(&pdev->dev, "sai"); 510 sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
417 if (IS_ERR(sai->clk)) { 511 "sai", base, &fsl_sai_regmap_config);
418 dev_err(&pdev->dev, "Cannot get SAI's clock\n"); 512 if (IS_ERR(sai->regmap)) {
419 return PTR_ERR(sai->clk); 513 dev_err(&pdev->dev, "regmap init failed\n");
514 return PTR_ERR(sai->regmap);
420 } 515 }
421 516
422 sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; 517 sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
@@ -424,9 +519,6 @@ static int fsl_sai_probe(struct platform_device *pdev)
424 sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; 519 sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
425 sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; 520 sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;
426 521
427 sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
428 sai->big_endian_data = of_property_read_bool(np, "big-endian-data");
429
430 platform_set_drvdata(pdev, sai); 522 platform_set_drvdata(pdev, sai);
431 523
432 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, 524 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index 41bb62e69361..e432260be598 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -15,31 +15,36 @@
15 SNDRV_PCM_FMTBIT_S20_3LE |\ 15 SNDRV_PCM_FMTBIT_S20_3LE |\
16 SNDRV_PCM_FMTBIT_S24_LE) 16 SNDRV_PCM_FMTBIT_S24_LE)
17 17
18/* SAI Register Map Register */
19#define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */
20#define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */
21#define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */
22#define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */
23#define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */
24#define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */
25#define FSL_SAI_TDR 0x20 /* SAI Transmit Data */
26#define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */
27#define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */
28#define FSL_SAI_RCSR 0x80 /* SAI Receive Control */
29#define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */
30#define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */
31#define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */
32#define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */
33#define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */
34#define FSL_SAI_RDR 0xa0 /* SAI Receive Data */
35#define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */
36#define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */
37
18/* SAI Transmit/Recieve Control Register */ 38/* SAI Transmit/Recieve Control Register */
19#define FSL_SAI_TCSR 0x00
20#define FSL_SAI_RCSR 0x80
21#define FSL_SAI_CSR_TERE BIT(31) 39#define FSL_SAI_CSR_TERE BIT(31)
22#define FSL_SAI_CSR_FWF BIT(17) 40#define FSL_SAI_CSR_FWF BIT(17)
23#define FSL_SAI_CSR_FRIE BIT(8) 41#define FSL_SAI_CSR_FRIE BIT(8)
24#define FSL_SAI_CSR_FRDE BIT(0) 42#define FSL_SAI_CSR_FRDE BIT(0)
25 43
26/* SAI Transmit Data/FIFO/MASK Register */
27#define FSL_SAI_TDR 0x20
28#define FSL_SAI_TFR 0x40
29#define FSL_SAI_TMR 0x60
30
31/* SAI Recieve Data/FIFO/MASK Register */
32#define FSL_SAI_RDR 0xa0
33#define FSL_SAI_RFR 0xc0
34#define FSL_SAI_RMR 0xe0
35
36/* SAI Transmit and Recieve Configuration 1 Register */ 44/* SAI Transmit and Recieve Configuration 1 Register */
37#define FSL_SAI_TCR1 0x04 45#define FSL_SAI_CR1_RFW_MASK 0x1f
38#define FSL_SAI_RCR1 0x84
39 46
40/* SAI Transmit and Recieve Configuration 2 Register */ 47/* SAI Transmit and Recieve Configuration 2 Register */
41#define FSL_SAI_TCR2 0x08
42#define FSL_SAI_RCR2 0x88
43#define FSL_SAI_CR2_SYNC BIT(30) 48#define FSL_SAI_CR2_SYNC BIT(30)
44#define FSL_SAI_CR2_MSEL_MASK (0xff << 26) 49#define FSL_SAI_CR2_MSEL_MASK (0xff << 26)
45#define FSL_SAI_CR2_MSEL_BUS 0 50#define FSL_SAI_CR2_MSEL_BUS 0
@@ -50,15 +55,11 @@
50#define FSL_SAI_CR2_BCD_MSTR BIT(24) 55#define FSL_SAI_CR2_BCD_MSTR BIT(24)
51 56
52/* SAI Transmit and Recieve Configuration 3 Register */ 57/* SAI Transmit and Recieve Configuration 3 Register */
53#define FSL_SAI_TCR3 0x0c
54#define FSL_SAI_RCR3 0x8c
55#define FSL_SAI_CR3_TRCE BIT(16) 58#define FSL_SAI_CR3_TRCE BIT(16)
56#define FSL_SAI_CR3_WDFL(x) (x) 59#define FSL_SAI_CR3_WDFL(x) (x)
57#define FSL_SAI_CR3_WDFL_MASK 0x1f 60#define FSL_SAI_CR3_WDFL_MASK 0x1f
58 61
59/* SAI Transmit and Recieve Configuration 4 Register */ 62/* SAI Transmit and Recieve Configuration 4 Register */
60#define FSL_SAI_TCR4 0x10
61#define FSL_SAI_RCR4 0x90
62#define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16) 63#define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16)
63#define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16) 64#define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16)
64#define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8) 65#define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8)
@@ -69,8 +70,6 @@
69#define FSL_SAI_CR4_FSD_MSTR BIT(0) 70#define FSL_SAI_CR4_FSD_MSTR BIT(0)
70 71
71/* SAI Transmit and Recieve Configuration 5 Register */ 72/* SAI Transmit and Recieve Configuration 5 Register */
72#define FSL_SAI_TCR5 0x14
73#define FSL_SAI_RCR5 0x94
74#define FSL_SAI_CR5_WNW(x) (((x) - 1) << 24) 73#define FSL_SAI_CR5_WNW(x) (((x) - 1) << 24)
75#define FSL_SAI_CR5_WNW_MASK (0x1f << 24) 74#define FSL_SAI_CR5_WNW_MASK (0x1f << 24)
76#define FSL_SAI_CR5_W0W(x) (((x) - 1) << 16) 75#define FSL_SAI_CR5_W0W(x) (((x) - 1) << 16)
@@ -100,12 +99,11 @@
100#define FSL_SAI_MAXBURST_RX 6 99#define FSL_SAI_MAXBURST_RX 6
101 100
102struct fsl_sai { 101struct fsl_sai {
103 struct clk *clk; 102 struct regmap *regmap;
104
105 void __iomem *base;
106 103
107 bool big_endian_regs; 104 bool big_endian_regs;
108 bool big_endian_data; 105 bool big_endian_data;
106 bool is_dsp_mode;
109 107
110 struct snd_dmaengine_dai_dma_data dma_params_rx; 108 struct snd_dmaengine_dai_dma_data dma_params_rx;
111 struct snd_dmaengine_dai_dma_data dma_params_tx; 109 struct snd_dmaengine_dai_dma_data dma_params_tx;
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 4d075f1abe78..6452ca83d889 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -911,8 +911,8 @@ static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
911{ 911{
912 struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai); 912 struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai);
913 913
914 dai->playback_dma_data = &spdif_private->dma_params_tx; 914 snd_soc_dai_init_dma_data(dai, &spdif_private->dma_params_tx,
915 dai->capture_dma_data = &spdif_private->dma_params_rx; 915 &spdif_private->dma_params_rx);
916 916
917 snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls)); 917 snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls));
918 918
@@ -985,7 +985,7 @@ static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg)
985 } 985 }
986} 986}
987 987
988static const struct regmap_config fsl_spdif_regmap_config = { 988static struct regmap_config fsl_spdif_regmap_config = {
989 .reg_bits = 32, 989 .reg_bits = 32,
990 .reg_stride = 4, 990 .reg_stride = 4,
991 .val_bits = 32, 991 .val_bits = 32,
@@ -1105,6 +1105,9 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1105 memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai)); 1105 memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai));
1106 spdif_priv->cpu_dai_drv.name = spdif_priv->name; 1106 spdif_priv->cpu_dai_drv.name = spdif_priv->name;
1107 1107
1108 if (of_property_read_bool(np, "big-endian"))
1109 fsl_spdif_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
1110
1108 /* Get the addresses and IRQ */ 1111 /* Get the addresses and IRQ */
1109 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1112 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1110 regs = devm_ioremap_resource(&pdev->dev, res); 1113 regs = devm_ioremap_resource(&pdev->dev, res);
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
index 79cee782dbbf..a2fd7321b5a9 100644
--- a/sound/soc/fsl/imx-mc13783.c
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -160,7 +160,6 @@ static struct platform_driver imx_mc13783_audio_driver = {
160 .driver = { 160 .driver = {
161 .name = "imx_mc13783", 161 .name = "imx_mc13783",
162 .owner = THIS_MODULE, 162 .owner = THIS_MODULE,
163 .pm = &snd_soc_pm_ops,
164 }, 163 },
165 .probe = imx_mc13783_probe, 164 .probe = imx_mc13783_probe,
166 .remove = imx_mc13783_remove 165 .remove = imx_mc13783_remove
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 6553202dd48c..7abf6a079574 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -270,18 +270,17 @@ static int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
270 ret = imx_pcm_preallocate_dma_buffer(pcm, 270 ret = imx_pcm_preallocate_dma_buffer(pcm,
271 SNDRV_PCM_STREAM_PLAYBACK); 271 SNDRV_PCM_STREAM_PLAYBACK);
272 if (ret) 272 if (ret)
273 goto out; 273 return ret;
274 } 274 }
275 275
276 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { 276 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
277 ret = imx_pcm_preallocate_dma_buffer(pcm, 277 ret = imx_pcm_preallocate_dma_buffer(pcm,
278 SNDRV_PCM_STREAM_CAPTURE); 278 SNDRV_PCM_STREAM_CAPTURE);
279 if (ret) 279 if (ret)
280 goto out; 280 return ret;
281 } 281 }
282 282
283out: 283 return 0;
284 return ret;
285} 284}
286 285
287static int ssi_irq = 0; 286static int ssi_irq = 0;
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index f2beae78969f..1cb22dd034eb 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -33,8 +33,7 @@ struct imx_sgtl5000_data {
33 33
34static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd) 34static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd)
35{ 35{
36 struct imx_sgtl5000_data *data = container_of(rtd->card, 36 struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(rtd->card);
37 struct imx_sgtl5000_data, card);
38 struct device *dev = rtd->card->dev; 37 struct device *dev = rtd->card->dev;
39 int ret; 38 int ret;
40 39
@@ -159,13 +158,15 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
159 data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; 158 data->card.dapm_widgets = imx_sgtl5000_dapm_widgets;
160 data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); 159 data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets);
161 160
161 platform_set_drvdata(pdev, &data->card);
162 snd_soc_card_set_drvdata(&data->card, data);
163
162 ret = devm_snd_soc_register_card(&pdev->dev, &data->card); 164 ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
163 if (ret) { 165 if (ret) {
164 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); 166 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
165 goto fail; 167 goto fail;
166 } 168 }
167 169
168 platform_set_drvdata(pdev, data);
169 of_node_put(ssi_np); 170 of_node_put(ssi_np);
170 of_node_put(codec_np); 171 of_node_put(codec_np);
171 172
@@ -184,7 +185,8 @@ fail:
184 185
185static int imx_sgtl5000_remove(struct platform_device *pdev) 186static int imx_sgtl5000_remove(struct platform_device *pdev)
186{ 187{
187 struct imx_sgtl5000_data *data = platform_get_drvdata(pdev); 188 struct snd_soc_card *card = platform_get_drvdata(pdev);
189 struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(card);
188 190
189 clk_put(data->codec_clk); 191 clk_put(data->codec_clk);
190 192
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index 3fd76bc391de..3a3d17ce6ba4 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -71,7 +71,7 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
71{ 71{
72 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 72 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
73 struct imx_priv *priv = &card_priv; 73 struct imx_priv *priv = &card_priv;
74 struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev); 74 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
75 struct device *dev = &priv->pdev->dev; 75 struct device *dev = &priv->pdev->dev;
76 unsigned int pll_out; 76 unsigned int pll_out;
77 int ret; 77 int ret;
@@ -137,7 +137,7 @@ static int imx_wm8962_late_probe(struct snd_soc_card *card)
137{ 137{
138 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 138 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
139 struct imx_priv *priv = &card_priv; 139 struct imx_priv *priv = &card_priv;
140 struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev); 140 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
141 struct device *dev = &priv->pdev->dev; 141 struct device *dev = &priv->pdev->dev;
142 int ret; 142 int ret;
143 143
@@ -264,13 +264,15 @@ static int imx_wm8962_probe(struct platform_device *pdev)
264 data->card.late_probe = imx_wm8962_late_probe; 264 data->card.late_probe = imx_wm8962_late_probe;
265 data->card.set_bias_level = imx_wm8962_set_bias_level; 265 data->card.set_bias_level = imx_wm8962_set_bias_level;
266 266
267 platform_set_drvdata(pdev, &data->card);
268 snd_soc_card_set_drvdata(&data->card, data);
269
267 ret = devm_snd_soc_register_card(&pdev->dev, &data->card); 270 ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
268 if (ret) { 271 if (ret) {
269 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); 272 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
270 goto clk_fail; 273 goto clk_fail;
271 } 274 }
272 275
273 platform_set_drvdata(pdev, data);
274 of_node_put(ssi_np); 276 of_node_put(ssi_np);
275 of_node_put(codec_np); 277 of_node_put(codec_np);
276 278
@@ -289,7 +291,8 @@ fail:
289 291
290static int imx_wm8962_remove(struct platform_device *pdev) 292static int imx_wm8962_remove(struct platform_device *pdev)
291{ 293{
292 struct imx_wm8962_data *data = platform_get_drvdata(pdev); 294 struct snd_soc_card *card = platform_get_drvdata(pdev);
295 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
293 296
294 if (!IS_ERR(data->codec_clk)) 297 if (!IS_ERR(data->codec_clk))
295 clk_disable_unprepare(data->codec_clk); 298 clk_disable_unprepare(data->codec_clk);
diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c
index fce63252bdbb..804749a6c61e 100644
--- a/sound/soc/fsl/wm1133-ev1.c
+++ b/sound/soc/fsl/wm1133-ev1.c
@@ -214,12 +214,6 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
214 struct snd_soc_codec *codec = rtd->codec; 214 struct snd_soc_codec *codec = rtd->codec;
215 struct snd_soc_dapm_context *dapm = &codec->dapm; 215 struct snd_soc_dapm_context *dapm = &codec->dapm;
216 216
217 snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets,
218 ARRAY_SIZE(wm1133_ev1_widgets));
219
220 snd_soc_dapm_add_routes(dapm, wm1133_ev1_map,
221 ARRAY_SIZE(wm1133_ev1_map));
222
223 /* Headphone jack detection */ 217 /* Headphone jack detection */
224 snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack); 218 snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack);
225 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), 219 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
@@ -257,6 +251,11 @@ static struct snd_soc_card wm1133_ev1 = {
257 .owner = THIS_MODULE, 251 .owner = THIS_MODULE,
258 .dai_link = &wm1133_ev1_dai, 252 .dai_link = &wm1133_ev1_dai,
259 .num_links = 1, 253 .num_links = 1,
254
255 .dapm_widgets = wm1133_ev1_widgets,
256 .num_dapm_widgets = ARRAY_SIZE(wm1133_ev1_widgets),
257 .dapm_routes = wm1133_ev1_map,
258 .num_dapm_routes = ARRAY_SIZE(wm1133_ev1_map),
260}; 259};
261 260
262static struct platform_device *wm1133_ev1_snd_device; 261static struct platform_device *wm1133_ev1_snd_device;
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 61c10bf503d2..4577b69fcf2c 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -2,12 +2,50 @@ config SND_MFLD_MACHINE
2 tristate "SOC Machine Audio driver for Intel Medfield MID platform" 2 tristate "SOC Machine Audio driver for Intel Medfield MID platform"
3 depends on INTEL_SCU_IPC 3 depends on INTEL_SCU_IPC
4 select SND_SOC_SN95031 4 select SND_SOC_SN95031
5 select SND_SST_PLATFORM 5 select SND_SST_MFLD_PLATFORM
6 help 6 help
7 This adds support for ASoC machine driver for Intel(R) MID Medfield platform 7 This adds support for ASoC machine driver for Intel(R) MID Medfield platform
8 used as alsa device in audio substem in Intel(R) MID devices 8 used as alsa device in audio substem in Intel(R) MID devices
9 Say Y if you have such a device 9 Say Y if you have such a device
10 If unsure select "N". 10 If unsure select "N".
11 11
12config SND_SST_PLATFORM 12config SND_SST_MFLD_PLATFORM
13 tristate 13 tristate
14
15config SND_SOC_INTEL_SST
16 tristate "ASoC support for Intel(R) Smart Sound Technology"
17 select SND_SOC_INTEL_SST_ACPI if ACPI
18 depends on (X86 || COMPILE_TEST)
19 help
20 This adds support for Intel(R) Smart Sound Technology (SST).
21 Say Y if you have such a device
22 If unsure select "N".
23
24config SND_SOC_INTEL_SST_ACPI
25 tristate
26
27config SND_SOC_INTEL_HASWELL
28 tristate
29
30config SND_SOC_INTEL_BAYTRAIL
31 tristate
32
33config SND_SOC_INTEL_HASWELL_MACH
34 tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
35 depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS
36 select SND_SOC_INTEL_HASWELL
37 select SND_SOC_RT5640
38 help
39 This adds support for the Lynxpoint Audio DSP on Intel(R) Haswell
40 Ultrabook platforms.
41 Say Y if you have such a device
42 If unsure select "N".
43
44config SND_SOC_INTEL_BYT_RT5640_MACH
45 tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec"
46 depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS
47 select SND_SOC_INTEL_BAYTRAIL
48 select SND_SOC_RT5640
49 help
50 This adds audio driver for Intel Baytrail platform based boards
51 with the RT5640 audio codec.
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile
index 639883339465..edeb79ae3dff 100644
--- a/sound/soc/intel/Makefile
+++ b/sound/soc/intel/Makefile
@@ -1,5 +1,28 @@
1snd-soc-sst-platform-objs := sst_platform.o 1# Core support
2snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o
3snd-soc-sst-acpi-objs := sst-acpi.o
4
5snd-soc-sst-mfld-platform-objs := sst-mfld-platform.o
2snd-soc-mfld-machine-objs := mfld_machine.o 6snd-soc-mfld-machine-objs := mfld_machine.o
3 7
4obj-$(CONFIG_SND_SST_PLATFORM) += snd-soc-sst-platform.o 8obj-$(CONFIG_SND_SST_MFLD_PLATFORM) += snd-soc-sst-mfld-platform.o
5obj-$(CONFIG_SND_MFLD_MACHINE) += snd-soc-mfld-machine.o 9obj-$(CONFIG_SND_MFLD_MACHINE) += snd-soc-mfld-machine.o
10
11obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o
12obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
13
14# Platform Support
15snd-soc-sst-haswell-pcm-objs := \
16 sst-haswell-ipc.o sst-haswell-pcm.o sst-haswell-dsp.o
17snd-soc-sst-baytrail-pcm-objs := \
18 sst-baytrail-ipc.o sst-baytrail-pcm.o sst-baytrail-dsp.o
19
20obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += snd-soc-sst-haswell-pcm.o
21obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += snd-soc-sst-baytrail-pcm.o
22
23# Machine support
24snd-soc-sst-haswell-objs := haswell.o
25snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
26
27obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
28obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
diff --git a/sound/soc/intel/byt-rt5640.c b/sound/soc/intel/byt-rt5640.c
new file mode 100644
index 000000000000..eff97c8e5218
--- /dev/null
+++ b/sound/soc/intel/byt-rt5640.c
@@ -0,0 +1,187 @@
1/*
2 * Intel Baytrail SST RT5640 machine driver
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/acpi.h>
19#include <linux/device.h>
20#include <linux/slab.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <sound/jack.h>
25#include "../codecs/rt5640.h"
26
27#include "sst-dsp.h"
28
29static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
30 SND_SOC_DAPM_HP("Headphone", NULL),
31 SND_SOC_DAPM_MIC("Headset Mic", NULL),
32 SND_SOC_DAPM_MIC("Internal Mic", NULL),
33 SND_SOC_DAPM_SPK("Speaker", NULL),
34};
35
36static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
37 {"IN2P", NULL, "Headset Mic"},
38 {"IN2N", NULL, "Headset Mic"},
39 {"DMIC1", NULL, "Internal Mic"},
40 {"Headphone", NULL, "HPOL"},
41 {"Headphone", NULL, "HPOR"},
42 {"Speaker", NULL, "SPOLP"},
43 {"Speaker", NULL, "SPOLN"},
44 {"Speaker", NULL, "SPORP"},
45 {"Speaker", NULL, "SPORN"},
46};
47
48static const struct snd_kcontrol_new byt_rt5640_controls[] = {
49 SOC_DAPM_PIN_SWITCH("Headphone"),
50 SOC_DAPM_PIN_SWITCH("Headset Mic"),
51 SOC_DAPM_PIN_SWITCH("Internal Mic"),
52 SOC_DAPM_PIN_SWITCH("Speaker"),
53};
54
55static int byt_rt5640_hw_params(struct snd_pcm_substream *substream,
56 struct snd_pcm_hw_params *params)
57{
58 struct snd_soc_pcm_runtime *rtd = substream->private_data;
59 struct snd_soc_dai *codec_dai = rtd->codec_dai;
60 int ret;
61
62 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
63 params_rate(params) * 256,
64 SND_SOC_CLOCK_IN);
65 if (ret < 0) {
66 dev_err(codec_dai->dev, "can't set codec clock %d\n", ret);
67 return ret;
68 }
69 ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1,
70 params_rate(params) * 64,
71 params_rate(params) * 256);
72 if (ret < 0) {
73 dev_err(codec_dai->dev, "can't set codec pll: %d\n", ret);
74 return ret;
75 }
76 return 0;
77}
78
79static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
80{
81 int ret;
82 struct snd_soc_codec *codec = runtime->codec;
83 struct snd_soc_dapm_context *dapm = &codec->dapm;
84 struct snd_soc_card *card = runtime->card;
85
86 card->dapm.idle_bias_off = true;
87
88 ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
89 ARRAY_SIZE(byt_rt5640_controls));
90 if (ret) {
91 dev_err(card->dev, "unable to add card controls\n");
92 return ret;
93 }
94
95 snd_soc_dapm_ignore_suspend(dapm, "HPOL");
96 snd_soc_dapm_ignore_suspend(dapm, "HPOR");
97
98 snd_soc_dapm_ignore_suspend(dapm, "SPOLP");
99 snd_soc_dapm_ignore_suspend(dapm, "SPOLN");
100 snd_soc_dapm_ignore_suspend(dapm, "SPORP");
101 snd_soc_dapm_ignore_suspend(dapm, "SPORN");
102
103 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
104 snd_soc_dapm_enable_pin(dapm, "Headphone");
105 snd_soc_dapm_enable_pin(dapm, "Speaker");
106 snd_soc_dapm_enable_pin(dapm, "Internal Mic");
107
108 snd_soc_dapm_sync(dapm);
109 return ret;
110}
111
112static struct snd_soc_ops byt_rt5640_ops = {
113 .hw_params = byt_rt5640_hw_params,
114};
115
116static struct snd_soc_dai_link byt_rt5640_dais[] = {
117 {
118 .name = "Baytrail Audio",
119 .stream_name = "Audio",
120 .cpu_dai_name = "Front-cpu-dai",
121 .codec_dai_name = "rt5640-aif1",
122 .codec_name = "i2c-10EC5640:00",
123 .platform_name = "baytrail-pcm-audio",
124 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
125 SND_SOC_DAIFMT_CBS_CFS,
126 .init = byt_rt5640_init,
127 .ignore_suspend = 1,
128 .ops = &byt_rt5640_ops,
129 },
130 {
131 .name = "Baytrail Voice",
132 .stream_name = "Voice",
133 .cpu_dai_name = "Mic1-cpu-dai",
134 .codec_dai_name = "rt5640-aif1",
135 .codec_name = "i2c-10EC5640:00",
136 .platform_name = "baytrail-pcm-audio",
137 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
138 SND_SOC_DAIFMT_CBS_CFS,
139 .init = NULL,
140 .ignore_suspend = 1,
141 .ops = &byt_rt5640_ops,
142 },
143};
144
145static struct snd_soc_card byt_rt5640_card = {
146 .name = "byt-rt5640",
147 .dai_link = byt_rt5640_dais,
148 .num_links = ARRAY_SIZE(byt_rt5640_dais),
149 .dapm_widgets = byt_rt5640_widgets,
150 .num_dapm_widgets = ARRAY_SIZE(byt_rt5640_widgets),
151 .dapm_routes = byt_rt5640_audio_map,
152 .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
153};
154
155static int byt_rt5640_probe(struct platform_device *pdev)
156{
157 struct snd_soc_card *card = &byt_rt5640_card;
158 struct device *dev = &pdev->dev;
159
160 card->dev = &pdev->dev;
161 dev_set_drvdata(dev, card);
162 return snd_soc_register_card(card);
163}
164
165static int byt_rt5640_remove(struct platform_device *pdev)
166{
167 struct snd_soc_card *card = platform_get_drvdata(pdev);
168
169 snd_soc_unregister_card(card);
170
171 return 0;
172}
173
174static struct platform_driver byt_rt5640_audio = {
175 .probe = byt_rt5640_probe,
176 .remove = byt_rt5640_remove,
177 .driver = {
178 .name = "byt-rt5640",
179 .owner = THIS_MODULE,
180 },
181};
182module_platform_driver(byt_rt5640_audio)
183
184MODULE_DESCRIPTION("ASoC Intel(R) Baytrail Machine driver");
185MODULE_AUTHOR("Omair Md Abdullah, Jarkko Nikula");
186MODULE_LICENSE("GPL v2");
187MODULE_ALIAS("platform:byt-rt5640");
diff --git a/sound/soc/intel/haswell.c b/sound/soc/intel/haswell.c
new file mode 100644
index 000000000000..54345a2a7386
--- /dev/null
+++ b/sound/soc/intel/haswell.c
@@ -0,0 +1,235 @@
1/*
2 * Intel Haswell Lynxpoint SST Audio
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/pcm_params.h>
23
24#include "sst-dsp.h"
25#include "sst-haswell-ipc.h"
26
27#include "../codecs/rt5640.h"
28
29/* Haswell ULT platforms have a Headphone and Mic jack */
30static const struct snd_soc_dapm_widget haswell_widgets[] = {
31 SND_SOC_DAPM_HP("Headphones", NULL),
32 SND_SOC_DAPM_MIC("Mic", NULL),
33};
34
35static const struct snd_soc_dapm_route haswell_rt5640_map[] = {
36
37 {"Headphones", NULL, "HPOR"},
38 {"Headphones", NULL, "HPOL"},
39 {"IN2P", NULL, "Mic"},
40
41 /* CODEC BE connections */
42 {"SSP0 CODEC IN", NULL, "AIF1 Capture"},
43 {"AIF1 Playback", NULL, "SSP0 CODEC OUT"},
44};
45
46static int haswell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
47 struct snd_pcm_hw_params *params)
48{
49 struct snd_interval *rate = hw_param_interval(params,
50 SNDRV_PCM_HW_PARAM_RATE);
51 struct snd_interval *channels = hw_param_interval(params,
52 SNDRV_PCM_HW_PARAM_CHANNELS);
53
54 /* The ADSP will covert the FE rate to 48k, stereo */
55 rate->min = rate->max = 48000;
56 channels->min = channels->max = 2;
57
58 /* set SSP0 to 16 bit */
59 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT -
60 SNDRV_PCM_HW_PARAM_FIRST_MASK],
61 SNDRV_PCM_FORMAT_S16_LE);
62 return 0;
63}
64
65static int haswell_rt5640_hw_params(struct snd_pcm_substream *substream,
66 struct snd_pcm_hw_params *params)
67{
68 struct snd_soc_pcm_runtime *rtd = substream->private_data;
69 struct snd_soc_dai *codec_dai = rtd->codec_dai;
70 int ret;
71
72 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK, 12288000,
73 SND_SOC_CLOCK_IN);
74
75 if (ret < 0) {
76 dev_err(rtd->dev, "can't set codec sysclk configuration\n");
77 return ret;
78 }
79
80 /* set correct codec filter for DAI format and clock config */
81 snd_soc_update_bits(rtd->codec, 0x83, 0xffff, 0x8000);
82
83 return ret;
84}
85
86static struct snd_soc_ops haswell_rt5640_ops = {
87 .hw_params = haswell_rt5640_hw_params,
88};
89
90static int haswell_rtd_init(struct snd_soc_pcm_runtime *rtd)
91{
92 struct snd_soc_codec *codec = rtd->codec;
93 struct snd_soc_dapm_context *dapm = &codec->dapm;
94 struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
95 struct sst_hsw *haswell = pdata->dsp;
96 int ret;
97
98 /* Set ADSP SSP port settings */
99 ret = sst_hsw_device_set_config(haswell, SST_HSW_DEVICE_SSP_0,
100 SST_HSW_DEVICE_MCLK_FREQ_24_MHZ,
101 SST_HSW_DEVICE_CLOCK_MASTER, 9);
102 if (ret < 0) {
103 dev_err(rtd->dev, "failed to set device config\n");
104 return ret;
105 }
106
107 /* always connected */
108 snd_soc_dapm_enable_pin(dapm, "Headphones");
109 snd_soc_dapm_enable_pin(dapm, "Mic");
110
111 return 0;
112}
113
114static struct snd_soc_dai_link haswell_rt5640_dais[] = {
115 /* Front End DAI links */
116 {
117 .name = "System",
118 .stream_name = "System Playback",
119 .cpu_dai_name = "System Pin",
120 .platform_name = "haswell-pcm-audio",
121 .dynamic = 1,
122 .codec_name = "snd-soc-dummy",
123 .codec_dai_name = "snd-soc-dummy-dai",
124 .init = haswell_rtd_init,
125 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
126 .dpcm_playback = 1,
127 },
128 {
129 .name = "Offload0",
130 .stream_name = "Offload0 Playback",
131 .cpu_dai_name = "Offload0 Pin",
132 .platform_name = "haswell-pcm-audio",
133 .dynamic = 1,
134 .codec_name = "snd-soc-dummy",
135 .codec_dai_name = "snd-soc-dummy-dai",
136 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
137 .dpcm_playback = 1,
138 },
139 {
140 .name = "Offload1",
141 .stream_name = "Offload1 Playback",
142 .cpu_dai_name = "Offload1 Pin",
143 .platform_name = "haswell-pcm-audio",
144 .dynamic = 1,
145 .codec_name = "snd-soc-dummy",
146 .codec_dai_name = "snd-soc-dummy-dai",
147 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
148 .dpcm_playback = 1,
149 },
150 {
151 .name = "Loopback",
152 .stream_name = "Loopback",
153 .cpu_dai_name = "Loopback Pin",
154 .platform_name = "haswell-pcm-audio",
155 .dynamic = 0,
156 .codec_name = "snd-soc-dummy",
157 .codec_dai_name = "snd-soc-dummy-dai",
158 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
159 .dpcm_capture = 1,
160 },
161 {
162 .name = "Capture",
163 .stream_name = "Capture",
164 .cpu_dai_name = "Capture Pin",
165 .platform_name = "haswell-pcm-audio",
166 .dynamic = 1,
167 .codec_name = "snd-soc-dummy",
168 .codec_dai_name = "snd-soc-dummy-dai",
169 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
170 .dpcm_capture = 1,
171 },
172
173 /* Back End DAI links */
174 {
175 /* SSP0 - Codec */
176 .name = "Codec",
177 .be_id = 0,
178 .cpu_dai_name = "snd-soc-dummy-dai",
179 .platform_name = "snd-soc-dummy",
180 .no_pcm = 1,
181 .codec_name = "i2c-INT33CA:00",
182 .codec_dai_name = "rt5640-aif1",
183 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
184 SND_SOC_DAIFMT_CBS_CFS,
185 .ignore_suspend = 1,
186 .ignore_pmdown_time = 1,
187 .be_hw_params_fixup = haswell_ssp0_fixup,
188 .ops = &haswell_rt5640_ops,
189 .dpcm_playback = 1,
190 .dpcm_capture = 1,
191 },
192};
193
194/* audio machine driver for Haswell Lynxpoint DSP + RT5640 */
195static struct snd_soc_card haswell_rt5640 = {
196 .name = "haswell-rt5640",
197 .owner = THIS_MODULE,
198 .dai_link = haswell_rt5640_dais,
199 .num_links = ARRAY_SIZE(haswell_rt5640_dais),
200 .dapm_widgets = haswell_widgets,
201 .num_dapm_widgets = ARRAY_SIZE(haswell_widgets),
202 .dapm_routes = haswell_rt5640_map,
203 .num_dapm_routes = ARRAY_SIZE(haswell_rt5640_map),
204 .fully_routed = true,
205};
206
207static int haswell_audio_probe(struct platform_device *pdev)
208{
209 haswell_rt5640.dev = &pdev->dev;
210
211 return snd_soc_register_card(&haswell_rt5640);
212}
213
214static int haswell_audio_remove(struct platform_device *pdev)
215{
216 snd_soc_unregister_card(&haswell_rt5640);
217 return 0;
218}
219
220static struct platform_driver haswell_audio = {
221 .probe = haswell_audio_probe,
222 .remove = haswell_audio_remove,
223 .driver = {
224 .name = "haswell-audio",
225 .owner = THIS_MODULE,
226 },
227};
228
229module_platform_driver(haswell_audio)
230
231/* Module information */
232MODULE_AUTHOR("Liam Girdwood, Xingchao Wang");
233MODULE_DESCRIPTION("Intel SST Audio for Haswell Lynxpoint");
234MODULE_LICENSE("GPL v2");
235MODULE_ALIAS("platform:haswell-audio");
diff --git a/sound/soc/intel/mfld_machine.c b/sound/soc/intel/mfld_machine.c
index d3d4c32434f7..0cef32e9d402 100644
--- a/sound/soc/intel/mfld_machine.c
+++ b/sound/soc/intel/mfld_machine.c
@@ -101,20 +101,27 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol,
101 struct snd_ctl_elem_value *ucontrol) 101 struct snd_ctl_elem_value *ucontrol)
102{ 102{
103 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 103 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
104 struct snd_soc_dapm_context *dapm = &codec->dapm;
104 105
105 if (ucontrol->value.integer.value[0] == hs_switch) 106 if (ucontrol->value.integer.value[0] == hs_switch)
106 return 0; 107 return 0;
107 108
109 snd_soc_dapm_mutex_lock(dapm);
110
108 if (ucontrol->value.integer.value[0]) { 111 if (ucontrol->value.integer.value[0]) {
109 pr_debug("hs_set HS path\n"); 112 pr_debug("hs_set HS path\n");
110 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones"); 113 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones");
111 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 114 snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
112 } else { 115 } else {
113 pr_debug("hs_set EP path\n"); 116 pr_debug("hs_set EP path\n");
114 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); 117 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
115 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); 118 snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT");
116 } 119 }
117 snd_soc_dapm_sync(&codec->dapm); 120
121 snd_soc_dapm_sync_unlocked(dapm);
122
123 snd_soc_dapm_mutex_unlock(dapm);
124
118 hs_switch = ucontrol->value.integer.value[0]; 125 hs_switch = ucontrol->value.integer.value[0];
119 126
120 return 0; 127 return 0;
@@ -122,18 +129,20 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol,
122 129
123static void lo_enable_out_pins(struct snd_soc_codec *codec) 130static void lo_enable_out_pins(struct snd_soc_codec *codec)
124{ 131{
125 snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTL"); 132 struct snd_soc_dapm_context *dapm = &codec->dapm;
126 snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTR"); 133
127 snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTL"); 134 snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTL");
128 snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTR"); 135 snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTR");
129 snd_soc_dapm_enable_pin(&codec->dapm, "VIB1OUT"); 136 snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTL");
130 snd_soc_dapm_enable_pin(&codec->dapm, "VIB2OUT"); 137 snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTR");
138 snd_soc_dapm_enable_pin_unlocked(dapm, "VIB1OUT");
139 snd_soc_dapm_enable_pin_unlocked(dapm, "VIB2OUT");
131 if (hs_switch) { 140 if (hs_switch) {
132 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones"); 141 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones");
133 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 142 snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
134 } else { 143 } else {
135 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); 144 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
136 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); 145 snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT");
137 } 146 }
138} 147}
139 148
@@ -148,44 +157,52 @@ static int lo_set_switch(struct snd_kcontrol *kcontrol,
148 struct snd_ctl_elem_value *ucontrol) 157 struct snd_ctl_elem_value *ucontrol)
149{ 158{
150 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 159 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
160 struct snd_soc_dapm_context *dapm = &codec->dapm;
151 161
152 if (ucontrol->value.integer.value[0] == lo_dac) 162 if (ucontrol->value.integer.value[0] == lo_dac)
153 return 0; 163 return 0;
154 164
165 snd_soc_dapm_mutex_lock(dapm);
166
155 /* we dont want to work with last state of lineout so just enable all 167 /* we dont want to work with last state of lineout so just enable all
156 * pins and then disable pins not required 168 * pins and then disable pins not required
157 */ 169 */
158 lo_enable_out_pins(codec); 170 lo_enable_out_pins(codec);
171
159 switch (ucontrol->value.integer.value[0]) { 172 switch (ucontrol->value.integer.value[0]) {
160 case 0: 173 case 0:
161 pr_debug("set vibra path\n"); 174 pr_debug("set vibra path\n");
162 snd_soc_dapm_disable_pin(&codec->dapm, "VIB1OUT"); 175 snd_soc_dapm_disable_pin_unlocked(dapm, "VIB1OUT");
163 snd_soc_dapm_disable_pin(&codec->dapm, "VIB2OUT"); 176 snd_soc_dapm_disable_pin_unlocked(dapm, "VIB2OUT");
164 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0); 177 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0);
165 break; 178 break;
166 179
167 case 1: 180 case 1:
168 pr_debug("set hs path\n"); 181 pr_debug("set hs path\n");
169 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); 182 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
170 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 183 snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
171 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22); 184 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22);
172 break; 185 break;
173 186
174 case 2: 187 case 2:
175 pr_debug("set spkr path\n"); 188 pr_debug("set spkr path\n");
176 snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTL"); 189 snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTL");
177 snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTR"); 190 snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTR");
178 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44); 191 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44);
179 break; 192 break;
180 193
181 case 3: 194 case 3:
182 pr_debug("set null path\n"); 195 pr_debug("set null path\n");
183 snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTL"); 196 snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTL");
184 snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTR"); 197 snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTR");
185 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66); 198 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66);
186 break; 199 break;
187 } 200 }
188 snd_soc_dapm_sync(&codec->dapm); 201
202 snd_soc_dapm_sync_unlocked(dapm);
203
204 snd_soc_dapm_mutex_unlock(dapm);
205
189 lo_dac = ucontrol->value.integer.value[0]; 206 lo_dac = ucontrol->value.integer.value[0];
190 return 0; 207 return 0;
191} 208}
diff --git a/sound/soc/intel/sst-acpi.c b/sound/soc/intel/sst-acpi.c
new file mode 100644
index 000000000000..5d06eecb6198
--- /dev/null
+++ b/sound/soc/intel/sst-acpi.c
@@ -0,0 +1,284 @@
1/*
2 * Intel SST loader on ACPI systems
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/acpi.h>
18#include <linux/device.h>
19#include <linux/firmware.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22
23#include "sst-dsp.h"
24
25#define SST_LPT_DSP_DMA_ADDR_OFFSET 0x0F0000
26#define SST_WPT_DSP_DMA_ADDR_OFFSET 0x0FE000
27#define SST_LPT_DSP_DMA_SIZE (1024 - 1)
28
29/* Descriptor for SST ASoC machine driver */
30struct sst_acpi_mach {
31 /* ACPI ID for the matching machine driver. Audio codec for instance */
32 const u8 id[ACPI_ID_LEN];
33 /* machine driver name */
34 const char *drv_name;
35 /* firmware file name */
36 const char *fw_filename;
37};
38
39/* Descriptor for setting up SST platform data */
40struct sst_acpi_desc {
41 const char *drv_name;
42 struct sst_acpi_mach *machines;
43 /* Platform resource indexes. Must set to -1 if not used */
44 int resindex_lpe_base;
45 int resindex_pcicfg_base;
46 int resindex_fw_base;
47 int irqindex_host_ipc;
48 int resindex_dma_base;
49 /* Unique number identifying the SST core on platform */
50 int sst_id;
51 /* DMA only valid when resindex_dma_base != -1*/
52 int dma_engine;
53 int dma_size;
54};
55
56struct sst_acpi_priv {
57 struct platform_device *pdev_mach;
58 struct platform_device *pdev_pcm;
59 struct sst_pdata sst_pdata;
60 struct sst_acpi_desc *desc;
61 struct sst_acpi_mach *mach;
62};
63
64static void sst_acpi_fw_cb(const struct firmware *fw, void *context)
65{
66 struct platform_device *pdev = context;
67 struct device *dev = &pdev->dev;
68 struct sst_acpi_priv *sst_acpi = platform_get_drvdata(pdev);
69 struct sst_pdata *sst_pdata = &sst_acpi->sst_pdata;
70 struct sst_acpi_desc *desc = sst_acpi->desc;
71 struct sst_acpi_mach *mach = sst_acpi->mach;
72
73 sst_pdata->fw = fw;
74 if (!fw) {
75 dev_err(dev, "Cannot load firmware %s\n", mach->fw_filename);
76 return;
77 }
78
79 /* register PCM and DAI driver */
80 sst_acpi->pdev_pcm =
81 platform_device_register_data(dev, desc->drv_name, -1,
82 sst_pdata, sizeof(*sst_pdata));
83 if (IS_ERR(sst_acpi->pdev_pcm)) {
84 dev_err(dev, "Cannot register device %s. Error %d\n",
85 desc->drv_name, (int)PTR_ERR(sst_acpi->pdev_pcm));
86 }
87
88 return;
89}
90
91static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
92 void *context, void **ret)
93{
94 *(bool *)context = true;
95 return AE_OK;
96}
97
98static struct sst_acpi_mach *sst_acpi_find_machine(
99 struct sst_acpi_mach *machines)
100{
101 struct sst_acpi_mach *mach;
102 bool found = false;
103
104 for (mach = machines; mach->id[0]; mach++)
105 if (ACPI_SUCCESS(acpi_get_devices(mach->id,
106 sst_acpi_mach_match,
107 &found, NULL)) && found)
108 return mach;
109
110 return NULL;
111}
112
113static int sst_acpi_probe(struct platform_device *pdev)
114{
115 const struct acpi_device_id *id;
116 struct device *dev = &pdev->dev;
117 struct sst_acpi_priv *sst_acpi;
118 struct sst_pdata *sst_pdata;
119 struct sst_acpi_mach *mach;
120 struct sst_acpi_desc *desc;
121 struct resource *mmio;
122 int ret = 0;
123
124 sst_acpi = devm_kzalloc(dev, sizeof(*sst_acpi), GFP_KERNEL);
125 if (sst_acpi == NULL)
126 return -ENOMEM;
127
128 id = acpi_match_device(dev->driver->acpi_match_table, dev);
129 if (!id)
130 return -ENODEV;
131
132 desc = (struct sst_acpi_desc *)id->driver_data;
133 mach = sst_acpi_find_machine(desc->machines);
134 if (mach == NULL) {
135 dev_err(dev, "No matching ASoC machine driver found\n");
136 return -ENODEV;
137 }
138
139 sst_pdata = &sst_acpi->sst_pdata;
140 sst_pdata->id = desc->sst_id;
141 sst_acpi->desc = desc;
142 sst_acpi->mach = mach;
143
144 if (desc->resindex_dma_base >= 0) {
145 sst_pdata->dma_engine = desc->dma_engine;
146 sst_pdata->dma_base = desc->resindex_dma_base;
147 sst_pdata->dma_size = desc->dma_size;
148 }
149
150 if (desc->irqindex_host_ipc >= 0)
151 sst_pdata->irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
152
153 if (desc->resindex_lpe_base >= 0) {
154 mmio = platform_get_resource(pdev, IORESOURCE_MEM,
155 desc->resindex_lpe_base);
156 if (mmio) {
157 sst_pdata->lpe_base = mmio->start;
158 sst_pdata->lpe_size = resource_size(mmio);
159 }
160 }
161
162 if (desc->resindex_pcicfg_base >= 0) {
163 mmio = platform_get_resource(pdev, IORESOURCE_MEM,
164 desc->resindex_pcicfg_base);
165 if (mmio) {
166 sst_pdata->pcicfg_base = mmio->start;
167 sst_pdata->pcicfg_size = resource_size(mmio);
168 }
169 }
170
171 if (desc->resindex_fw_base >= 0) {
172 mmio = platform_get_resource(pdev, IORESOURCE_MEM,
173 desc->resindex_fw_base);
174 if (mmio) {
175 sst_pdata->fw_base = mmio->start;
176 sst_pdata->fw_size = resource_size(mmio);
177 }
178 }
179
180 platform_set_drvdata(pdev, sst_acpi);
181
182 /* register machine driver */
183 sst_acpi->pdev_mach =
184 platform_device_register_data(dev, mach->drv_name, -1,
185 sst_pdata, sizeof(*sst_pdata));
186 if (IS_ERR(sst_acpi->pdev_mach))
187 return PTR_ERR(sst_acpi->pdev_mach);
188
189 /* continue SST probing after firmware is loaded */
190 ret = request_firmware_nowait(THIS_MODULE, true, mach->fw_filename,
191 dev, GFP_KERNEL, pdev, sst_acpi_fw_cb);
192 if (ret)
193 platform_device_unregister(sst_acpi->pdev_mach);
194
195 return ret;
196}
197
198static int sst_acpi_remove(struct platform_device *pdev)
199{
200 struct sst_acpi_priv *sst_acpi = platform_get_drvdata(pdev);
201 struct sst_pdata *sst_pdata = &sst_acpi->sst_pdata;
202
203 platform_device_unregister(sst_acpi->pdev_mach);
204 if (!IS_ERR_OR_NULL(sst_acpi->pdev_pcm))
205 platform_device_unregister(sst_acpi->pdev_pcm);
206 release_firmware(sst_pdata->fw);
207
208 return 0;
209}
210
211static struct sst_acpi_mach haswell_machines[] = {
212 { "INT33CA", "haswell-audio", "intel/IntcSST1.bin" },
213 {}
214};
215
216static struct sst_acpi_desc sst_acpi_haswell_desc = {
217 .drv_name = "haswell-pcm-audio",
218 .machines = haswell_machines,
219 .resindex_lpe_base = 0,
220 .resindex_pcicfg_base = 1,
221 .resindex_fw_base = -1,
222 .irqindex_host_ipc = 0,
223 .sst_id = SST_DEV_ID_LYNX_POINT,
224 .dma_engine = SST_DMA_TYPE_DW,
225 .resindex_dma_base = SST_LPT_DSP_DMA_ADDR_OFFSET,
226 .dma_size = SST_LPT_DSP_DMA_SIZE,
227};
228
229static struct sst_acpi_mach broadwell_machines[] = {
230 { "INT343A", "broadwell-audio", "intel/IntcSST2.bin" },
231 {}
232};
233
234static struct sst_acpi_desc sst_acpi_broadwell_desc = {
235 .drv_name = "haswell-pcm-audio",
236 .machines = broadwell_machines,
237 .resindex_lpe_base = 0,
238 .resindex_pcicfg_base = 1,
239 .resindex_fw_base = -1,
240 .irqindex_host_ipc = 0,
241 .sst_id = SST_DEV_ID_WILDCAT_POINT,
242 .dma_engine = SST_DMA_TYPE_DW,
243 .resindex_dma_base = SST_WPT_DSP_DMA_ADDR_OFFSET,
244 .dma_size = SST_LPT_DSP_DMA_SIZE,
245};
246
247static struct sst_acpi_mach baytrail_machines[] = {
248 { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-i2s_master" },
249 {}
250};
251
252static struct sst_acpi_desc sst_acpi_baytrail_desc = {
253 .drv_name = "baytrail-pcm-audio",
254 .machines = baytrail_machines,
255 .resindex_lpe_base = 0,
256 .resindex_pcicfg_base = 1,
257 .resindex_fw_base = 2,
258 .irqindex_host_ipc = 5,
259 .sst_id = SST_DEV_ID_BYT,
260 .resindex_dma_base = -1,
261};
262
263static struct acpi_device_id sst_acpi_match[] = {
264 { "INT33C8", (unsigned long)&sst_acpi_haswell_desc },
265 { "INT3438", (unsigned long)&sst_acpi_broadwell_desc },
266 { "80860F28", (unsigned long)&sst_acpi_baytrail_desc },
267 { }
268};
269MODULE_DEVICE_TABLE(acpi, sst_acpi_match);
270
271static struct platform_driver sst_acpi_driver = {
272 .probe = sst_acpi_probe,
273 .remove = sst_acpi_remove,
274 .driver = {
275 .name = "sst-acpi",
276 .owner = THIS_MODULE,
277 .acpi_match_table = ACPI_PTR(sst_acpi_match),
278 },
279};
280module_platform_driver(sst_acpi_driver);
281
282MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>");
283MODULE_DESCRIPTION("Intel SST loader on ACPI systems");
284MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/intel/sst-baytrail-dsp.c b/sound/soc/intel/sst-baytrail-dsp.c
new file mode 100644
index 000000000000..a50bf7fc0e3a
--- /dev/null
+++ b/sound/soc/intel/sst-baytrail-dsp.c
@@ -0,0 +1,372 @@
1/*
2 * Intel Baytrail SST DSP driver
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/delay.h>
16#include <linux/fs.h>
17#include <linux/slab.h>
18#include <linux/device.h>
19#include <linux/interrupt.h>
20#include <linux/module.h>
21#include <linux/dma-mapping.h>
22#include <linux/platform_device.h>
23#include <linux/firmware.h>
24
25#include "sst-dsp.h"
26#include "sst-dsp-priv.h"
27#include "sst-baytrail-ipc.h"
28
29#define SST_BYT_FW_SIGNATURE_SIZE 4
30#define SST_BYT_FW_SIGN "$SST"
31
32#define SST_BYT_IRAM_OFFSET 0xC0000
33#define SST_BYT_DRAM_OFFSET 0x100000
34#define SST_BYT_SHIM_OFFSET 0x140000
35
36enum sst_ram_type {
37 SST_BYT_IRAM = 1,
38 SST_BYT_DRAM = 2,
39 SST_BYT_CACHE = 3,
40};
41
42struct dma_block_info {
43 enum sst_ram_type type; /* IRAM/DRAM */
44 u32 size; /* Bytes */
45 u32 ram_offset; /* Offset in I/DRAM */
46 u32 rsvd; /* Reserved field */
47};
48
49struct fw_header {
50 unsigned char signature[SST_BYT_FW_SIGNATURE_SIZE];
51 u32 file_size; /* size of fw minus this header */
52 u32 modules; /* # of modules */
53 u32 file_format; /* version of header format */
54 u32 reserved[4];
55};
56
57struct sst_byt_fw_module_header {
58 unsigned char signature[SST_BYT_FW_SIGNATURE_SIZE];
59 u32 mod_size; /* size of module */
60 u32 blocks; /* # of blocks */
61 u32 type; /* codec type, pp lib */
62 u32 entry_point;
63};
64
65static int sst_byt_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
66 struct sst_byt_fw_module_header *module)
67{
68 struct dma_block_info *block;
69 struct sst_module *mod;
70 struct sst_module_data block_data;
71 struct sst_module_template template;
72 int count;
73
74 memset(&template, 0, sizeof(template));
75 template.id = module->type;
76 template.entry = module->entry_point;
77 template.p.type = SST_MEM_DRAM;
78 template.p.data_type = SST_DATA_P;
79 template.s.type = SST_MEM_DRAM;
80 template.s.data_type = SST_DATA_S;
81
82 mod = sst_module_new(fw, &template, NULL);
83 if (mod == NULL)
84 return -ENOMEM;
85
86 block = (void *)module + sizeof(*module);
87
88 for (count = 0; count < module->blocks; count++) {
89
90 if (block->size <= 0) {
91 dev_err(dsp->dev, "block %d size invalid\n", count);
92 return -EINVAL;
93 }
94
95 switch (block->type) {
96 case SST_BYT_IRAM:
97 block_data.offset = block->ram_offset +
98 dsp->addr.iram_offset;
99 block_data.type = SST_MEM_IRAM;
100 break;
101 case SST_BYT_DRAM:
102 block_data.offset = block->ram_offset +
103 dsp->addr.dram_offset;
104 block_data.type = SST_MEM_DRAM;
105 break;
106 case SST_BYT_CACHE:
107 block_data.offset = block->ram_offset +
108 (dsp->addr.fw_ext - dsp->addr.lpe);
109 block_data.type = SST_MEM_CACHE;
110 break;
111 default:
112 dev_err(dsp->dev, "wrong ram type 0x%x in block0x%x\n",
113 block->type, count);
114 return -EINVAL;
115 }
116
117 block_data.size = block->size;
118 block_data.data_type = SST_DATA_M;
119 block_data.data = (void *)block + sizeof(*block);
120
121 sst_module_insert_fixed_block(mod, &block_data);
122
123 block = (void *)block + sizeof(*block) + block->size;
124 }
125 return 0;
126}
127
128static int sst_byt_parse_fw_image(struct sst_fw *sst_fw)
129{
130 struct fw_header *header;
131 struct sst_byt_fw_module_header *module;
132 struct sst_dsp *dsp = sst_fw->dsp;
133 int ret, count;
134
135 /* Read the header information from the data pointer */
136 header = (struct fw_header *)sst_fw->dma_buf;
137
138 /* verify FW */
139 if ((strncmp(header->signature, SST_BYT_FW_SIGN, 4) != 0) ||
140 (sst_fw->size != header->file_size + sizeof(*header))) {
141 /* Invalid FW signature */
142 dev_err(dsp->dev, "Invalid FW sign/filesize mismatch\n");
143 return -EINVAL;
144 }
145
146 dev_dbg(dsp->dev,
147 "header sign=%4s size=0x%x modules=0x%x fmt=0x%x size=%zu\n",
148 header->signature, header->file_size, header->modules,
149 header->file_format, sizeof(*header));
150
151 module = (void *)sst_fw->dma_buf + sizeof(*header);
152 for (count = 0; count < header->modules; count++) {
153 /* module */
154 ret = sst_byt_parse_module(dsp, sst_fw, module);
155 if (ret < 0) {
156 dev_err(dsp->dev, "invalid module %d\n", count);
157 return ret;
158 }
159 module = (void *)module + sizeof(*module) + module->mod_size;
160 }
161
162 return 0;
163}
164
165static void sst_byt_dump_shim(struct sst_dsp *sst)
166{
167 int i;
168 u64 reg;
169
170 for (i = 0; i <= 0xF0; i += 8) {
171 reg = sst_dsp_shim_read64_unlocked(sst, i);
172 if (reg)
173 dev_dbg(sst->dev, "shim 0x%2.2x value 0x%16.16llx\n",
174 i, reg);
175 }
176
177 for (i = 0x00; i <= 0xff; i += 4) {
178 reg = readl(sst->addr.pci_cfg + i);
179 if (reg)
180 dev_dbg(sst->dev, "pci 0x%2.2x value 0x%8.8x\n",
181 i, (u32)reg);
182 }
183}
184
185static irqreturn_t sst_byt_irq(int irq, void *context)
186{
187 struct sst_dsp *sst = (struct sst_dsp *) context;
188 u64 isrx;
189 irqreturn_t ret = IRQ_NONE;
190
191 spin_lock(&sst->spinlock);
192
193 isrx = sst_dsp_shim_read64_unlocked(sst, SST_ISRX);
194 if (isrx & SST_ISRX_DONE) {
195 /* ADSP has processed the message request from IA */
196 sst_dsp_shim_update_bits64_unlocked(sst, SST_IPCX,
197 SST_BYT_IPCX_DONE, 0);
198 ret = IRQ_WAKE_THREAD;
199 }
200 if (isrx & SST_BYT_ISRX_REQUEST) {
201 /* mask message request from ADSP and do processing later */
202 sst_dsp_shim_update_bits64_unlocked(sst, SST_IMRX,
203 SST_BYT_IMRX_REQUEST,
204 SST_BYT_IMRX_REQUEST);
205 ret = IRQ_WAKE_THREAD;
206 }
207
208 spin_unlock(&sst->spinlock);
209
210 return ret;
211}
212
213static void sst_byt_boot(struct sst_dsp *sst)
214{
215 int tries = 10;
216
217 /* release stall and wait to unstall */
218 sst_dsp_shim_update_bits64(sst, SST_CSR, SST_BYT_CSR_STALL, 0x0);
219 while (tries--) {
220 if (!(sst_dsp_shim_read64(sst, SST_CSR) &
221 SST_BYT_CSR_PWAITMODE))
222 break;
223 msleep(100);
224 }
225 if (tries < 0) {
226 dev_err(sst->dev, "unable to start DSP\n");
227 sst_byt_dump_shim(sst);
228 }
229}
230
231static void sst_byt_reset(struct sst_dsp *sst)
232{
233 /* put DSP into reset, set reset vector and stall */
234 sst_dsp_shim_update_bits64(sst, SST_CSR,
235 SST_BYT_CSR_RST | SST_BYT_CSR_VECTOR_SEL | SST_BYT_CSR_STALL,
236 SST_BYT_CSR_RST | SST_BYT_CSR_VECTOR_SEL | SST_BYT_CSR_STALL);
237
238 udelay(10);
239
240 /* take DSP out of reset and keep stalled for FW loading */
241 sst_dsp_shim_update_bits64(sst, SST_CSR, SST_BYT_CSR_RST, 0);
242}
243
244struct sst_adsp_memregion {
245 u32 start;
246 u32 end;
247 int blocks;
248 enum sst_mem_type type;
249};
250
251/* BYT test stuff */
252static const struct sst_adsp_memregion byt_region[] = {
253 {0xC0000, 0x100000, 8, SST_MEM_IRAM}, /* I-SRAM - 8 * 32kB */
254 {0x100000, 0x140000, 8, SST_MEM_DRAM}, /* D-SRAM0 - 8 * 32kB */
255};
256
257static int sst_byt_resource_map(struct sst_dsp *sst, struct sst_pdata *pdata)
258{
259 sst->addr.lpe_base = pdata->lpe_base;
260 sst->addr.lpe = ioremap(pdata->lpe_base, pdata->lpe_size);
261 if (!sst->addr.lpe)
262 return -ENODEV;
263
264 /* ADSP PCI MMIO config space */
265 sst->addr.pci_cfg = ioremap(pdata->pcicfg_base, pdata->pcicfg_size);
266 if (!sst->addr.pci_cfg) {
267 iounmap(sst->addr.lpe);
268 return -ENODEV;
269 }
270
271 /* SST Extended FW allocation */
272 sst->addr.fw_ext = ioremap(pdata->fw_base, pdata->fw_size);
273 if (!sst->addr.fw_ext) {
274 iounmap(sst->addr.pci_cfg);
275 iounmap(sst->addr.lpe);
276 return -ENODEV;
277 }
278
279 /* SST Shim */
280 sst->addr.shim = sst->addr.lpe + sst->addr.shim_offset;
281
282 sst_dsp_mailbox_init(sst, SST_BYT_MAILBOX_OFFSET + 0x204,
283 SST_BYT_IPC_MAX_PAYLOAD_SIZE,
284 SST_BYT_MAILBOX_OFFSET,
285 SST_BYT_IPC_MAX_PAYLOAD_SIZE);
286
287 sst->irq = pdata->irq;
288
289 return 0;
290}
291
292static int sst_byt_init(struct sst_dsp *sst, struct sst_pdata *pdata)
293{
294 const struct sst_adsp_memregion *region;
295 struct device *dev;
296 int ret = -ENODEV, i, j, region_count;
297 u32 offset, size;
298
299 dev = sst->dev;
300
301 switch (sst->id) {
302 case SST_DEV_ID_BYT:
303 region = byt_region;
304 region_count = ARRAY_SIZE(byt_region);
305 sst->addr.iram_offset = SST_BYT_IRAM_OFFSET;
306 sst->addr.dram_offset = SST_BYT_DRAM_OFFSET;
307 sst->addr.shim_offset = SST_BYT_SHIM_OFFSET;
308 break;
309 default:
310 dev_err(dev, "failed to get mem resources\n");
311 return ret;
312 }
313
314 ret = sst_byt_resource_map(sst, pdata);
315 if (ret < 0) {
316 dev_err(dev, "failed to map resources\n");
317 return ret;
318 }
319
320 /*
321 * save the physical address of extended firmware block in the first
322 * 4 bytes of the mailbox
323 */
324 memcpy_toio(sst->addr.lpe + SST_BYT_MAILBOX_OFFSET,
325 &pdata->fw_base, sizeof(u32));
326
327 ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
328 if (ret)
329 return ret;
330
331 /* enable Interrupt from both sides */
332 sst_dsp_shim_update_bits64(sst, SST_IMRX, 0x3, 0x0);
333 sst_dsp_shim_update_bits64(sst, SST_IMRD, 0x3, 0x0);
334
335 /* register DSP memory blocks - ideally we should get this from ACPI */
336 for (i = 0; i < region_count; i++) {
337 offset = region[i].start;
338 size = (region[i].end - region[i].start) / region[i].blocks;
339
340 /* register individual memory blocks */
341 for (j = 0; j < region[i].blocks; j++) {
342 sst_mem_block_register(sst, offset, size,
343 region[i].type, NULL, j, sst);
344 offset += size;
345 }
346 }
347
348 return 0;
349}
350
351static void sst_byt_free(struct sst_dsp *sst)
352{
353 sst_mem_block_unregister_all(sst);
354 iounmap(sst->addr.lpe);
355 iounmap(sst->addr.pci_cfg);
356 iounmap(sst->addr.fw_ext);
357}
358
359struct sst_ops sst_byt_ops = {
360 .reset = sst_byt_reset,
361 .boot = sst_byt_boot,
362 .write = sst_shim32_write,
363 .read = sst_shim32_read,
364 .write64 = sst_shim32_write64,
365 .read64 = sst_shim32_read64,
366 .ram_read = sst_memcpy_fromio_32,
367 .ram_write = sst_memcpy_toio_32,
368 .irq_handler = sst_byt_irq,
369 .init = sst_byt_init,
370 .free = sst_byt_free,
371 .parse_fw = sst_byt_parse_fw_image,
372};
diff --git a/sound/soc/intel/sst-baytrail-ipc.c b/sound/soc/intel/sst-baytrail-ipc.c
new file mode 100644
index 000000000000..d0eaeee21be4
--- /dev/null
+++ b/sound/soc/intel/sst-baytrail-ipc.c
@@ -0,0 +1,867 @@
1/*
2 * Intel Baytrail SST IPC Support
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/list.h>
18#include <linux/device.h>
19#include <linux/wait.h>
20#include <linux/spinlock.h>
21#include <linux/workqueue.h>
22#include <linux/export.h>
23#include <linux/slab.h>
24#include <linux/delay.h>
25#include <linux/list.h>
26#include <linux/platform_device.h>
27#include <linux/kthread.h>
28#include <linux/firmware.h>
29#include <linux/io.h>
30#include <asm/div64.h>
31
32#include "sst-baytrail-ipc.h"
33#include "sst-dsp.h"
34#include "sst-dsp-priv.h"
35
36/* IPC message timeout */
37#define IPC_TIMEOUT_MSECS 300
38#define IPC_BOOT_MSECS 200
39
40#define IPC_EMPTY_LIST_SIZE 8
41
42/* IPC header bits */
43#define IPC_HEADER_MSG_ID_MASK 0xff
44#define IPC_HEADER_MSG_ID(x) ((x) & IPC_HEADER_MSG_ID_MASK)
45#define IPC_HEADER_STR_ID_SHIFT 8
46#define IPC_HEADER_STR_ID_MASK 0x1f
47#define IPC_HEADER_STR_ID(x) (((x) & 0x1f) << IPC_HEADER_STR_ID_SHIFT)
48#define IPC_HEADER_LARGE_SHIFT 13
49#define IPC_HEADER_LARGE(x) (((x) & 0x1) << IPC_HEADER_LARGE_SHIFT)
50#define IPC_HEADER_DATA_SHIFT 16
51#define IPC_HEADER_DATA_MASK 0x3fff
52#define IPC_HEADER_DATA(x) (((x) & 0x3fff) << IPC_HEADER_DATA_SHIFT)
53
54/* mask for differentiating between notification and reply message */
55#define IPC_NOTIFICATION (0x1 << 7)
56
57/* I2L Stream config/control msgs */
58#define IPC_IA_ALLOC_STREAM 0x20
59#define IPC_IA_FREE_STREAM 0x21
60#define IPC_IA_PAUSE_STREAM 0x24
61#define IPC_IA_RESUME_STREAM 0x25
62#define IPC_IA_DROP_STREAM 0x26
63#define IPC_IA_START_STREAM 0x30
64
65/* notification messages */
66#define IPC_IA_FW_INIT_CMPLT 0x81
67#define IPC_SST_PERIOD_ELAPSED 0x97
68
69/* IPC messages between host and ADSP */
70struct sst_byt_address_info {
71 u32 addr;
72 u32 size;
73} __packed;
74
75struct sst_byt_str_type {
76 u8 codec_type;
77 u8 str_type;
78 u8 operation;
79 u8 protected_str;
80 u8 time_slots;
81 u8 reserved;
82 u16 result;
83} __packed;
84
85struct sst_byt_pcm_params {
86 u8 num_chan;
87 u8 pcm_wd_sz;
88 u8 use_offload_path;
89 u8 reserved;
90 u32 sfreq;
91 u8 channel_map[8];
92} __packed;
93
94struct sst_byt_frames_info {
95 u16 num_entries;
96 u16 rsrvd;
97 u32 frag_size;
98 struct sst_byt_address_info ring_buf_info[8];
99} __packed;
100
101struct sst_byt_alloc_params {
102 struct sst_byt_str_type str_type;
103 struct sst_byt_pcm_params pcm_params;
104 struct sst_byt_frames_info frame_info;
105} __packed;
106
107struct sst_byt_alloc_response {
108 struct sst_byt_str_type str_type;
109 u8 reserved[88];
110} __packed;
111
112struct sst_byt_start_stream_params {
113 u32 byte_offset;
114} __packed;
115
116struct sst_byt_tstamp {
117 u64 ring_buffer_counter;
118 u64 hardware_counter;
119 u64 frames_decoded;
120 u64 bytes_decoded;
121 u64 bytes_copied;
122 u32 sampling_frequency;
123 u32 channel_peak[8];
124} __packed;
125
126/* driver internal IPC message structure */
127struct ipc_message {
128 struct list_head list;
129 u64 header;
130
131 /* direction wrt host CPU */
132 char tx_data[SST_BYT_IPC_MAX_PAYLOAD_SIZE];
133 size_t tx_size;
134 char rx_data[SST_BYT_IPC_MAX_PAYLOAD_SIZE];
135 size_t rx_size;
136
137 wait_queue_head_t waitq;
138 bool complete;
139 bool wait;
140 int errno;
141};
142
143struct sst_byt_stream;
144struct sst_byt;
145
146/* stream infomation */
147struct sst_byt_stream {
148 struct list_head node;
149
150 /* configuration */
151 struct sst_byt_alloc_params request;
152 struct sst_byt_alloc_response reply;
153
154 /* runtime info */
155 struct sst_byt *byt;
156 int str_id;
157 bool commited;
158 bool running;
159
160 /* driver callback */
161 u32 (*notify_position)(struct sst_byt_stream *stream, void *data);
162 void *pdata;
163};
164
165/* SST Baytrail IPC data */
166struct sst_byt {
167 struct device *dev;
168 struct sst_dsp *dsp;
169
170 /* stream */
171 struct list_head stream_list;
172
173 /* boot */
174 wait_queue_head_t boot_wait;
175 bool boot_complete;
176
177 /* IPC messaging */
178 struct list_head tx_list;
179 struct list_head rx_list;
180 struct list_head empty_list;
181 wait_queue_head_t wait_txq;
182 struct task_struct *tx_thread;
183 struct kthread_worker kworker;
184 struct kthread_work kwork;
185 struct ipc_message *msg;
186};
187
188static inline u64 sst_byt_header(int msg_id, int data, bool large, int str_id)
189{
190 u64 header;
191
192 header = IPC_HEADER_MSG_ID(msg_id) |
193 IPC_HEADER_STR_ID(str_id) |
194 IPC_HEADER_LARGE(large) |
195 IPC_HEADER_DATA(data) |
196 SST_BYT_IPCX_BUSY;
197
198 return header;
199}
200
201static inline u16 sst_byt_header_msg_id(u64 header)
202{
203 return header & IPC_HEADER_MSG_ID_MASK;
204}
205
206static inline u8 sst_byt_header_str_id(u64 header)
207{
208 return (header >> IPC_HEADER_STR_ID_SHIFT) & IPC_HEADER_STR_ID_MASK;
209}
210
211static inline u16 sst_byt_header_data(u64 header)
212{
213 return (header >> IPC_HEADER_DATA_SHIFT) & IPC_HEADER_DATA_MASK;
214}
215
216static struct sst_byt_stream *sst_byt_get_stream(struct sst_byt *byt,
217 int stream_id)
218{
219 struct sst_byt_stream *stream;
220
221 list_for_each_entry(stream, &byt->stream_list, node) {
222 if (stream->str_id == stream_id)
223 return stream;
224 }
225
226 return NULL;
227}
228
229static void sst_byt_ipc_shim_dbg(struct sst_byt *byt, const char *text)
230{
231 struct sst_dsp *sst = byt->dsp;
232 u64 isr, ipcd, imrx, ipcx;
233
234 ipcx = sst_dsp_shim_read64_unlocked(sst, SST_IPCX);
235 isr = sst_dsp_shim_read64_unlocked(sst, SST_ISRX);
236 ipcd = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
237 imrx = sst_dsp_shim_read64_unlocked(sst, SST_IMRX);
238
239 dev_err(byt->dev,
240 "ipc: --%s-- ipcx 0x%llx isr 0x%llx ipcd 0x%llx imrx 0x%llx\n",
241 text, ipcx, isr, ipcd, imrx);
242}
243
244/* locks held by caller */
245static struct ipc_message *sst_byt_msg_get_empty(struct sst_byt *byt)
246{
247 struct ipc_message *msg = NULL;
248
249 if (!list_empty(&byt->empty_list)) {
250 msg = list_first_entry(&byt->empty_list,
251 struct ipc_message, list);
252 list_del(&msg->list);
253 }
254
255 return msg;
256}
257
258static void sst_byt_ipc_tx_msgs(struct kthread_work *work)
259{
260 struct sst_byt *byt =
261 container_of(work, struct sst_byt, kwork);
262 struct ipc_message *msg;
263 u64 ipcx;
264 unsigned long flags;
265
266 spin_lock_irqsave(&byt->dsp->spinlock, flags);
267 if (list_empty(&byt->tx_list)) {
268 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
269 return;
270 }
271
272 /* if the DSP is busy we will TX messages after IRQ */
273 ipcx = sst_dsp_shim_read64_unlocked(byt->dsp, SST_IPCX);
274 if (ipcx & SST_BYT_IPCX_BUSY) {
275 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
276 return;
277 }
278
279 msg = list_first_entry(&byt->tx_list, struct ipc_message, list);
280
281 list_move(&msg->list, &byt->rx_list);
282
283 /* send the message */
284 if (msg->header & IPC_HEADER_LARGE(true))
285 sst_dsp_outbox_write(byt->dsp, msg->tx_data, msg->tx_size);
286 sst_dsp_shim_write64_unlocked(byt->dsp, SST_IPCX, msg->header);
287
288 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
289}
290
291static inline void sst_byt_tx_msg_reply_complete(struct sst_byt *byt,
292 struct ipc_message *msg)
293{
294 msg->complete = true;
295
296 if (!msg->wait)
297 list_add_tail(&msg->list, &byt->empty_list);
298 else
299 wake_up(&msg->waitq);
300}
301
302static int sst_byt_tx_wait_done(struct sst_byt *byt, struct ipc_message *msg,
303 void *rx_data)
304{
305 unsigned long flags;
306 int ret;
307
308 /* wait for DSP completion */
309 ret = wait_event_timeout(msg->waitq, msg->complete,
310 msecs_to_jiffies(IPC_TIMEOUT_MSECS));
311
312 spin_lock_irqsave(&byt->dsp->spinlock, flags);
313 if (ret == 0) {
314 list_del(&msg->list);
315 sst_byt_ipc_shim_dbg(byt, "message timeout");
316
317 ret = -ETIMEDOUT;
318 } else {
319
320 /* copy the data returned from DSP */
321 if (msg->rx_size)
322 memcpy(rx_data, msg->rx_data, msg->rx_size);
323 ret = msg->errno;
324 }
325
326 list_add_tail(&msg->list, &byt->empty_list);
327 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
328 return ret;
329}
330
331static int sst_byt_ipc_tx_message(struct sst_byt *byt, u64 header,
332 void *tx_data, size_t tx_bytes,
333 void *rx_data, size_t rx_bytes, int wait)
334{
335 unsigned long flags;
336 struct ipc_message *msg;
337
338 spin_lock_irqsave(&byt->dsp->spinlock, flags);
339
340 msg = sst_byt_msg_get_empty(byt);
341 if (msg == NULL) {
342 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
343 return -EBUSY;
344 }
345
346 msg->header = header;
347 msg->tx_size = tx_bytes;
348 msg->rx_size = rx_bytes;
349 msg->wait = wait;
350 msg->errno = 0;
351 msg->complete = false;
352
353 if (tx_bytes) {
354 /* msg content = lower 32-bit of the header + data */
355 *(u32 *)msg->tx_data = (u32)(header & (u32)-1);
356 memcpy(msg->tx_data + sizeof(u32), tx_data, tx_bytes);
357 msg->tx_size += sizeof(u32);
358 }
359
360 list_add_tail(&msg->list, &byt->tx_list);
361 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
362
363 queue_kthread_work(&byt->kworker, &byt->kwork);
364
365 if (wait)
366 return sst_byt_tx_wait_done(byt, msg, rx_data);
367 else
368 return 0;
369}
370
371static inline int sst_byt_ipc_tx_msg_wait(struct sst_byt *byt, u64 header,
372 void *tx_data, size_t tx_bytes,
373 void *rx_data, size_t rx_bytes)
374{
375 return sst_byt_ipc_tx_message(byt, header, tx_data, tx_bytes,
376 rx_data, rx_bytes, 1);
377}
378
379static inline int sst_byt_ipc_tx_msg_nowait(struct sst_byt *byt, u64 header,
380 void *tx_data, size_t tx_bytes)
381{
382 return sst_byt_ipc_tx_message(byt, header, tx_data, tx_bytes,
383 NULL, 0, 0);
384}
385
386static struct ipc_message *sst_byt_reply_find_msg(struct sst_byt *byt,
387 u64 header)
388{
389 struct ipc_message *msg = NULL, *_msg;
390 u64 mask;
391
392 /* match reply to message sent based on msg and stream IDs */
393 mask = IPC_HEADER_MSG_ID_MASK |
394 IPC_HEADER_STR_ID_MASK << IPC_HEADER_STR_ID_SHIFT;
395 header &= mask;
396
397 if (list_empty(&byt->rx_list)) {
398 dev_err(byt->dev,
399 "ipc: rx list is empty but received 0x%llx\n", header);
400 goto out;
401 }
402
403 list_for_each_entry(_msg, &byt->rx_list, list) {
404 if ((_msg->header & mask) == header) {
405 msg = _msg;
406 break;
407 }
408 }
409
410out:
411 return msg;
412}
413
414static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg)
415{
416 struct sst_byt_stream *stream;
417 u64 header = msg->header;
418 u8 stream_id = sst_byt_header_str_id(header);
419 u8 stream_msg = sst_byt_header_msg_id(header);
420
421 stream = sst_byt_get_stream(byt, stream_id);
422 if (stream == NULL)
423 return;
424
425 switch (stream_msg) {
426 case IPC_IA_DROP_STREAM:
427 case IPC_IA_PAUSE_STREAM:
428 case IPC_IA_FREE_STREAM:
429 stream->running = false;
430 break;
431 case IPC_IA_START_STREAM:
432 case IPC_IA_RESUME_STREAM:
433 stream->running = true;
434 break;
435 }
436}
437
438static int sst_byt_process_reply(struct sst_byt *byt, u64 header)
439{
440 struct ipc_message *msg;
441
442 msg = sst_byt_reply_find_msg(byt, header);
443 if (msg == NULL)
444 return 1;
445
446 if (header & IPC_HEADER_LARGE(true)) {
447 msg->rx_size = sst_byt_header_data(header);
448 sst_dsp_inbox_read(byt->dsp, msg->rx_data, msg->rx_size);
449 }
450
451 /* update any stream states */
452 sst_byt_stream_update(byt, msg);
453
454 list_del(&msg->list);
455 /* wake up */
456 sst_byt_tx_msg_reply_complete(byt, msg);
457
458 return 1;
459}
460
461static void sst_byt_fw_ready(struct sst_byt *byt, u64 header)
462{
463 dev_dbg(byt->dev, "ipc: DSP is ready 0x%llX\n", header);
464
465 byt->boot_complete = true;
466 wake_up(&byt->boot_wait);
467}
468
469static int sst_byt_process_notification(struct sst_byt *byt,
470 unsigned long *flags)
471{
472 struct sst_dsp *sst = byt->dsp;
473 struct sst_byt_stream *stream;
474 u64 header;
475 u8 msg_id, stream_id;
476 int handled = 1;
477
478 header = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
479 msg_id = sst_byt_header_msg_id(header);
480
481 switch (msg_id) {
482 case IPC_SST_PERIOD_ELAPSED:
483 stream_id = sst_byt_header_str_id(header);
484 stream = sst_byt_get_stream(byt, stream_id);
485 if (stream && stream->running && stream->notify_position) {
486 spin_unlock_irqrestore(&sst->spinlock, *flags);
487 stream->notify_position(stream, stream->pdata);
488 spin_lock_irqsave(&sst->spinlock, *flags);
489 }
490 break;
491 case IPC_IA_FW_INIT_CMPLT:
492 sst_byt_fw_ready(byt, header);
493 break;
494 }
495
496 return handled;
497}
498
499static irqreturn_t sst_byt_irq_thread(int irq, void *context)
500{
501 struct sst_dsp *sst = (struct sst_dsp *) context;
502 struct sst_byt *byt = sst_dsp_get_thread_context(sst);
503 u64 header;
504 unsigned long flags;
505
506 spin_lock_irqsave(&sst->spinlock, flags);
507
508 header = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
509 if (header & SST_BYT_IPCD_BUSY) {
510 if (header & IPC_NOTIFICATION) {
511 /* message from ADSP */
512 sst_byt_process_notification(byt, &flags);
513 } else {
514 /* reply from ADSP */
515 sst_byt_process_reply(byt, header);
516 }
517 /*
518 * clear IPCD BUSY bit and set DONE bit. Tell DSP we have
519 * processed the message and can accept new. Clear data part
520 * of the header
521 */
522 sst_dsp_shim_update_bits64_unlocked(sst, SST_IPCD,
523 SST_BYT_IPCD_DONE | SST_BYT_IPCD_BUSY |
524 IPC_HEADER_DATA(IPC_HEADER_DATA_MASK),
525 SST_BYT_IPCD_DONE);
526 /* unmask message request interrupts */
527 sst_dsp_shim_update_bits64_unlocked(sst, SST_IMRX,
528 SST_BYT_IMRX_REQUEST, 0);
529 }
530
531 spin_unlock_irqrestore(&sst->spinlock, flags);
532
533 /* continue to send any remaining messages... */
534 queue_kthread_work(&byt->kworker, &byt->kwork);
535
536 return IRQ_HANDLED;
537}
538
539/* stream API */
540struct sst_byt_stream *sst_byt_stream_new(struct sst_byt *byt, int id,
541 u32 (*notify_position)(struct sst_byt_stream *stream, void *data),
542 void *data)
543{
544 struct sst_byt_stream *stream;
545
546 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
547 if (stream == NULL)
548 return NULL;
549
550 list_add(&stream->node, &byt->stream_list);
551 stream->notify_position = notify_position;
552 stream->pdata = data;
553 stream->byt = byt;
554 stream->str_id = id;
555
556 return stream;
557}
558
559int sst_byt_stream_set_bits(struct sst_byt *byt, struct sst_byt_stream *stream,
560 int bits)
561{
562 stream->request.pcm_params.pcm_wd_sz = bits;
563 return 0;
564}
565
566int sst_byt_stream_set_channels(struct sst_byt *byt,
567 struct sst_byt_stream *stream, u8 channels)
568{
569 stream->request.pcm_params.num_chan = channels;
570 return 0;
571}
572
573int sst_byt_stream_set_rate(struct sst_byt *byt, struct sst_byt_stream *stream,
574 unsigned int rate)
575{
576 stream->request.pcm_params.sfreq = rate;
577 return 0;
578}
579
580/* stream sonfiguration */
581int sst_byt_stream_type(struct sst_byt *byt, struct sst_byt_stream *stream,
582 int codec_type, int stream_type, int operation)
583{
584 stream->request.str_type.codec_type = codec_type;
585 stream->request.str_type.str_type = stream_type;
586 stream->request.str_type.operation = operation;
587 stream->request.str_type.time_slots = 0xc;
588
589 return 0;
590}
591
592int sst_byt_stream_buffer(struct sst_byt *byt, struct sst_byt_stream *stream,
593 uint32_t buffer_addr, uint32_t buffer_size)
594{
595 stream->request.frame_info.num_entries = 1;
596 stream->request.frame_info.ring_buf_info[0].addr = buffer_addr;
597 stream->request.frame_info.ring_buf_info[0].size = buffer_size;
598 /* calculate bytes per 4 ms fragment */
599 stream->request.frame_info.frag_size =
600 stream->request.pcm_params.sfreq *
601 stream->request.pcm_params.num_chan *
602 stream->request.pcm_params.pcm_wd_sz / 8 *
603 4 / 1000;
604 return 0;
605}
606
607int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
608{
609 struct sst_byt_alloc_params *str_req = &stream->request;
610 struct sst_byt_alloc_response *reply = &stream->reply;
611 u64 header;
612 int ret;
613
614 header = sst_byt_header(IPC_IA_ALLOC_STREAM,
615 sizeof(*str_req) + sizeof(u32),
616 true, stream->str_id);
617 ret = sst_byt_ipc_tx_msg_wait(byt, header, str_req, sizeof(*str_req),
618 reply, sizeof(*reply));
619 if (ret < 0) {
620 dev_err(byt->dev, "ipc: error stream commit failed\n");
621 return ret;
622 }
623
624 stream->commited = true;
625
626 return 0;
627}
628
629int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
630{
631 u64 header;
632 int ret = 0;
633
634 if (!stream->commited)
635 goto out;
636
637 header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id);
638 ret = sst_byt_ipc_tx_msg_wait(byt, header, NULL, 0, NULL, 0);
639 if (ret < 0) {
640 dev_err(byt->dev, "ipc: free stream %d failed\n",
641 stream->str_id);
642 return -EAGAIN;
643 }
644
645 stream->commited = false;
646out:
647 list_del(&stream->node);
648 kfree(stream);
649
650 return ret;
651}
652
653static int sst_byt_stream_operations(struct sst_byt *byt, int type,
654 int stream_id, int wait)
655{
656 struct sst_byt_start_stream_params start_stream;
657 u64 header;
658 void *tx_msg = NULL;
659 size_t size = 0;
660
661 if (type != IPC_IA_START_STREAM) {
662 header = sst_byt_header(type, 0, false, stream_id);
663 } else {
664 start_stream.byte_offset = 0;
665 header = sst_byt_header(IPC_IA_START_STREAM,
666 sizeof(start_stream) + sizeof(u32),
667 true, stream_id);
668 tx_msg = &start_stream;
669 size = sizeof(start_stream);
670 }
671
672 if (wait)
673 return sst_byt_ipc_tx_msg_wait(byt, header,
674 tx_msg, size, NULL, 0);
675 else
676 return sst_byt_ipc_tx_msg_nowait(byt, header, tx_msg, size);
677}
678
679/* stream ALSA trigger operations */
680int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream)
681{
682 int ret;
683
684 ret = sst_byt_stream_operations(byt, IPC_IA_START_STREAM,
685 stream->str_id, 0);
686 if (ret < 0)
687 dev_err(byt->dev, "ipc: error failed to start stream %d\n",
688 stream->str_id);
689
690 return ret;
691}
692
693int sst_byt_stream_stop(struct sst_byt *byt, struct sst_byt_stream *stream)
694{
695 int ret;
696
697 /* don't stop streams that are not commited */
698 if (!stream->commited)
699 return 0;
700
701 ret = sst_byt_stream_operations(byt, IPC_IA_DROP_STREAM,
702 stream->str_id, 0);
703 if (ret < 0)
704 dev_err(byt->dev, "ipc: error failed to stop stream %d\n",
705 stream->str_id);
706 return ret;
707}
708
709int sst_byt_stream_pause(struct sst_byt *byt, struct sst_byt_stream *stream)
710{
711 int ret;
712
713 ret = sst_byt_stream_operations(byt, IPC_IA_PAUSE_STREAM,
714 stream->str_id, 0);
715 if (ret < 0)
716 dev_err(byt->dev, "ipc: error failed to pause stream %d\n",
717 stream->str_id);
718
719 return ret;
720}
721
722int sst_byt_stream_resume(struct sst_byt *byt, struct sst_byt_stream *stream)
723{
724 int ret;
725
726 ret = sst_byt_stream_operations(byt, IPC_IA_RESUME_STREAM,
727 stream->str_id, 0);
728 if (ret < 0)
729 dev_err(byt->dev, "ipc: error failed to resume stream %d\n",
730 stream->str_id);
731
732 return ret;
733}
734
735int sst_byt_get_dsp_position(struct sst_byt *byt,
736 struct sst_byt_stream *stream, int buffer_size)
737{
738 struct sst_dsp *sst = byt->dsp;
739 struct sst_byt_tstamp fw_tstamp;
740 u8 str_id = stream->str_id;
741 u32 tstamp_offset;
742
743 tstamp_offset = SST_BYT_TIMESTAMP_OFFSET + str_id * sizeof(fw_tstamp);
744 memcpy_fromio(&fw_tstamp,
745 sst->addr.lpe + tstamp_offset, sizeof(fw_tstamp));
746
747 return do_div(fw_tstamp.ring_buffer_counter, buffer_size);
748}
749
750static int msg_empty_list_init(struct sst_byt *byt)
751{
752 struct ipc_message *msg;
753 int i;
754
755 byt->msg = kzalloc(sizeof(*msg) * IPC_EMPTY_LIST_SIZE, GFP_KERNEL);
756 if (byt->msg == NULL)
757 return -ENOMEM;
758
759 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
760 init_waitqueue_head(&byt->msg[i].waitq);
761 list_add(&byt->msg[i].list, &byt->empty_list);
762 }
763
764 return 0;
765}
766
767struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt)
768{
769 return byt->dsp;
770}
771
772static struct sst_dsp_device byt_dev = {
773 .thread = sst_byt_irq_thread,
774 .ops = &sst_byt_ops,
775};
776
777int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata)
778{
779 struct sst_byt *byt;
780 struct sst_fw *byt_sst_fw;
781 int err;
782
783 dev_dbg(dev, "initialising Byt DSP IPC\n");
784
785 byt = devm_kzalloc(dev, sizeof(*byt), GFP_KERNEL);
786 if (byt == NULL)
787 return -ENOMEM;
788
789 byt->dev = dev;
790 INIT_LIST_HEAD(&byt->stream_list);
791 INIT_LIST_HEAD(&byt->tx_list);
792 INIT_LIST_HEAD(&byt->rx_list);
793 INIT_LIST_HEAD(&byt->empty_list);
794 init_waitqueue_head(&byt->boot_wait);
795 init_waitqueue_head(&byt->wait_txq);
796
797 err = msg_empty_list_init(byt);
798 if (err < 0)
799 return -ENOMEM;
800
801 /* start the IPC message thread */
802 init_kthread_worker(&byt->kworker);
803 byt->tx_thread = kthread_run(kthread_worker_fn,
804 &byt->kworker,
805 dev_name(byt->dev));
806 if (IS_ERR(byt->tx_thread)) {
807 err = PTR_ERR(byt->tx_thread);
808 dev_err(byt->dev, "error failed to create message TX task\n");
809 goto err_free_msg;
810 }
811 init_kthread_work(&byt->kwork, sst_byt_ipc_tx_msgs);
812
813 byt_dev.thread_context = byt;
814
815 /* init SST shim */
816 byt->dsp = sst_dsp_new(dev, &byt_dev, pdata);
817 if (byt->dsp == NULL) {
818 err = -ENODEV;
819 goto err_free_msg;
820 }
821
822 /* keep the DSP in reset state for base FW loading */
823 sst_dsp_reset(byt->dsp);
824
825 byt_sst_fw = sst_fw_new(byt->dsp, pdata->fw, byt);
826 if (byt_sst_fw == NULL) {
827 err = -ENODEV;
828 dev_err(dev, "error: failed to load firmware\n");
829 goto fw_err;
830 }
831
832 /* wait for DSP boot completion */
833 sst_dsp_boot(byt->dsp);
834 err = wait_event_timeout(byt->boot_wait, byt->boot_complete,
835 msecs_to_jiffies(IPC_BOOT_MSECS));
836 if (err == 0) {
837 err = -EIO;
838 dev_err(byt->dev, "ipc: error DSP boot timeout\n");
839 goto boot_err;
840 }
841
842 pdata->dsp = byt;
843
844 return 0;
845
846boot_err:
847 sst_dsp_reset(byt->dsp);
848 sst_fw_free(byt_sst_fw);
849fw_err:
850 sst_dsp_free(byt->dsp);
851err_free_msg:
852 kfree(byt->msg);
853
854 return err;
855}
856EXPORT_SYMBOL_GPL(sst_byt_dsp_init);
857
858void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata)
859{
860 struct sst_byt *byt = pdata->dsp;
861
862 sst_dsp_reset(byt->dsp);
863 sst_fw_free_all(byt->dsp);
864 sst_dsp_free(byt->dsp);
865 kfree(byt->msg);
866}
867EXPORT_SYMBOL_GPL(sst_byt_dsp_free);
diff --git a/sound/soc/intel/sst-baytrail-ipc.h b/sound/soc/intel/sst-baytrail-ipc.h
new file mode 100644
index 000000000000..f172b6440fa9
--- /dev/null
+++ b/sound/soc/intel/sst-baytrail-ipc.h
@@ -0,0 +1,69 @@
1/*
2 * Intel Baytrail SST IPC Support
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#ifndef __SST_BYT_IPC_H
16#define __SST_BYT_IPC_H
17
18#include <linux/types.h>
19
20struct sst_byt;
21struct sst_byt_stream;
22struct sst_pdata;
23extern struct sst_ops sst_byt_ops;
24
25
26#define SST_BYT_MAILBOX_OFFSET 0x144000
27#define SST_BYT_TIMESTAMP_OFFSET (SST_BYT_MAILBOX_OFFSET + 0x800)
28
29/**
30 * Upfront defined maximum message size that is
31 * expected by the in/out communication pipes in FW.
32 */
33#define SST_BYT_IPC_MAX_PAYLOAD_SIZE 200
34
35/* stream API */
36struct sst_byt_stream *sst_byt_stream_new(struct sst_byt *byt, int id,
37 uint32_t (*get_write_position)(struct sst_byt_stream *stream,
38 void *data),
39 void *data);
40
41/* stream configuration */
42int sst_byt_stream_set_bits(struct sst_byt *byt, struct sst_byt_stream *stream,
43 int bits);
44int sst_byt_stream_set_channels(struct sst_byt *byt,
45 struct sst_byt_stream *stream, u8 channels);
46int sst_byt_stream_set_rate(struct sst_byt *byt, struct sst_byt_stream *stream,
47 unsigned int rate);
48int sst_byt_stream_type(struct sst_byt *byt, struct sst_byt_stream *stream,
49 int codec_type, int stream_type, int operation);
50int sst_byt_stream_buffer(struct sst_byt *byt, struct sst_byt_stream *stream,
51 uint32_t buffer_addr, uint32_t buffer_size);
52int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream);
53int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream);
54
55/* stream ALSA trigger operations */
56int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream);
57int sst_byt_stream_stop(struct sst_byt *byt, struct sst_byt_stream *stream);
58int sst_byt_stream_pause(struct sst_byt *byt, struct sst_byt_stream *stream);
59int sst_byt_stream_resume(struct sst_byt *byt, struct sst_byt_stream *stream);
60
61int sst_byt_get_dsp_position(struct sst_byt *byt,
62 struct sst_byt_stream *stream, int buffer_size);
63
64/* init */
65int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata);
66void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata);
67struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt);
68
69#endif
diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/sst-baytrail-pcm.c
new file mode 100644
index 000000000000..6d101f3813b4
--- /dev/null
+++ b/sound/soc/intel/sst-baytrail-pcm.c
@@ -0,0 +1,422 @@
1/*
2 * Intel Baytrail SST PCM Support
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/module.h>
16#include <linux/dma-mapping.h>
17#include <linux/slab.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include "sst-baytrail-ipc.h"
23#include "sst-dsp-priv.h"
24#include "sst-dsp.h"
25
26#define BYT_PCM_COUNT 2
27
28static const struct snd_pcm_hardware sst_byt_pcm_hardware = {
29 .info = SNDRV_PCM_INFO_MMAP |
30 SNDRV_PCM_INFO_MMAP_VALID |
31 SNDRV_PCM_INFO_INTERLEAVED |
32 SNDRV_PCM_INFO_PAUSE |
33 SNDRV_PCM_INFO_RESUME,
34 .formats = SNDRV_PCM_FMTBIT_S16_LE |
35 SNDRV_PCM_FORMAT_S24_LE,
36 .period_bytes_min = 384,
37 .period_bytes_max = 48000,
38 .periods_min = 2,
39 .periods_max = 250,
40 .buffer_bytes_max = 96000,
41};
42
43/* private data for each PCM DSP stream */
44struct sst_byt_pcm_data {
45 struct sst_byt_stream *stream;
46 struct snd_pcm_substream *substream;
47 struct mutex mutex;
48};
49
50/* private data for the driver */
51struct sst_byt_priv_data {
52 /* runtime DSP */
53 struct sst_byt *byt;
54
55 /* DAI data */
56 struct sst_byt_pcm_data pcm[BYT_PCM_COUNT];
57};
58
59/* this may get called several times by oss emulation */
60static int sst_byt_pcm_hw_params(struct snd_pcm_substream *substream,
61 struct snd_pcm_hw_params *params)
62{
63 struct snd_soc_pcm_runtime *rtd = substream->private_data;
64 struct sst_byt_priv_data *pdata =
65 snd_soc_platform_get_drvdata(rtd->platform);
66 struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
67 struct sst_byt *byt = pdata->byt;
68 u32 rate, bits;
69 u8 channels;
70 int ret, playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
71
72 dev_dbg(rtd->dev, "PCM: hw_params, pcm_data %p\n", pcm_data);
73
74 ret = sst_byt_stream_type(byt, pcm_data->stream,
75 1, 1, !playback);
76 if (ret < 0) {
77 dev_err(rtd->dev, "failed to set stream format %d\n", ret);
78 return ret;
79 }
80
81 rate = params_rate(params);
82 ret = sst_byt_stream_set_rate(byt, pcm_data->stream, rate);
83 if (ret < 0) {
84 dev_err(rtd->dev, "could not set rate %d\n", rate);
85 return ret;
86 }
87
88 bits = snd_pcm_format_width(params_format(params));
89 ret = sst_byt_stream_set_bits(byt, pcm_data->stream, bits);
90 if (ret < 0) {
91 dev_err(rtd->dev, "could not set formats %d\n",
92 params_rate(params));
93 return ret;
94 }
95
96 channels = (u8)(params_channels(params) & 0xF);
97 ret = sst_byt_stream_set_channels(byt, pcm_data->stream, channels);
98 if (ret < 0) {
99 dev_err(rtd->dev, "could not set channels %d\n",
100 params_rate(params));
101 return ret;
102 }
103
104 snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
105
106 ret = sst_byt_stream_buffer(byt, pcm_data->stream,
107 substream->dma_buffer.addr,
108 params_buffer_bytes(params));
109 if (ret < 0) {
110 dev_err(rtd->dev, "PCM: failed to set DMA buffer %d\n", ret);
111 return ret;
112 }
113
114 ret = sst_byt_stream_commit(byt, pcm_data->stream);
115 if (ret < 0) {
116 dev_err(rtd->dev, "PCM: failed stream commit %d\n", ret);
117 return ret;
118 }
119
120 return 0;
121}
122
123static int sst_byt_pcm_hw_free(struct snd_pcm_substream *substream)
124{
125 struct snd_soc_pcm_runtime *rtd = substream->private_data;
126
127 dev_dbg(rtd->dev, "PCM: hw_free\n");
128 snd_pcm_lib_free_pages(substream);
129
130 return 0;
131}
132
133static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
134{
135 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct sst_byt_priv_data *pdata =
137 snd_soc_platform_get_drvdata(rtd->platform);
138 struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
139 struct sst_byt *byt = pdata->byt;
140
141 dev_dbg(rtd->dev, "PCM: trigger %d\n", cmd);
142
143 switch (cmd) {
144 case SNDRV_PCM_TRIGGER_START:
145 sst_byt_stream_start(byt, pcm_data->stream);
146 break;
147 case SNDRV_PCM_TRIGGER_RESUME:
148 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
149 sst_byt_stream_resume(byt, pcm_data->stream);
150 break;
151 case SNDRV_PCM_TRIGGER_STOP:
152 sst_byt_stream_stop(byt, pcm_data->stream);
153 break;
154 case SNDRV_PCM_TRIGGER_SUSPEND:
155 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
156 sst_byt_stream_pause(byt, pcm_data->stream);
157 break;
158 default:
159 break;
160 }
161
162 return 0;
163}
164
165static u32 byt_notify_pointer(struct sst_byt_stream *stream, void *data)
166{
167 struct sst_byt_pcm_data *pcm_data = data;
168 struct snd_pcm_substream *substream = pcm_data->substream;
169 struct snd_pcm_runtime *runtime = substream->runtime;
170 struct snd_soc_pcm_runtime *rtd = substream->private_data;
171 u32 pos;
172
173 pos = frames_to_bytes(runtime,
174 (runtime->control->appl_ptr %
175 runtime->buffer_size));
176
177 dev_dbg(rtd->dev, "PCM: App pointer %d bytes\n", pos);
178
179 snd_pcm_period_elapsed(substream);
180 return pos;
181}
182
183static snd_pcm_uframes_t sst_byt_pcm_pointer(struct snd_pcm_substream *substream)
184{
185 struct snd_soc_pcm_runtime *rtd = substream->private_data;
186 struct snd_pcm_runtime *runtime = substream->runtime;
187 struct sst_byt_priv_data *pdata =
188 snd_soc_platform_get_drvdata(rtd->platform);
189 struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
190 struct sst_byt *byt = pdata->byt;
191 snd_pcm_uframes_t offset;
192 int pos;
193
194 pos = sst_byt_get_dsp_position(byt, pcm_data->stream,
195 snd_pcm_lib_buffer_bytes(substream));
196 offset = bytes_to_frames(runtime, pos);
197
198 dev_dbg(rtd->dev, "PCM: DMA pointer %zu bytes\n",
199 frames_to_bytes(runtime, (u32)offset));
200 return offset;
201}
202
203static int sst_byt_pcm_open(struct snd_pcm_substream *substream)
204{
205 struct snd_soc_pcm_runtime *rtd = substream->private_data;
206 struct sst_byt_priv_data *pdata =
207 snd_soc_platform_get_drvdata(rtd->platform);
208 struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
209 struct sst_byt *byt = pdata->byt;
210
211 dev_dbg(rtd->dev, "PCM: open\n");
212
213 pcm_data = &pdata->pcm[rtd->cpu_dai->id];
214 mutex_lock(&pcm_data->mutex);
215
216 snd_soc_pcm_set_drvdata(rtd, pcm_data);
217 pcm_data->substream = substream;
218
219 snd_soc_set_runtime_hwparams(substream, &sst_byt_pcm_hardware);
220
221 pcm_data->stream = sst_byt_stream_new(byt, rtd->cpu_dai->id + 1,
222 byt_notify_pointer, pcm_data);
223 if (pcm_data->stream == NULL) {
224 dev_err(rtd->dev, "failed to create stream\n");
225 mutex_unlock(&pcm_data->mutex);
226 return -EINVAL;
227 }
228
229 mutex_unlock(&pcm_data->mutex);
230 return 0;
231}
232
233static int sst_byt_pcm_close(struct snd_pcm_substream *substream)
234{
235 struct snd_soc_pcm_runtime *rtd = substream->private_data;
236 struct sst_byt_priv_data *pdata =
237 snd_soc_platform_get_drvdata(rtd->platform);
238 struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
239 struct sst_byt *byt = pdata->byt;
240 int ret;
241
242 dev_dbg(rtd->dev, "PCM: close\n");
243
244 mutex_lock(&pcm_data->mutex);
245 ret = sst_byt_stream_free(byt, pcm_data->stream);
246 if (ret < 0) {
247 dev_dbg(rtd->dev, "Free stream fail\n");
248 goto out;
249 }
250 pcm_data->stream = NULL;
251
252out:
253 mutex_unlock(&pcm_data->mutex);
254 return ret;
255}
256
257static int sst_byt_pcm_mmap(struct snd_pcm_substream *substream,
258 struct vm_area_struct *vma)
259{
260 struct snd_soc_pcm_runtime *rtd = substream->private_data;
261
262 dev_dbg(rtd->dev, "PCM: mmap\n");
263 return snd_pcm_lib_default_mmap(substream, vma);
264}
265
266static struct snd_pcm_ops sst_byt_pcm_ops = {
267 .open = sst_byt_pcm_open,
268 .close = sst_byt_pcm_close,
269 .ioctl = snd_pcm_lib_ioctl,
270 .hw_params = sst_byt_pcm_hw_params,
271 .hw_free = sst_byt_pcm_hw_free,
272 .trigger = sst_byt_pcm_trigger,
273 .pointer = sst_byt_pcm_pointer,
274 .mmap = sst_byt_pcm_mmap,
275};
276
277static void sst_byt_pcm_free(struct snd_pcm *pcm)
278{
279 snd_pcm_lib_preallocate_free_for_all(pcm);
280}
281
282static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd)
283{
284 struct snd_pcm *pcm = rtd->pcm;
285 size_t size;
286 int ret = 0;
287
288 ret = dma_coerce_mask_and_coherent(rtd->card->dev, DMA_BIT_MASK(32));
289 if (ret)
290 return ret;
291
292 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
293 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
294 size = sst_byt_pcm_hardware.buffer_bytes_max;
295 ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
296 SNDRV_DMA_TYPE_DEV,
297 rtd->card->dev,
298 size, size);
299 if (ret) {
300 dev_err(rtd->dev, "dma buffer allocation failed %d\n",
301 ret);
302 return ret;
303 }
304 }
305
306 return ret;
307}
308
309static struct snd_soc_dai_driver byt_dais[] = {
310 {
311 .name = "Front-cpu-dai",
312 .playback = {
313 .stream_name = "System Playback",
314 .channels_min = 2,
315 .channels_max = 2,
316 .rates = SNDRV_PCM_RATE_48000,
317 .formats = SNDRV_PCM_FMTBIT_S24_3LE |
318 SNDRV_PCM_FMTBIT_S16_LE,
319 },
320 },
321 {
322 .name = "Mic1-cpu-dai",
323 .capture = {
324 .stream_name = "Analog Capture",
325 .channels_min = 2,
326 .channels_max = 2,
327 .rates = SNDRV_PCM_RATE_48000,
328 .formats = SNDRV_PCM_FMTBIT_S16_LE,
329 },
330 },
331};
332
333static int sst_byt_pcm_probe(struct snd_soc_platform *platform)
334{
335 struct sst_pdata *plat_data = dev_get_platdata(platform->dev);
336 struct sst_byt_priv_data *priv_data;
337 int i;
338
339 if (!plat_data)
340 return -ENODEV;
341
342 priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data),
343 GFP_KERNEL);
344 priv_data->byt = plat_data->dsp;
345 snd_soc_platform_set_drvdata(platform, priv_data);
346
347 for (i = 0; i < ARRAY_SIZE(byt_dais); i++)
348 mutex_init(&priv_data->pcm[i].mutex);
349
350 return 0;
351}
352
353static int sst_byt_pcm_remove(struct snd_soc_platform *platform)
354{
355 return 0;
356}
357
358static struct snd_soc_platform_driver byt_soc_platform = {
359 .probe = sst_byt_pcm_probe,
360 .remove = sst_byt_pcm_remove,
361 .ops = &sst_byt_pcm_ops,
362 .pcm_new = sst_byt_pcm_new,
363 .pcm_free = sst_byt_pcm_free,
364};
365
366static const struct snd_soc_component_driver byt_dai_component = {
367 .name = "byt-dai",
368};
369
370static int sst_byt_pcm_dev_probe(struct platform_device *pdev)
371{
372 struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
373 int ret;
374
375 ret = sst_byt_dsp_init(&pdev->dev, sst_pdata);
376 if (ret < 0)
377 return -ENODEV;
378
379 ret = snd_soc_register_platform(&pdev->dev, &byt_soc_platform);
380 if (ret < 0)
381 goto err_plat;
382
383 ret = snd_soc_register_component(&pdev->dev, &byt_dai_component,
384 byt_dais, ARRAY_SIZE(byt_dais));
385 if (ret < 0)
386 goto err_comp;
387
388 return 0;
389
390err_comp:
391 snd_soc_unregister_platform(&pdev->dev);
392err_plat:
393 sst_byt_dsp_free(&pdev->dev, sst_pdata);
394 return ret;
395}
396
397static int sst_byt_pcm_dev_remove(struct platform_device *pdev)
398{
399 struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
400
401 snd_soc_unregister_platform(&pdev->dev);
402 snd_soc_unregister_component(&pdev->dev);
403 sst_byt_dsp_free(&pdev->dev, sst_pdata);
404
405 return 0;
406}
407
408static struct platform_driver sst_byt_pcm_driver = {
409 .driver = {
410 .name = "baytrail-pcm-audio",
411 .owner = THIS_MODULE,
412 },
413
414 .probe = sst_byt_pcm_dev_probe,
415 .remove = sst_byt_pcm_dev_remove,
416};
417module_platform_driver(sst_byt_pcm_driver);
418
419MODULE_AUTHOR("Jarkko Nikula");
420MODULE_DESCRIPTION("Baytrail PCM");
421MODULE_LICENSE("GPL v2");
422MODULE_ALIAS("platform:baytrail-pcm-audio");
diff --git a/sound/soc/intel/sst-dsp-priv.h b/sound/soc/intel/sst-dsp-priv.h
new file mode 100644
index 000000000000..fe8e81aad646
--- /dev/null
+++ b/sound/soc/intel/sst-dsp-priv.h
@@ -0,0 +1,309 @@
1/*
2 * Intel Smart Sound Technology
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef __SOUND_SOC_SST_DSP_PRIV_H
18#define __SOUND_SOC_SST_DSP_PRIV_H
19
20#include <linux/kernel.h>
21#include <linux/types.h>
22#include <linux/interrupt.h>
23#include <linux/firmware.h>
24
25struct sst_mem_block;
26struct sst_module;
27struct sst_fw;
28
29/*
30 * DSP Operations exported by platform Audio DSP driver.
31 */
32struct sst_ops {
33 /* DSP core boot / reset */
34 void (*boot)(struct sst_dsp *);
35 void (*reset)(struct sst_dsp *);
36
37 /* Shim IO */
38 void (*write)(void __iomem *addr, u32 offset, u32 value);
39 u32 (*read)(void __iomem *addr, u32 offset);
40 void (*write64)(void __iomem *addr, u32 offset, u64 value);
41 u64 (*read64)(void __iomem *addr, u32 offset);
42
43 /* DSP I/DRAM IO */
44 void (*ram_read)(struct sst_dsp *sst, void *dest, void __iomem *src,
45 size_t bytes);
46 void (*ram_write)(struct sst_dsp *sst, void __iomem *dest, void *src,
47 size_t bytes);
48
49 void (*dump)(struct sst_dsp *);
50
51 /* IRQ handlers */
52 irqreturn_t (*irq_handler)(int irq, void *context);
53
54 /* SST init and free */
55 int (*init)(struct sst_dsp *sst, struct sst_pdata *pdata);
56 void (*free)(struct sst_dsp *sst);
57
58 /* FW module parser/loader */
59 int (*parse_fw)(struct sst_fw *sst_fw);
60};
61
62/*
63 * Audio DSP memory offsets and addresses.
64 */
65struct sst_addr {
66 u32 lpe_base;
67 u32 shim_offset;
68 u32 iram_offset;
69 u32 dram_offset;
70 void __iomem *lpe;
71 void __iomem *shim;
72 void __iomem *pci_cfg;
73 void __iomem *fw_ext;
74};
75
76/*
77 * Audio DSP Mailbox configuration.
78 */
79struct sst_mailbox {
80 void __iomem *in_base;
81 void __iomem *out_base;
82 size_t in_size;
83 size_t out_size;
84};
85
86/*
87 * Audio DSP Firmware data types.
88 */
89enum sst_data_type {
90 SST_DATA_M = 0, /* module block data */
91 SST_DATA_P = 1, /* peristant data (text, data) */
92 SST_DATA_S = 2, /* scratch data (usually buffers) */
93};
94
95/*
96 * Audio DSP memory block types.
97 */
98enum sst_mem_type {
99 SST_MEM_IRAM = 0,
100 SST_MEM_DRAM = 1,
101 SST_MEM_ANY = 2,
102 SST_MEM_CACHE= 3,
103};
104
105/*
106 * Audio DSP Generic Firmware File.
107 *
108 * SST Firmware files can consist of 1..N modules. This generic structure is
109 * used to manage each firmware file and it's modules regardless of SST firmware
110 * type. A SST driver may load multiple FW files.
111 */
112struct sst_fw {
113 struct sst_dsp *dsp;
114
115 /* base addresses of FW file data */
116 dma_addr_t dmable_fw_paddr; /* physical address of fw data */
117 void *dma_buf; /* virtual address of fw data */
118 u32 size; /* size of fw data */
119
120 /* lists */
121 struct list_head list; /* DSP list of FW */
122 struct list_head module_list; /* FW list of modules */
123
124 void *private; /* core doesn't touch this */
125};
126
127/*
128 * Audio DSP Generic Module data.
129 *
130 * This is used to dsecribe any sections of persistent (text and data) and
131 * scratch (buffers) of module data in ADSP memory space.
132 */
133struct sst_module_data {
134
135 enum sst_mem_type type; /* destination memory type */
136 enum sst_data_type data_type; /* type of module data */
137
138 u32 size; /* size in bytes */
139 u32 offset; /* offset in FW file */
140 u32 data_offset; /* offset in ADSP memory space */
141 void *data; /* module data */
142};
143
144/*
145 * Audio DSP Generic Module Template.
146 *
147 * Used to define and register a new FW module. This data is extracted from
148 * FW module header information.
149 */
150struct sst_module_template {
151 u32 id;
152 u32 entry; /* entry point */
153 struct sst_module_data s; /* scratch data */
154 struct sst_module_data p; /* peristant data */
155};
156
157/*
158 * Audio DSP Generic Module.
159 *
160 * Each Firmware file can consist of 1..N modules. A module can span multiple
161 * ADSP memory blocks. The simplest FW will be a file with 1 module.
162 */
163struct sst_module {
164 struct sst_dsp *dsp;
165 struct sst_fw *sst_fw; /* parent FW we belong too */
166
167 /* module configuration */
168 u32 id;
169 u32 entry; /* module entry point */
170 u32 offset; /* module offset in firmware file */
171 u32 size; /* module size */
172 struct sst_module_data s; /* scratch data */
173 struct sst_module_data p; /* peristant data */
174
175 /* runtime */
176 u32 usage_count; /* can be unloaded if count == 0 */
177 void *private; /* core doesn't touch this */
178
179 /* lists */
180 struct list_head block_list; /* Module list of blocks in use */
181 struct list_head list; /* DSP list of modules */
182 struct list_head list_fw; /* FW list of modules */
183};
184
185/*
186 * SST Memory Block operations.
187 */
188struct sst_block_ops {
189 int (*enable)(struct sst_mem_block *block);
190 int (*disable)(struct sst_mem_block *block);
191};
192
193/*
194 * SST Generic Memory Block.
195 *
196 * SST ADP memory has multiple IRAM and DRAM blocks. Some ADSP blocks can be
197 * power gated.
198 */
199struct sst_mem_block {
200 struct sst_dsp *dsp;
201 struct sst_module *module; /* module that uses this block */
202
203 /* block config */
204 u32 offset; /* offset from base */
205 u32 size; /* block size */
206 u32 index; /* block index 0..N */
207 enum sst_mem_type type; /* block memory type IRAM/DRAM */
208 struct sst_block_ops *ops; /* block operations, if any */
209
210 /* block status */
211 enum sst_data_type data_type; /* data type held in this block */
212 u32 bytes_used; /* bytes in use by modules */
213 void *private; /* generic core does not touch this */
214 int users; /* number of modules using this block */
215
216 /* block lists */
217 struct list_head module_list; /* Module list of blocks */
218 struct list_head list; /* Map list of free/used blocks */
219};
220
221/*
222 * Generic SST Shim Interface.
223 */
224struct sst_dsp {
225
226 /* runtime */
227 struct sst_dsp_device *sst_dev;
228 spinlock_t spinlock; /* IPC locking */
229 struct mutex mutex; /* DSP FW lock */
230 struct device *dev;
231 void *thread_context;
232 int irq;
233 u32 id;
234
235 /* list of free and used ADSP memory blocks */
236 struct list_head used_block_list;
237 struct list_head free_block_list;
238
239 /* operations */
240 struct sst_ops *ops;
241
242 /* debug FS */
243 struct dentry *debugfs_root;
244
245 /* base addresses */
246 struct sst_addr addr;
247
248 /* mailbox */
249 struct sst_mailbox mailbox;
250
251 /* SST FW files loaded and their modules */
252 struct list_head module_list;
253 struct list_head fw_list;
254
255 /* platform data */
256 struct sst_pdata *pdata;
257
258 /* DMA FW loading */
259 struct sst_dma *dma;
260 bool fw_use_dma;
261};
262
263/* Size optimised DRAM/IRAM memcpy */
264static inline void sst_dsp_write(struct sst_dsp *sst, void *src,
265 u32 dest_offset, size_t bytes)
266{
267 sst->ops->ram_write(sst, sst->addr.lpe + dest_offset, src, bytes);
268}
269
270static inline void sst_dsp_read(struct sst_dsp *sst, void *dest,
271 u32 src_offset, size_t bytes)
272{
273 sst->ops->ram_read(sst, dest, sst->addr.lpe + src_offset, bytes);
274}
275
276static inline void *sst_dsp_get_thread_context(struct sst_dsp *sst)
277{
278 return sst->thread_context;
279}
280
281/* Create/Free FW files - can contain multiple modules */
282struct sst_fw *sst_fw_new(struct sst_dsp *dsp,
283 const struct firmware *fw, void *private);
284void sst_fw_free(struct sst_fw *sst_fw);
285void sst_fw_free_all(struct sst_dsp *dsp);
286
287/* Create/Free firmware modules */
288struct sst_module *sst_module_new(struct sst_fw *sst_fw,
289 struct sst_module_template *template, void *private);
290void sst_module_free(struct sst_module *sst_module);
291int sst_module_insert(struct sst_module *sst_module);
292int sst_module_remove(struct sst_module *sst_module);
293int sst_module_insert_fixed_block(struct sst_module *module,
294 struct sst_module_data *data);
295struct sst_module *sst_module_get_from_id(struct sst_dsp *dsp, u32 id);
296
297/* allocate/free pesistent/scratch memory regions managed by drv */
298struct sst_module *sst_mem_block_alloc_scratch(struct sst_dsp *dsp);
299void sst_mem_block_free_scratch(struct sst_dsp *dsp,
300 struct sst_module *scratch);
301int sst_block_module_remove(struct sst_module *module);
302
303/* Register the DSPs memory blocks - would be nice to read from ACPI */
304struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset,
305 u32 size, enum sst_mem_type type, struct sst_block_ops *ops, u32 index,
306 void *private);
307void sst_mem_block_unregister_all(struct sst_dsp *dsp);
308
309#endif
diff --git a/sound/soc/intel/sst-dsp.c b/sound/soc/intel/sst-dsp.c
new file mode 100644
index 000000000000..0c129fd85ecf
--- /dev/null
+++ b/sound/soc/intel/sst-dsp.c
@@ -0,0 +1,385 @@
1/*
2 * Intel Smart Sound Technology (SST) DSP Core Driver
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/slab.h>
18#include <linux/export.h>
19#include <linux/interrupt.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/io.h>
23
24#include "sst-dsp.h"
25#include "sst-dsp-priv.h"
26
27#define CREATE_TRACE_POINTS
28#include <trace/events/intel-sst.h>
29
30/* Internal generic low-level SST IO functions - can be overidden */
31void sst_shim32_write(void __iomem *addr, u32 offset, u32 value)
32{
33 writel(value, addr + offset);
34}
35EXPORT_SYMBOL_GPL(sst_shim32_write);
36
37u32 sst_shim32_read(void __iomem *addr, u32 offset)
38{
39 return readl(addr + offset);
40}
41EXPORT_SYMBOL_GPL(sst_shim32_read);
42
43void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value)
44{
45 memcpy_toio(addr + offset, &value, sizeof(value));
46}
47EXPORT_SYMBOL_GPL(sst_shim32_write64);
48
49u64 sst_shim32_read64(void __iomem *addr, u32 offset)
50{
51 u64 val;
52
53 memcpy_fromio(&val, addr + offset, sizeof(val));
54 return val;
55}
56EXPORT_SYMBOL_GPL(sst_shim32_read64);
57
58static inline void _sst_memcpy_toio_32(volatile u32 __iomem *dest,
59 u32 *src, size_t bytes)
60{
61 int i, words = bytes >> 2;
62
63 for (i = 0; i < words; i++)
64 writel(src[i], dest + i);
65}
66
67static inline void _sst_memcpy_fromio_32(u32 *dest,
68 const volatile __iomem u32 *src, size_t bytes)
69{
70 int i, words = bytes >> 2;
71
72 for (i = 0; i < words; i++)
73 dest[i] = readl(src + i);
74}
75
76void sst_memcpy_toio_32(struct sst_dsp *sst,
77 void __iomem *dest, void *src, size_t bytes)
78{
79 _sst_memcpy_toio_32(dest, src, bytes);
80}
81EXPORT_SYMBOL_GPL(sst_memcpy_toio_32);
82
83void sst_memcpy_fromio_32(struct sst_dsp *sst, void *dest,
84 void __iomem *src, size_t bytes)
85{
86 _sst_memcpy_fromio_32(dest, src, bytes);
87}
88EXPORT_SYMBOL_GPL(sst_memcpy_fromio_32);
89
90/* Public API */
91void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value)
92{
93 unsigned long flags;
94
95 spin_lock_irqsave(&sst->spinlock, flags);
96 sst->ops->write(sst->addr.shim, offset, value);
97 spin_unlock_irqrestore(&sst->spinlock, flags);
98}
99EXPORT_SYMBOL_GPL(sst_dsp_shim_write);
100
101u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset)
102{
103 unsigned long flags;
104 u32 val;
105
106 spin_lock_irqsave(&sst->spinlock, flags);
107 val = sst->ops->read(sst->addr.shim, offset);
108 spin_unlock_irqrestore(&sst->spinlock, flags);
109
110 return val;
111}
112EXPORT_SYMBOL_GPL(sst_dsp_shim_read);
113
114void sst_dsp_shim_write64(struct sst_dsp *sst, u32 offset, u64 value)
115{
116 unsigned long flags;
117
118 spin_lock_irqsave(&sst->spinlock, flags);
119 sst->ops->write64(sst->addr.shim, offset, value);
120 spin_unlock_irqrestore(&sst->spinlock, flags);
121}
122EXPORT_SYMBOL_GPL(sst_dsp_shim_write64);
123
124u64 sst_dsp_shim_read64(struct sst_dsp *sst, u32 offset)
125{
126 unsigned long flags;
127 u64 val;
128
129 spin_lock_irqsave(&sst->spinlock, flags);
130 val = sst->ops->read64(sst->addr.shim, offset);
131 spin_unlock_irqrestore(&sst->spinlock, flags);
132
133 return val;
134}
135EXPORT_SYMBOL_GPL(sst_dsp_shim_read64);
136
137void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value)
138{
139 sst->ops->write(sst->addr.shim, offset, value);
140}
141EXPORT_SYMBOL_GPL(sst_dsp_shim_write_unlocked);
142
143u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset)
144{
145 return sst->ops->read(sst->addr.shim, offset);
146}
147EXPORT_SYMBOL_GPL(sst_dsp_shim_read_unlocked);
148
149void sst_dsp_shim_write64_unlocked(struct sst_dsp *sst, u32 offset, u64 value)
150{
151 sst->ops->write64(sst->addr.shim, offset, value);
152}
153EXPORT_SYMBOL_GPL(sst_dsp_shim_write64_unlocked);
154
155u64 sst_dsp_shim_read64_unlocked(struct sst_dsp *sst, u32 offset)
156{
157 return sst->ops->read64(sst->addr.shim, offset);
158}
159EXPORT_SYMBOL_GPL(sst_dsp_shim_read64_unlocked);
160
161int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset,
162 u32 mask, u32 value)
163{
164 bool change;
165 unsigned int old, new;
166 u32 ret;
167
168 ret = sst_dsp_shim_read_unlocked(sst, offset);
169
170 old = ret;
171 new = (old & (~mask)) | (value & mask);
172
173 change = (old != new);
174 if (change)
175 sst_dsp_shim_write_unlocked(sst, offset, new);
176
177 return change;
178}
179EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_unlocked);
180
181int sst_dsp_shim_update_bits64_unlocked(struct sst_dsp *sst, u32 offset,
182 u64 mask, u64 value)
183{
184 bool change;
185 u64 old, new;
186
187 old = sst_dsp_shim_read64_unlocked(sst, offset);
188
189 new = (old & (~mask)) | (value & mask);
190
191 change = (old != new);
192 if (change)
193 sst_dsp_shim_write64_unlocked(sst, offset, new);
194
195 return change;
196}
197EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits64_unlocked);
198
199int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset,
200 u32 mask, u32 value)
201{
202 unsigned long flags;
203 bool change;
204
205 spin_lock_irqsave(&sst->spinlock, flags);
206 change = sst_dsp_shim_update_bits_unlocked(sst, offset, mask, value);
207 spin_unlock_irqrestore(&sst->spinlock, flags);
208 return change;
209}
210EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits);
211
212int sst_dsp_shim_update_bits64(struct sst_dsp *sst, u32 offset,
213 u64 mask, u64 value)
214{
215 unsigned long flags;
216 bool change;
217
218 spin_lock_irqsave(&sst->spinlock, flags);
219 change = sst_dsp_shim_update_bits64_unlocked(sst, offset, mask, value);
220 spin_unlock_irqrestore(&sst->spinlock, flags);
221 return change;
222}
223EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits64);
224
225void sst_dsp_dump(struct sst_dsp *sst)
226{
227 sst->ops->dump(sst);
228}
229EXPORT_SYMBOL_GPL(sst_dsp_dump);
230
231void sst_dsp_reset(struct sst_dsp *sst)
232{
233 sst->ops->reset(sst);
234}
235EXPORT_SYMBOL_GPL(sst_dsp_reset);
236
237int sst_dsp_boot(struct sst_dsp *sst)
238{
239 sst->ops->boot(sst);
240 return 0;
241}
242EXPORT_SYMBOL_GPL(sst_dsp_boot);
243
244void sst_dsp_ipc_msg_tx(struct sst_dsp *dsp, u32 msg)
245{
246 sst_dsp_shim_write_unlocked(dsp, SST_IPCX, msg | SST_IPCX_BUSY);
247 trace_sst_ipc_msg_tx(msg);
248}
249EXPORT_SYMBOL_GPL(sst_dsp_ipc_msg_tx);
250
251u32 sst_dsp_ipc_msg_rx(struct sst_dsp *dsp)
252{
253 u32 msg;
254
255 msg = sst_dsp_shim_read_unlocked(dsp, SST_IPCX);
256 trace_sst_ipc_msg_rx(msg);
257
258 return msg;
259}
260EXPORT_SYMBOL_GPL(sst_dsp_ipc_msg_rx);
261
262int sst_dsp_mailbox_init(struct sst_dsp *sst, u32 inbox_offset, size_t inbox_size,
263 u32 outbox_offset, size_t outbox_size)
264{
265 sst->mailbox.in_base = sst->addr.lpe + inbox_offset;
266 sst->mailbox.out_base = sst->addr.lpe + outbox_offset;
267 sst->mailbox.in_size = inbox_size;
268 sst->mailbox.out_size = outbox_size;
269 return 0;
270}
271EXPORT_SYMBOL_GPL(sst_dsp_mailbox_init);
272
273void sst_dsp_outbox_write(struct sst_dsp *sst, void *message, size_t bytes)
274{
275 u32 i;
276
277 trace_sst_ipc_outbox_write(bytes);
278
279 memcpy_toio(sst->mailbox.out_base, message, bytes);
280
281 for (i = 0; i < bytes; i += 4)
282 trace_sst_ipc_outbox_wdata(i, *(u32 *)(message + i));
283}
284EXPORT_SYMBOL_GPL(sst_dsp_outbox_write);
285
286void sst_dsp_outbox_read(struct sst_dsp *sst, void *message, size_t bytes)
287{
288 u32 i;
289
290 trace_sst_ipc_outbox_read(bytes);
291
292 memcpy_fromio(message, sst->mailbox.out_base, bytes);
293
294 for (i = 0; i < bytes; i += 4)
295 trace_sst_ipc_outbox_rdata(i, *(u32 *)(message + i));
296}
297EXPORT_SYMBOL_GPL(sst_dsp_outbox_read);
298
299void sst_dsp_inbox_write(struct sst_dsp *sst, void *message, size_t bytes)
300{
301 u32 i;
302
303 trace_sst_ipc_inbox_write(bytes);
304
305 memcpy_toio(sst->mailbox.in_base, message, bytes);
306
307 for (i = 0; i < bytes; i += 4)
308 trace_sst_ipc_inbox_wdata(i, *(u32 *)(message + i));
309}
310EXPORT_SYMBOL_GPL(sst_dsp_inbox_write);
311
312void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes)
313{
314 u32 i;
315
316 trace_sst_ipc_inbox_read(bytes);
317
318 memcpy_fromio(message, sst->mailbox.in_base, bytes);
319
320 for (i = 0; i < bytes; i += 4)
321 trace_sst_ipc_inbox_rdata(i, *(u32 *)(message + i));
322}
323EXPORT_SYMBOL_GPL(sst_dsp_inbox_read);
324
325struct sst_dsp *sst_dsp_new(struct device *dev,
326 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata)
327{
328 struct sst_dsp *sst;
329 int err;
330
331 dev_dbg(dev, "initialising audio DSP id 0x%x\n", pdata->id);
332
333 sst = devm_kzalloc(dev, sizeof(*sst), GFP_KERNEL);
334 if (sst == NULL)
335 return NULL;
336
337 spin_lock_init(&sst->spinlock);
338 mutex_init(&sst->mutex);
339 sst->dev = dev;
340 sst->thread_context = sst_dev->thread_context;
341 sst->sst_dev = sst_dev;
342 sst->id = pdata->id;
343 sst->irq = pdata->irq;
344 sst->ops = sst_dev->ops;
345 sst->pdata = pdata;
346 INIT_LIST_HEAD(&sst->used_block_list);
347 INIT_LIST_HEAD(&sst->free_block_list);
348 INIT_LIST_HEAD(&sst->module_list);
349 INIT_LIST_HEAD(&sst->fw_list);
350
351 /* Initialise SST Audio DSP */
352 if (sst->ops->init) {
353 err = sst->ops->init(sst, pdata);
354 if (err < 0)
355 return NULL;
356 }
357
358 /* Register the ISR */
359 err = request_threaded_irq(sst->irq, sst->ops->irq_handler,
360 sst_dev->thread, IRQF_SHARED, "AudioDSP", sst);
361 if (err)
362 goto irq_err;
363
364 return sst;
365
366irq_err:
367 if (sst->ops->free)
368 sst->ops->free(sst);
369
370 return NULL;
371}
372EXPORT_SYMBOL_GPL(sst_dsp_new);
373
374void sst_dsp_free(struct sst_dsp *sst)
375{
376 free_irq(sst->irq, sst);
377 if (sst->ops->free)
378 sst->ops->free(sst);
379}
380EXPORT_SYMBOL_GPL(sst_dsp_free);
381
382/* Module information */
383MODULE_AUTHOR("Liam Girdwood");
384MODULE_DESCRIPTION("Intel SST Core");
385MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/intel/sst-dsp.h b/sound/soc/intel/sst-dsp.h
new file mode 100644
index 000000000000..74052b59485c
--- /dev/null
+++ b/sound/soc/intel/sst-dsp.h
@@ -0,0 +1,233 @@
1/*
2 * Intel Smart Sound Technology (SST) Core
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef __SOUND_SOC_SST_DSP_H
18#define __SOUND_SOC_SST_DSP_H
19
20#include <linux/kernel.h>
21#include <linux/types.h>
22#include <linux/interrupt.h>
23
24/* SST Device IDs */
25#define SST_DEV_ID_LYNX_POINT 0x33C8
26#define SST_DEV_ID_WILDCAT_POINT 0x3438
27#define SST_DEV_ID_BYT 0x0F28
28
29/* Supported SST DMA Devices */
30#define SST_DMA_TYPE_DW 1
31#define SST_DMA_TYPE_MID 2
32
33/* SST Shim register map
34 * The register naming can differ between products. Some products also
35 * contain extra functionality.
36 */
37#define SST_CSR 0x00
38#define SST_PISR 0x08
39#define SST_PIMR 0x10
40#define SST_ISRX 0x18
41#define SST_ISRD 0x20
42#define SST_IMRX 0x28
43#define SST_IMRD 0x30
44#define SST_IPCX 0x38 /* IPC IA -> SST */
45#define SST_IPCD 0x40 /* IPC SST -> IA */
46#define SST_ISRSC 0x48
47#define SST_ISRLPESC 0x50
48#define SST_IMRSC 0x58
49#define SST_IMRLPESC 0x60
50#define SST_IPCSC 0x68
51#define SST_IPCLPESC 0x70
52#define SST_CLKCTL 0x78
53#define SST_CSR2 0x80
54#define SST_LTRC 0xE0
55#define SST_HDMC 0xE8
56#define SST_DBGO 0xF0
57
58#define SST_SHIM_SIZE 0x100
59#define SST_PWMCTRL 0x1000
60
61/* SST Shim Register bits
62 * The register bit naming can differ between products. Some products also
63 * contain extra functionality.
64 */
65
66/* CSR / CS */
67#define SST_CSR_RST (0x1 << 1)
68#define SST_CSR_SBCS0 (0x1 << 2)
69#define SST_CSR_SBCS1 (0x1 << 3)
70#define SST_CSR_DCS(x) (x << 4)
71#define SST_CSR_DCS_MASK (0x7 << 4)
72#define SST_CSR_STALL (0x1 << 10)
73#define SST_CSR_S0IOCS (0x1 << 21)
74#define SST_CSR_S1IOCS (0x1 << 23)
75#define SST_CSR_LPCS (0x1 << 31)
76#define SST_BYT_CSR_RST (0x1 << 0)
77#define SST_BYT_CSR_VECTOR_SEL (0x1 << 1)
78#define SST_BYT_CSR_STALL (0x1 << 2)
79#define SST_BYT_CSR_PWAITMODE (0x1 << 3)
80
81/* ISRX / ISC */
82#define SST_ISRX_BUSY (0x1 << 1)
83#define SST_ISRX_DONE (0x1 << 0)
84#define SST_BYT_ISRX_REQUEST (0x1 << 1)
85
86/* ISRD / ISD */
87#define SST_ISRD_BUSY (0x1 << 1)
88#define SST_ISRD_DONE (0x1 << 0)
89
90/* IMRX / IMC */
91#define SST_IMRX_BUSY (0x1 << 1)
92#define SST_IMRX_DONE (0x1 << 0)
93#define SST_BYT_IMRX_REQUEST (0x1 << 1)
94
95/* IPCX / IPCC */
96#define SST_IPCX_DONE (0x1 << 30)
97#define SST_IPCX_BUSY (0x1 << 31)
98#define SST_BYT_IPCX_DONE ((u64)0x1 << 62)
99#define SST_BYT_IPCX_BUSY ((u64)0x1 << 63)
100
101/* IPCD */
102#define SST_IPCD_DONE (0x1 << 30)
103#define SST_IPCD_BUSY (0x1 << 31)
104#define SST_BYT_IPCD_DONE ((u64)0x1 << 62)
105#define SST_BYT_IPCD_BUSY ((u64)0x1 << 63)
106
107/* CLKCTL */
108#define SST_CLKCTL_SMOS(x) (x << 24)
109#define SST_CLKCTL_MASK (3 << 24)
110#define SST_CLKCTL_DCPLCG (1 << 18)
111#define SST_CLKCTL_SCOE1 (1 << 17)
112#define SST_CLKCTL_SCOE0 (1 << 16)
113
114/* CSR2 / CS2 */
115#define SST_CSR2_SDFD_SSP0 (1 << 1)
116#define SST_CSR2_SDFD_SSP1 (1 << 2)
117
118/* LTRC */
119#define SST_LTRC_VAL(x) (x << 0)
120
121/* HDMC */
122#define SST_HDMC_HDDA0(x) (x << 0)
123#define SST_HDMC_HDDA1(x) (x << 7)
124
125
126/* SST Vendor Defined Registers and bits */
127#define SST_VDRTCTL0 0xa0
128#define SST_VDRTCTL1 0xa4
129#define SST_VDRTCTL2 0xa8
130#define SST_VDRTCTL3 0xaC
131
132/* VDRTCTL0 */
133#define SST_VDRTCL0_DSRAMPGE_SHIFT 16
134#define SST_VDRTCL0_DSRAMPGE_MASK (0xffff << SST_VDRTCL0_DSRAMPGE_SHIFT)
135#define SST_VDRTCL0_ISRAMPGE_SHIFT 6
136#define SST_VDRTCL0_ISRAMPGE_MASK (0x3ff << SST_VDRTCL0_ISRAMPGE_SHIFT)
137
138struct sst_dsp;
139
140/*
141 * SST Device.
142 *
143 * This structure is populated by the SST core driver.
144 */
145struct sst_dsp_device {
146 /* Mandatory fields */
147 struct sst_ops *ops;
148 irqreturn_t (*thread)(int irq, void *context);
149 void *thread_context;
150};
151
152/*
153 * SST Platform Data.
154 */
155struct sst_pdata {
156 /* ACPI data */
157 u32 lpe_base;
158 u32 lpe_size;
159 u32 pcicfg_base;
160 u32 pcicfg_size;
161 u32 fw_base;
162 u32 fw_size;
163 int irq;
164
165 /* Firmware */
166 const struct firmware *fw;
167
168 /* DMA */
169 u32 dma_base;
170 u32 dma_size;
171 int dma_engine;
172
173 /* DSP */
174 u32 id;
175 void *dsp;
176};
177
178/* Initialization */
179struct sst_dsp *sst_dsp_new(struct device *dev,
180 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata);
181void sst_dsp_free(struct sst_dsp *sst);
182
183/* SHIM Read / Write */
184void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value);
185u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset);
186int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset,
187 u32 mask, u32 value);
188void sst_dsp_shim_write64(struct sst_dsp *sst, u32 offset, u64 value);
189u64 sst_dsp_shim_read64(struct sst_dsp *sst, u32 offset);
190int sst_dsp_shim_update_bits64(struct sst_dsp *sst, u32 offset,
191 u64 mask, u64 value);
192
193/* SHIM Read / Write Unlocked for callers already holding sst lock */
194void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value);
195u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset);
196int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset,
197 u32 mask, u32 value);
198void sst_dsp_shim_write64_unlocked(struct sst_dsp *sst, u32 offset, u64 value);
199u64 sst_dsp_shim_read64_unlocked(struct sst_dsp *sst, u32 offset);
200int sst_dsp_shim_update_bits64_unlocked(struct sst_dsp *sst, u32 offset,
201 u64 mask, u64 value);
202
203/* Internal generic low-level SST IO functions - can be overidden */
204void sst_shim32_write(void __iomem *addr, u32 offset, u32 value);
205u32 sst_shim32_read(void __iomem *addr, u32 offset);
206void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value);
207u64 sst_shim32_read64(void __iomem *addr, u32 offset);
208void sst_memcpy_toio_32(struct sst_dsp *sst,
209 void __iomem *dest, void *src, size_t bytes);
210void sst_memcpy_fromio_32(struct sst_dsp *sst,
211 void *dest, void __iomem *src, size_t bytes);
212
213/* DSP reset & boot */
214void sst_dsp_reset(struct sst_dsp *sst);
215int sst_dsp_boot(struct sst_dsp *sst);
216
217/* Msg IO */
218void sst_dsp_ipc_msg_tx(struct sst_dsp *dsp, u32 msg);
219u32 sst_dsp_ipc_msg_rx(struct sst_dsp *dsp);
220
221/* Mailbox management */
222int sst_dsp_mailbox_init(struct sst_dsp *dsp, u32 inbox_offset,
223 size_t inbox_size, u32 outbox_offset, size_t outbox_size);
224void sst_dsp_inbox_write(struct sst_dsp *dsp, void *message, size_t bytes);
225void sst_dsp_inbox_read(struct sst_dsp *dsp, void *message, size_t bytes);
226void sst_dsp_outbox_write(struct sst_dsp *dsp, void *message, size_t bytes);
227void sst_dsp_outbox_read(struct sst_dsp *dsp, void *message, size_t bytes);
228void sst_dsp_mailbox_dump(struct sst_dsp *dsp, size_t bytes);
229
230/* Debug */
231void sst_dsp_dump(struct sst_dsp *sst);
232
233#endif
diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c
new file mode 100644
index 000000000000..f7687107cf7f
--- /dev/null
+++ b/sound/soc/intel/sst-firmware.c
@@ -0,0 +1,587 @@
1/*
2 * Intel SST Firmware Loader
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/slab.h>
19#include <linux/sched.h>
20#include <linux/firmware.h>
21#include <linux/export.h>
22#include <linux/platform_device.h>
23#include <linux/dma-mapping.h>
24#include <linux/dmaengine.h>
25#include <linux/pci.h>
26
27#include <asm/page.h>
28#include <asm/pgtable.h>
29
30#include "sst-dsp.h"
31#include "sst-dsp-priv.h"
32
33static void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes)
34{
35 u32 i;
36
37 /* copy one 32 bit word at a time as 64 bit access is not supported */
38 for (i = 0; i < bytes; i += 4)
39 memcpy_toio(dest + i, src + i, 4);
40}
41
42/* create new generic firmware object */
43struct sst_fw *sst_fw_new(struct sst_dsp *dsp,
44 const struct firmware *fw, void *private)
45{
46 struct sst_fw *sst_fw;
47 int err;
48
49 if (!dsp->ops->parse_fw)
50 return NULL;
51
52 sst_fw = kzalloc(sizeof(*sst_fw), GFP_KERNEL);
53 if (sst_fw == NULL)
54 return NULL;
55
56 sst_fw->dsp = dsp;
57 sst_fw->private = private;
58 sst_fw->size = fw->size;
59
60 err = dma_coerce_mask_and_coherent(dsp->dev, DMA_BIT_MASK(32));
61 if (err < 0) {
62 kfree(sst_fw);
63 return NULL;
64 }
65
66 /* allocate DMA buffer to store FW data */
67 sst_fw->dma_buf = dma_alloc_coherent(dsp->dev, sst_fw->size,
68 &sst_fw->dmable_fw_paddr, GFP_DMA | GFP_KERNEL);
69 if (!sst_fw->dma_buf) {
70 dev_err(dsp->dev, "error: DMA alloc failed\n");
71 kfree(sst_fw);
72 return NULL;
73 }
74
75 /* copy FW data to DMA-able memory */
76 memcpy((void *)sst_fw->dma_buf, (void *)fw->data, fw->size);
77
78 /* call core specific FW paser to load FW data into DSP */
79 err = dsp->ops->parse_fw(sst_fw);
80 if (err < 0) {
81 dev_err(dsp->dev, "error: parse fw failed %d\n", err);
82 goto parse_err;
83 }
84
85 mutex_lock(&dsp->mutex);
86 list_add(&sst_fw->list, &dsp->fw_list);
87 mutex_unlock(&dsp->mutex);
88
89 return sst_fw;
90
91parse_err:
92 dma_free_coherent(dsp->dev, sst_fw->size,
93 sst_fw->dma_buf,
94 sst_fw->dmable_fw_paddr);
95 kfree(sst_fw);
96 return NULL;
97}
98EXPORT_SYMBOL_GPL(sst_fw_new);
99
100/* free single firmware object */
101void sst_fw_free(struct sst_fw *sst_fw)
102{
103 struct sst_dsp *dsp = sst_fw->dsp;
104
105 mutex_lock(&dsp->mutex);
106 list_del(&sst_fw->list);
107 mutex_unlock(&dsp->mutex);
108
109 dma_free_coherent(dsp->dev, sst_fw->size, sst_fw->dma_buf,
110 sst_fw->dmable_fw_paddr);
111 kfree(sst_fw);
112}
113EXPORT_SYMBOL_GPL(sst_fw_free);
114
115/* free all firmware objects */
116void sst_fw_free_all(struct sst_dsp *dsp)
117{
118 struct sst_fw *sst_fw, *t;
119
120 mutex_lock(&dsp->mutex);
121 list_for_each_entry_safe(sst_fw, t, &dsp->fw_list, list) {
122
123 list_del(&sst_fw->list);
124 dma_free_coherent(dsp->dev, sst_fw->size, sst_fw->dma_buf,
125 sst_fw->dmable_fw_paddr);
126 kfree(sst_fw);
127 }
128 mutex_unlock(&dsp->mutex);
129}
130EXPORT_SYMBOL_GPL(sst_fw_free_all);
131
132/* create a new SST generic module from FW template */
133struct sst_module *sst_module_new(struct sst_fw *sst_fw,
134 struct sst_module_template *template, void *private)
135{
136 struct sst_dsp *dsp = sst_fw->dsp;
137 struct sst_module *sst_module;
138
139 sst_module = kzalloc(sizeof(*sst_module), GFP_KERNEL);
140 if (sst_module == NULL)
141 return NULL;
142
143 sst_module->id = template->id;
144 sst_module->dsp = dsp;
145 sst_module->sst_fw = sst_fw;
146
147 memcpy(&sst_module->s, &template->s, sizeof(struct sst_module_data));
148 memcpy(&sst_module->p, &template->p, sizeof(struct sst_module_data));
149
150 INIT_LIST_HEAD(&sst_module->block_list);
151
152 mutex_lock(&dsp->mutex);
153 list_add(&sst_module->list, &dsp->module_list);
154 mutex_unlock(&dsp->mutex);
155
156 return sst_module;
157}
158EXPORT_SYMBOL_GPL(sst_module_new);
159
160/* free firmware module and remove from available list */
161void sst_module_free(struct sst_module *sst_module)
162{
163 struct sst_dsp *dsp = sst_module->dsp;
164
165 mutex_lock(&dsp->mutex);
166 list_del(&sst_module->list);
167 mutex_unlock(&dsp->mutex);
168
169 kfree(sst_module);
170}
171EXPORT_SYMBOL_GPL(sst_module_free);
172
173static struct sst_mem_block *find_block(struct sst_dsp *dsp, int type,
174 u32 offset)
175{
176 struct sst_mem_block *block;
177
178 list_for_each_entry(block, &dsp->free_block_list, list) {
179 if (block->type == type && block->offset == offset)
180 return block;
181 }
182
183 return NULL;
184}
185
186static int block_alloc_contiguous(struct sst_module *module,
187 struct sst_module_data *data, u32 offset, int size)
188{
189 struct list_head tmp = LIST_HEAD_INIT(tmp);
190 struct sst_dsp *dsp = module->dsp;
191 struct sst_mem_block *block;
192
193 while (size > 0) {
194 block = find_block(dsp, data->type, offset);
195 if (!block) {
196 list_splice(&tmp, &dsp->free_block_list);
197 return -ENOMEM;
198 }
199
200 list_move_tail(&block->list, &tmp);
201 offset += block->size;
202 size -= block->size;
203 }
204
205 list_splice(&tmp, &dsp->used_block_list);
206 return 0;
207}
208
209/* allocate free DSP blocks for module data - callers hold locks */
210static int block_alloc(struct sst_module *module,
211 struct sst_module_data *data)
212{
213 struct sst_dsp *dsp = module->dsp;
214 struct sst_mem_block *block, *tmp;
215 int ret = 0;
216
217 if (data->size == 0)
218 return 0;
219
220 /* find first free whole blocks that can hold module */
221 list_for_each_entry_safe(block, tmp, &dsp->free_block_list, list) {
222
223 /* ignore blocks with wrong type */
224 if (block->type != data->type)
225 continue;
226
227 if (data->size > block->size)
228 continue;
229
230 data->offset = block->offset;
231 block->data_type = data->data_type;
232 block->bytes_used = data->size % block->size;
233 list_add(&block->module_list, &module->block_list);
234 list_move(&block->list, &dsp->used_block_list);
235 dev_dbg(dsp->dev, " *module %d added block %d:%d\n",
236 module->id, block->type, block->index);
237 return 0;
238 }
239
240 /* then find free multiple blocks that can hold module */
241 list_for_each_entry_safe(block, tmp, &dsp->free_block_list, list) {
242
243 /* ignore blocks with wrong type */
244 if (block->type != data->type)
245 continue;
246
247 /* do we span > 1 blocks */
248 if (data->size > block->size) {
249 ret = block_alloc_contiguous(module, data,
250 block->offset + block->size,
251 data->size - block->size);
252 if (ret == 0)
253 return ret;
254 }
255 }
256
257 /* not enough free block space */
258 return -ENOMEM;
259}
260
261/* remove module from memory - callers hold locks */
262static void block_module_remove(struct sst_module *module)
263{
264 struct sst_mem_block *block, *tmp;
265 struct sst_dsp *dsp = module->dsp;
266 int err;
267
268 /* disable each block */
269 list_for_each_entry(block, &module->block_list, module_list) {
270
271 if (block->ops && block->ops->disable) {
272 err = block->ops->disable(block);
273 if (err < 0)
274 dev_err(dsp->dev,
275 "error: cant disable block %d:%d\n",
276 block->type, block->index);
277 }
278 }
279
280 /* mark each block as free */
281 list_for_each_entry_safe(block, tmp, &module->block_list, module_list) {
282 list_del(&block->module_list);
283 list_move(&block->list, &dsp->free_block_list);
284 }
285}
286
287/* prepare the memory block to receive data from host - callers hold locks */
288static int block_module_prepare(struct sst_module *module)
289{
290 struct sst_mem_block *block;
291 int ret = 0;
292
293 /* enable each block so that's it'e ready for module P/S data */
294 list_for_each_entry(block, &module->block_list, module_list) {
295
296 if (block->ops && block->ops->enable) {
297 ret = block->ops->enable(block);
298 if (ret < 0) {
299 dev_err(module->dsp->dev,
300 "error: cant disable block %d:%d\n",
301 block->type, block->index);
302 goto err;
303 }
304 }
305 }
306 return ret;
307
308err:
309 list_for_each_entry(block, &module->block_list, module_list) {
310 if (block->ops && block->ops->disable)
311 block->ops->disable(block);
312 }
313 return ret;
314}
315
316/* allocate memory blocks for static module addresses - callers hold locks */
317static int block_alloc_fixed(struct sst_module *module,
318 struct sst_module_data *data)
319{
320 struct sst_dsp *dsp = module->dsp;
321 struct sst_mem_block *block, *tmp;
322 u32 end = data->offset + data->size, block_end;
323 int err;
324
325 /* only IRAM/DRAM blocks are managed */
326 if (data->type != SST_MEM_IRAM && data->type != SST_MEM_DRAM)
327 return 0;
328
329 /* are blocks already attached to this module */
330 list_for_each_entry_safe(block, tmp, &module->block_list, module_list) {
331
332 /* force compacting mem blocks of the same data_type */
333 if (block->data_type != data->data_type)
334 continue;
335
336 block_end = block->offset + block->size;
337
338 /* find block that holds section */
339 if (data->offset >= block->offset && end < block_end)
340 return 0;
341
342 /* does block span more than 1 section */
343 if (data->offset >= block->offset && data->offset < block_end) {
344
345 err = block_alloc_contiguous(module, data,
346 block->offset + block->size,
347 data->size - block->size + data->offset - block->offset);
348 if (err < 0)
349 return -ENOMEM;
350
351 /* module already owns blocks */
352 return 0;
353 }
354 }
355
356 /* find first free blocks that can hold section in free list */
357 list_for_each_entry_safe(block, tmp, &dsp->free_block_list, list) {
358 block_end = block->offset + block->size;
359
360 /* find block that holds section */
361 if (data->offset >= block->offset && end < block_end) {
362
363 /* add block */
364 block->data_type = data->data_type;
365 list_move(&block->list, &dsp->used_block_list);
366 list_add(&block->module_list, &module->block_list);
367 return 0;
368 }
369
370 /* does block span more than 1 section */
371 if (data->offset >= block->offset && data->offset < block_end) {
372
373 err = block_alloc_contiguous(module, data,
374 block->offset + block->size,
375 data->size - block->size);
376 if (err < 0)
377 return -ENOMEM;
378
379 /* add block */
380 block->data_type = data->data_type;
381 list_move(&block->list, &dsp->used_block_list);
382 list_add(&block->module_list, &module->block_list);
383 return 0;
384 }
385
386 }
387
388 return -ENOMEM;
389}
390
391/* Load fixed module data into DSP memory blocks */
392int sst_module_insert_fixed_block(struct sst_module *module,
393 struct sst_module_data *data)
394{
395 struct sst_dsp *dsp = module->dsp;
396 int ret;
397
398 mutex_lock(&dsp->mutex);
399
400 /* alloc blocks that includes this section */
401 ret = block_alloc_fixed(module, data);
402 if (ret < 0) {
403 dev_err(dsp->dev,
404 "error: no free blocks for section at offset 0x%x size 0x%x\n",
405 data->offset, data->size);
406 mutex_unlock(&dsp->mutex);
407 return -ENOMEM;
408 }
409
410 /* prepare DSP blocks for module copy */
411 ret = block_module_prepare(module);
412 if (ret < 0) {
413 dev_err(dsp->dev, "error: fw module prepare failed\n");
414 goto err;
415 }
416
417 /* copy partial module data to blocks */
418 sst_memcpy32(dsp->addr.lpe + data->offset, data->data, data->size);
419
420 mutex_unlock(&dsp->mutex);
421 return ret;
422
423err:
424 block_module_remove(module);
425 mutex_unlock(&dsp->mutex);
426 return ret;
427}
428EXPORT_SYMBOL_GPL(sst_module_insert_fixed_block);
429
430/* Unload entire module from DSP memory */
431int sst_block_module_remove(struct sst_module *module)
432{
433 struct sst_dsp *dsp = module->dsp;
434
435 mutex_lock(&dsp->mutex);
436 block_module_remove(module);
437 mutex_unlock(&dsp->mutex);
438 return 0;
439}
440EXPORT_SYMBOL_GPL(sst_block_module_remove);
441
442/* register a DSP memory block for use with FW based modules */
443struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset,
444 u32 size, enum sst_mem_type type, struct sst_block_ops *ops, u32 index,
445 void *private)
446{
447 struct sst_mem_block *block;
448
449 block = kzalloc(sizeof(*block), GFP_KERNEL);
450 if (block == NULL)
451 return NULL;
452
453 block->offset = offset;
454 block->size = size;
455 block->index = index;
456 block->type = type;
457 block->dsp = dsp;
458 block->private = private;
459 block->ops = ops;
460
461 mutex_lock(&dsp->mutex);
462 list_add(&block->list, &dsp->free_block_list);
463 mutex_unlock(&dsp->mutex);
464
465 return block;
466}
467EXPORT_SYMBOL_GPL(sst_mem_block_register);
468
469/* unregister all DSP memory blocks */
470void sst_mem_block_unregister_all(struct sst_dsp *dsp)
471{
472 struct sst_mem_block *block, *tmp;
473
474 mutex_lock(&dsp->mutex);
475
476 /* unregister used blocks */
477 list_for_each_entry_safe(block, tmp, &dsp->used_block_list, list) {
478 list_del(&block->list);
479 kfree(block);
480 }
481
482 /* unregister free blocks */
483 list_for_each_entry_safe(block, tmp, &dsp->free_block_list, list) {
484 list_del(&block->list);
485 kfree(block);
486 }
487
488 mutex_unlock(&dsp->mutex);
489}
490EXPORT_SYMBOL_GPL(sst_mem_block_unregister_all);
491
492/* allocate scratch buffer blocks */
493struct sst_module *sst_mem_block_alloc_scratch(struct sst_dsp *dsp)
494{
495 struct sst_module *sst_module, *scratch;
496 struct sst_mem_block *block, *tmp;
497 u32 block_size;
498 int ret = 0;
499
500 scratch = kzalloc(sizeof(struct sst_module), GFP_KERNEL);
501 if (scratch == NULL)
502 return NULL;
503
504 mutex_lock(&dsp->mutex);
505
506 /* calculate required scratch size */
507 list_for_each_entry(sst_module, &dsp->module_list, list) {
508 if (scratch->s.size > sst_module->s.size)
509 scratch->s.size = scratch->s.size;
510 else
511 scratch->s.size = sst_module->s.size;
512 }
513
514 dev_dbg(dsp->dev, "scratch buffer required is %d bytes\n",
515 scratch->s.size);
516
517 /* init scratch module */
518 scratch->dsp = dsp;
519 scratch->s.type = SST_MEM_DRAM;
520 scratch->s.data_type = SST_DATA_S;
521 INIT_LIST_HEAD(&scratch->block_list);
522
523 /* check free blocks before looking at used blocks for space */
524 if (!list_empty(&dsp->free_block_list))
525 block = list_first_entry(&dsp->free_block_list,
526 struct sst_mem_block, list);
527 else
528 block = list_first_entry(&dsp->used_block_list,
529 struct sst_mem_block, list);
530 block_size = block->size;
531
532 /* allocate blocks for module scratch buffers */
533 dev_dbg(dsp->dev, "allocating scratch blocks\n");
534 ret = block_alloc(scratch, &scratch->s);
535 if (ret < 0) {
536 dev_err(dsp->dev, "error: can't alloc scratch blocks\n");
537 goto err;
538 }
539
540 /* assign the same offset of scratch to each module */
541 list_for_each_entry(sst_module, &dsp->module_list, list)
542 sst_module->s.offset = scratch->s.offset;
543
544 mutex_unlock(&dsp->mutex);
545 return scratch;
546
547err:
548 list_for_each_entry_safe(block, tmp, &scratch->block_list, module_list)
549 list_del(&block->module_list);
550 mutex_unlock(&dsp->mutex);
551 return NULL;
552}
553EXPORT_SYMBOL_GPL(sst_mem_block_alloc_scratch);
554
555/* free all scratch blocks */
556void sst_mem_block_free_scratch(struct sst_dsp *dsp,
557 struct sst_module *scratch)
558{
559 struct sst_mem_block *block, *tmp;
560
561 mutex_lock(&dsp->mutex);
562
563 list_for_each_entry_safe(block, tmp, &scratch->block_list, module_list)
564 list_del(&block->module_list);
565
566 mutex_unlock(&dsp->mutex);
567}
568EXPORT_SYMBOL_GPL(sst_mem_block_free_scratch);
569
570/* get a module from it's unique ID */
571struct sst_module *sst_module_get_from_id(struct sst_dsp *dsp, u32 id)
572{
573 struct sst_module *module;
574
575 mutex_lock(&dsp->mutex);
576
577 list_for_each_entry(module, &dsp->module_list, list) {
578 if (module->id == id) {
579 mutex_unlock(&dsp->mutex);
580 return module;
581 }
582 }
583
584 mutex_unlock(&dsp->mutex);
585 return NULL;
586}
587EXPORT_SYMBOL_GPL(sst_module_get_from_id);
diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/sst-haswell-dsp.c
new file mode 100644
index 000000000000..f5ebf36af889
--- /dev/null
+++ b/sound/soc/intel/sst-haswell-dsp.c
@@ -0,0 +1,517 @@
1/*
2 * Intel Haswell SST DSP driver
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/delay.h>
18#include <linux/fs.h>
19#include <linux/slab.h>
20#include <linux/device.h>
21#include <linux/sched.h>
22#include <linux/export.h>
23#include <linux/interrupt.h>
24#include <linux/module.h>
25#include <linux/dma-mapping.h>
26#include <linux/platform_device.h>
27#include <linux/pci.h>
28#include <linux/firmware.h>
29#include <linux/pm_runtime.h>
30
31#include <linux/acpi.h>
32#include <acpi/acpi_bus.h>
33
34#include "sst-dsp.h"
35#include "sst-dsp-priv.h"
36#include "sst-haswell-ipc.h"
37
38#include <trace/events/hswadsp.h>
39
40#define SST_HSW_FW_SIGNATURE_SIZE 4
41#define SST_HSW_FW_SIGN "$SST"
42#define SST_HSW_FW_LIB_SIGN "$LIB"
43
44#define SST_WPT_SHIM_OFFSET 0xFB000
45#define SST_LP_SHIM_OFFSET 0xE7000
46#define SST_WPT_IRAM_OFFSET 0xA0000
47#define SST_LP_IRAM_OFFSET 0x80000
48
49#define SST_SHIM_PM_REG 0x84
50
51#define SST_HSW_IRAM 1
52#define SST_HSW_DRAM 2
53#define SST_HSW_REGS 3
54
55struct dma_block_info {
56 __le32 type; /* IRAM/DRAM */
57 __le32 size; /* Bytes */
58 __le32 ram_offset; /* Offset in I/DRAM */
59 __le32 rsvd; /* Reserved field */
60} __attribute__((packed));
61
62struct fw_module_info {
63 __le32 persistent_size;
64 __le32 scratch_size;
65} __attribute__((packed));
66
67struct fw_header {
68 unsigned char signature[SST_HSW_FW_SIGNATURE_SIZE]; /* FW signature */
69 __le32 file_size; /* size of fw minus this header */
70 __le32 modules; /* # of modules */
71 __le32 file_format; /* version of header format */
72 __le32 reserved[4];
73} __attribute__((packed));
74
75struct fw_module_header {
76 unsigned char signature[SST_HSW_FW_SIGNATURE_SIZE]; /* module signature */
77 __le32 mod_size; /* size of module */
78 __le32 blocks; /* # of blocks */
79 __le16 padding;
80 __le16 type; /* codec type, pp lib */
81 __le32 entry_point;
82 struct fw_module_info info;
83} __attribute__((packed));
84
85static void hsw_free(struct sst_dsp *sst);
86
87static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
88 struct fw_module_header *module)
89{
90 struct dma_block_info *block;
91 struct sst_module *mod;
92 struct sst_module_data block_data;
93 struct sst_module_template template;
94 int count;
95 void __iomem *ram;
96
97 /* TODO: allowed module types need to be configurable */
98 if (module->type != SST_HSW_MODULE_BASE_FW
99 && module->type != SST_HSW_MODULE_PCM_SYSTEM
100 && module->type != SST_HSW_MODULE_PCM
101 && module->type != SST_HSW_MODULE_PCM_REFERENCE
102 && module->type != SST_HSW_MODULE_PCM_CAPTURE
103 && module->type != SST_HSW_MODULE_LPAL)
104 return 0;
105
106 dev_dbg(dsp->dev, "new module sign 0x%s size 0x%x blocks 0x%x type 0x%x\n",
107 module->signature, module->mod_size,
108 module->blocks, module->type);
109 dev_dbg(dsp->dev, " entrypoint 0x%x\n", module->entry_point);
110 dev_dbg(dsp->dev, " persistent 0x%x scratch 0x%x\n",
111 module->info.persistent_size, module->info.scratch_size);
112
113 memset(&template, 0, sizeof(template));
114 template.id = module->type;
115 template.entry = module->entry_point;
116 template.p.size = module->info.persistent_size;
117 template.p.type = SST_MEM_DRAM;
118 template.p.data_type = SST_DATA_P;
119 template.s.size = module->info.scratch_size;
120 template.s.type = SST_MEM_DRAM;
121 template.s.data_type = SST_DATA_S;
122
123 mod = sst_module_new(fw, &template, NULL);
124 if (mod == NULL)
125 return -ENOMEM;
126
127 block = (void *)module + sizeof(*module);
128
129 for (count = 0; count < module->blocks; count++) {
130
131 if (block->size <= 0) {
132 dev_err(dsp->dev,
133 "error: block %d size invalid\n", count);
134 sst_module_free(mod);
135 return -EINVAL;
136 }
137
138 switch (block->type) {
139 case SST_HSW_IRAM:
140 ram = dsp->addr.lpe;
141 block_data.offset =
142 block->ram_offset + dsp->addr.iram_offset;
143 block_data.type = SST_MEM_IRAM;
144 break;
145 case SST_HSW_DRAM:
146 ram = dsp->addr.lpe;
147 block_data.offset = block->ram_offset;
148 block_data.type = SST_MEM_DRAM;
149 break;
150 default:
151 dev_err(dsp->dev, "error: bad type 0x%x for block 0x%x\n",
152 block->type, count);
153 sst_module_free(mod);
154 return -EINVAL;
155 }
156
157 block_data.size = block->size;
158 block_data.data_type = SST_DATA_M;
159 block_data.data = (void *)block + sizeof(*block);
160 block_data.data_offset = block_data.data - fw->dma_buf;
161
162 dev_dbg(dsp->dev, "copy firmware block %d type 0x%x "
163 "size 0x%x ==> ram %p offset 0x%x\n",
164 count, block->type, block->size, ram,
165 block->ram_offset);
166
167 sst_module_insert_fixed_block(mod, &block_data);
168
169 block = (void *)block + sizeof(*block) + block->size;
170 }
171 return 0;
172}
173
174static int hsw_parse_fw_image(struct sst_fw *sst_fw)
175{
176 struct fw_header *header;
177 struct sst_module *scratch;
178 struct fw_module_header *module;
179 struct sst_dsp *dsp = sst_fw->dsp;
180 struct sst_hsw *hsw = sst_fw->private;
181 int ret, count;
182
183 /* Read the header information from the data pointer */
184 header = (struct fw_header *)sst_fw->dma_buf;
185
186 /* verify FW */
187 if ((strncmp(header->signature, SST_HSW_FW_SIGN, 4) != 0) ||
188 (sst_fw->size != header->file_size + sizeof(*header))) {
189 dev_err(dsp->dev, "error: invalid fw sign/filesize mismatch\n");
190 return -EINVAL;
191 }
192
193 dev_dbg(dsp->dev, "header size=0x%x modules=0x%x fmt=0x%x size=%zu\n",
194 header->file_size, header->modules,
195 header->file_format, sizeof(*header));
196
197 /* parse each module */
198 module = (void *)sst_fw->dma_buf + sizeof(*header);
199 for (count = 0; count < header->modules; count++) {
200
201 /* module */
202 ret = hsw_parse_module(dsp, sst_fw, module);
203 if (ret < 0) {
204 dev_err(dsp->dev, "error: invalid module %d\n", count);
205 return ret;
206 }
207 module = (void *)module + sizeof(*module) + module->mod_size;
208 }
209
210 /* allocate persistent/scratch mem regions */
211 scratch = sst_mem_block_alloc_scratch(dsp);
212 if (scratch == NULL)
213 return -ENOMEM;
214
215 sst_hsw_set_scratch_module(hsw, scratch);
216
217 return 0;
218}
219
220static irqreturn_t hsw_irq(int irq, void *context)
221{
222 struct sst_dsp *sst = (struct sst_dsp *) context;
223 u32 isr;
224 int ret = IRQ_NONE;
225
226 spin_lock(&sst->spinlock);
227
228 /* Interrupt arrived, check src */
229 isr = sst_dsp_shim_read_unlocked(sst, SST_ISRX);
230 if (isr & SST_ISRX_DONE) {
231 trace_sst_irq_done(isr,
232 sst_dsp_shim_read_unlocked(sst, SST_IMRX));
233
234 /* Mask Done interrupt before return */
235 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX,
236 SST_IMRX_DONE, SST_IMRX_DONE);
237 ret = IRQ_WAKE_THREAD;
238 }
239
240 if (isr & SST_ISRX_BUSY) {
241 trace_sst_irq_busy(isr,
242 sst_dsp_shim_read_unlocked(sst, SST_IMRX));
243
244 /* Mask Busy interrupt before return */
245 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX,
246 SST_IMRX_BUSY, SST_IMRX_BUSY);
247 ret = IRQ_WAKE_THREAD;
248 }
249
250 spin_unlock(&sst->spinlock);
251 return ret;
252}
253
254static void hsw_boot(struct sst_dsp *sst)
255{
256 /* select SSP1 19.2MHz base clock, SSP clock 0, turn off Low Power Clock */
257 sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
258 SST_CSR_S1IOCS | SST_CSR_SBCS1 | SST_CSR_LPCS, 0x0);
259
260 /* stall DSP core, set clk to 192/96Mhz */
261 sst_dsp_shim_update_bits_unlocked(sst,
262 SST_CSR, SST_CSR_STALL | SST_CSR_DCS_MASK,
263 SST_CSR_STALL | SST_CSR_DCS(4));
264
265 /* Set 24MHz MCLK, prevent local clock gating, enable SSP0 clock */
266 sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL,
267 SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0,
268 SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0);
269
270 /* disable DMA finish function for SSP0 & SSP1 */
271 sst_dsp_shim_update_bits_unlocked(sst, SST_CSR2, SST_CSR2_SDFD_SSP1,
272 SST_CSR2_SDFD_SSP1);
273
274 /* enable DMA engine 0,1 all channels to access host memory */
275 sst_dsp_shim_update_bits_unlocked(sst, SST_HDMC,
276 SST_HDMC_HDDA1(0xff) | SST_HDMC_HDDA0(0xff),
277 SST_HDMC_HDDA1(0xff) | SST_HDMC_HDDA0(0xff));
278
279 /* disable all clock gating */
280 writel(0x0, sst->addr.pci_cfg + SST_VDRTCTL2);
281
282 /* set DSP to RUN */
283 sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, SST_CSR_STALL, 0x0);
284}
285
286static void hsw_reset(struct sst_dsp *sst)
287{
288 /* put DSP into reset and stall */
289 sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
290 SST_CSR_RST | SST_CSR_STALL, SST_CSR_RST | SST_CSR_STALL);
291
292 /* keep in reset for 10ms */
293 mdelay(10);
294
295 /* take DSP out of reset and keep stalled for FW loading */
296 sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
297 SST_CSR_RST | SST_CSR_STALL, SST_CSR_STALL);
298}
299
300struct sst_adsp_memregion {
301 u32 start;
302 u32 end;
303 int blocks;
304 enum sst_mem_type type;
305};
306
307/* lynx point ADSP mem regions */
308static const struct sst_adsp_memregion lp_region[] = {
309 {0x00000, 0x40000, 8, SST_MEM_DRAM}, /* D-SRAM0 - 8 * 32kB */
310 {0x40000, 0x80000, 8, SST_MEM_DRAM}, /* D-SRAM1 - 8 * 32kB */
311 {0x80000, 0xE0000, 12, SST_MEM_IRAM}, /* I-SRAM - 12 * 32kB */
312};
313
314/* wild cat point ADSP mem regions */
315static const struct sst_adsp_memregion wpt_region[] = {
316 {0x00000, 0x40000, 8, SST_MEM_DRAM}, /* D-SRAM0 - 8 * 32kB */
317 {0x40000, 0x80000, 8, SST_MEM_DRAM}, /* D-SRAM1 - 8 * 32kB */
318 {0x80000, 0xA0000, 4, SST_MEM_DRAM}, /* D-SRAM2 - 4 * 32kB */
319 {0xA0000, 0xF0000, 10, SST_MEM_IRAM}, /* I-SRAM - 10 * 32kB */
320};
321
322static int hsw_acpi_resource_map(struct sst_dsp *sst, struct sst_pdata *pdata)
323{
324 /* ADSP DRAM & IRAM */
325 sst->addr.lpe_base = pdata->lpe_base;
326 sst->addr.lpe = ioremap(pdata->lpe_base, pdata->lpe_size);
327 if (!sst->addr.lpe)
328 return -ENODEV;
329
330 /* ADSP PCI MMIO config space */
331 sst->addr.pci_cfg = ioremap(pdata->pcicfg_base, pdata->pcicfg_size);
332 if (!sst->addr.pci_cfg) {
333 iounmap(sst->addr.lpe);
334 return -ENODEV;
335 }
336
337 /* SST Shim */
338 sst->addr.shim = sst->addr.lpe + sst->addr.shim_offset;
339 return 0;
340}
341
342static u32 hsw_block_get_bit(struct sst_mem_block *block)
343{
344 u32 bit = 0, shift = 0;
345
346 switch (block->type) {
347 case SST_MEM_DRAM:
348 shift = 16;
349 break;
350 case SST_MEM_IRAM:
351 shift = 6;
352 break;
353 default:
354 return 0;
355 }
356
357 bit = 1 << (block->index + shift);
358
359 return bit;
360}
361
362/* enable 32kB memory block - locks held by caller */
363static int hsw_block_enable(struct sst_mem_block *block)
364{
365 struct sst_dsp *sst = block->dsp;
366 u32 bit, val;
367
368 if (block->users++ > 0)
369 return 0;
370
371 dev_dbg(block->dsp->dev, " enabled block %d:%d at offset 0x%x\n",
372 block->type, block->index, block->offset);
373
374 val = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
375 bit = hsw_block_get_bit(block);
376 writel(val & ~bit, sst->addr.pci_cfg + SST_VDRTCTL0);
377
378 /* wait 18 DSP clock ticks */
379 udelay(10);
380
381 return 0;
382}
383
384/* disable 32kB memory block - locks held by caller */
385static int hsw_block_disable(struct sst_mem_block *block)
386{
387 struct sst_dsp *sst = block->dsp;
388 u32 bit, val;
389
390 if (--block->users > 0)
391 return 0;
392
393 dev_dbg(block->dsp->dev, " disabled block %d:%d at offset 0x%x\n",
394 block->type, block->index, block->offset);
395
396 val = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
397 bit = hsw_block_get_bit(block);
398 writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0);
399
400 return 0;
401}
402
403static struct sst_block_ops sst_hsw_ops = {
404 .enable = hsw_block_enable,
405 .disable = hsw_block_disable,
406};
407
408static int hsw_enable_shim(struct sst_dsp *sst)
409{
410 int tries = 10;
411 u32 reg;
412
413 /* enable shim */
414 reg = readl(sst->addr.pci_cfg + SST_SHIM_PM_REG);
415 writel(reg & ~0x3, sst->addr.pci_cfg + SST_SHIM_PM_REG);
416
417 /* check that ADSP shim is enabled */
418 while (tries--) {
419 reg = sst_dsp_shim_read_unlocked(sst, SST_CSR);
420 if (reg != 0xffffffff)
421 return 0;
422
423 msleep(1);
424 }
425
426 return -ENODEV;
427}
428
429static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
430{
431 const struct sst_adsp_memregion *region;
432 struct device *dev;
433 int ret = -ENODEV, i, j, region_count;
434 u32 offset, size;
435
436 dev = sst->dev;
437
438 switch (sst->id) {
439 case SST_DEV_ID_LYNX_POINT:
440 region = lp_region;
441 region_count = ARRAY_SIZE(lp_region);
442 sst->addr.iram_offset = SST_LP_IRAM_OFFSET;
443 sst->addr.shim_offset = SST_LP_SHIM_OFFSET;
444 break;
445 case SST_DEV_ID_WILDCAT_POINT:
446 region = wpt_region;
447 region_count = ARRAY_SIZE(wpt_region);
448 sst->addr.iram_offset = SST_WPT_IRAM_OFFSET;
449 sst->addr.shim_offset = SST_WPT_SHIM_OFFSET;
450 break;
451 default:
452 dev_err(dev, "error: failed to get mem resources\n");
453 return ret;
454 }
455
456 ret = hsw_acpi_resource_map(sst, pdata);
457 if (ret < 0) {
458 dev_err(dev, "error: failed to map resources\n");
459 return ret;
460 }
461
462 /* enable the DSP SHIM */
463 ret = hsw_enable_shim(sst);
464 if (ret < 0) {
465 dev_err(dev, "error: failed to set DSP D0 and reset SHIM\n");
466 return ret;
467 }
468
469 ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
470 if (ret)
471 return ret;
472
473 /* Enable Interrupt from both sides */
474 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX, 0x3, 0x0);
475 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRD,
476 (0x3 | 0x1 << 16 | 0x3 << 21), 0x0);
477
478 /* register DSP memory blocks - ideally we should get this from ACPI */
479 for (i = 0; i < region_count; i++) {
480 offset = region[i].start;
481 size = (region[i].end - region[i].start) / region[i].blocks;
482
483 /* register individual memory blocks */
484 for (j = 0; j < region[i].blocks; j++) {
485 sst_mem_block_register(sst, offset, size,
486 region[i].type, &sst_hsw_ops, j, sst);
487 offset += size;
488 }
489 }
490
491 /* set default power gating mask */
492 writel(0x0, sst->addr.pci_cfg + SST_VDRTCTL0);
493
494 return 0;
495}
496
497static void hsw_free(struct sst_dsp *sst)
498{
499 sst_mem_block_unregister_all(sst);
500 iounmap(sst->addr.lpe);
501 iounmap(sst->addr.pci_cfg);
502}
503
504struct sst_ops haswell_ops = {
505 .reset = hsw_reset,
506 .boot = hsw_boot,
507 .write = sst_shim32_write,
508 .read = sst_shim32_read,
509 .write64 = sst_shim32_write64,
510 .read64 = sst_shim32_read64,
511 .ram_read = sst_memcpy_fromio_32,
512 .ram_write = sst_memcpy_toio_32,
513 .irq_handler = hsw_irq,
514 .init = hsw_init,
515 .free = hsw_free,
516 .parse_fw = hsw_parse_fw_image,
517};
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c
new file mode 100644
index 000000000000..f46bb4ddde6f
--- /dev/null
+++ b/sound/soc/intel/sst-haswell-ipc.c
@@ -0,0 +1,1785 @@
1/*
2 * Intel SST Haswell/Broadwell IPC Support
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/types.h>
18#include <linux/kernel.h>
19#include <linux/list.h>
20#include <linux/device.h>
21#include <linux/wait.h>
22#include <linux/spinlock.h>
23#include <linux/workqueue.h>
24#include <linux/export.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/sched.h>
28#include <linux/list.h>
29#include <linux/platform_device.h>
30#include <linux/kthread.h>
31#include <linux/firmware.h>
32#include <linux/dma-mapping.h>
33#include <linux/debugfs.h>
34
35#include "sst-haswell-ipc.h"
36#include "sst-dsp.h"
37#include "sst-dsp-priv.h"
38
39/* Global Message - Generic */
40#define IPC_GLB_TYPE_SHIFT 24
41#define IPC_GLB_TYPE_MASK (0x1f << IPC_GLB_TYPE_SHIFT)
42#define IPC_GLB_TYPE(x) (x << IPC_GLB_TYPE_SHIFT)
43
44/* Global Message - Reply */
45#define IPC_GLB_REPLY_SHIFT 0
46#define IPC_GLB_REPLY_MASK (0x1f << IPC_GLB_REPLY_SHIFT)
47#define IPC_GLB_REPLY_TYPE(x) (x << IPC_GLB_REPLY_TYPE_SHIFT)
48
49/* Stream Message - Generic */
50#define IPC_STR_TYPE_SHIFT 20
51#define IPC_STR_TYPE_MASK (0xf << IPC_STR_TYPE_SHIFT)
52#define IPC_STR_TYPE(x) (x << IPC_STR_TYPE_SHIFT)
53#define IPC_STR_ID_SHIFT 16
54#define IPC_STR_ID_MASK (0xf << IPC_STR_ID_SHIFT)
55#define IPC_STR_ID(x) (x << IPC_STR_ID_SHIFT)
56
57/* Stream Message - Reply */
58#define IPC_STR_REPLY_SHIFT 0
59#define IPC_STR_REPLY_MASK (0x1f << IPC_STR_REPLY_SHIFT)
60
61/* Stream Stage Message - Generic */
62#define IPC_STG_TYPE_SHIFT 12
63#define IPC_STG_TYPE_MASK (0xf << IPC_STG_TYPE_SHIFT)
64#define IPC_STG_TYPE(x) (x << IPC_STG_TYPE_SHIFT)
65#define IPC_STG_ID_SHIFT 10
66#define IPC_STG_ID_MASK (0x3 << IPC_STG_ID_SHIFT)
67#define IPC_STG_ID(x) (x << IPC_STG_ID_SHIFT)
68
69/* Stream Stage Message - Reply */
70#define IPC_STG_REPLY_SHIFT 0
71#define IPC_STG_REPLY_MASK (0x1f << IPC_STG_REPLY_SHIFT)
72
73/* Debug Log Message - Generic */
74#define IPC_LOG_OP_SHIFT 20
75#define IPC_LOG_OP_MASK (0xf << IPC_LOG_OP_SHIFT)
76#define IPC_LOG_OP_TYPE(x) (x << IPC_LOG_OP_SHIFT)
77#define IPC_LOG_ID_SHIFT 16
78#define IPC_LOG_ID_MASK (0xf << IPC_LOG_ID_SHIFT)
79#define IPC_LOG_ID(x) (x << IPC_LOG_ID_SHIFT)
80
81/* IPC message timeout (msecs) */
82#define IPC_TIMEOUT_MSECS 300
83#define IPC_BOOT_MSECS 200
84#define IPC_MSG_WAIT 0
85#define IPC_MSG_NOWAIT 1
86
87/* Firmware Ready Message */
88#define IPC_FW_READY (0x1 << 29)
89#define IPC_STATUS_MASK (0x3 << 30)
90
91#define IPC_EMPTY_LIST_SIZE 8
92#define IPC_MAX_STREAMS 4
93
94/* Mailbox */
95#define IPC_MAX_MAILBOX_BYTES 256
96
97/* Global Message - Types and Replies */
98enum ipc_glb_type {
99 IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */
100 IPC_GLB_PERFORMANCE_MONITOR = 1, /* Performance monitoring actions */
101 IPC_GLB_ALLOCATE_STREAM = 3, /* Request to allocate new stream */
102 IPC_GLB_FREE_STREAM = 4, /* Request to free stream */
103 IPC_GLB_GET_FW_CAPABILITIES = 5, /* Retrieves firmware capabilities */
104 IPC_GLB_STREAM_MESSAGE = 6, /* Message directed to stream or its stages */
105 /* Request to store firmware context during D0->D3 transition */
106 IPC_GLB_REQUEST_DUMP = 7,
107 /* Request to restore firmware context during D3->D0 transition */
108 IPC_GLB_RESTORE_CONTEXT = 8,
109 IPC_GLB_GET_DEVICE_FORMATS = 9, /* Set device format */
110 IPC_GLB_SET_DEVICE_FORMATS = 10, /* Get device format */
111 IPC_GLB_SHORT_REPLY = 11,
112 IPC_GLB_ENTER_DX_STATE = 12,
113 IPC_GLB_GET_MIXER_STREAM_INFO = 13, /* Request mixer stream params */
114 IPC_GLB_DEBUG_LOG_MESSAGE = 14, /* Message to or from the debug logger. */
115 IPC_GLB_REQUEST_TRANSFER = 16, /* < Request Transfer for host */
116 IPC_GLB_MAX_IPC_MESSAGE_TYPE = 17, /* Maximum message number */
117};
118
119enum ipc_glb_reply {
120 IPC_GLB_REPLY_SUCCESS = 0, /* The operation was successful. */
121 IPC_GLB_REPLY_ERROR_INVALID_PARAM = 1, /* Invalid parameter was passed. */
122 IPC_GLB_REPLY_UNKNOWN_MESSAGE_TYPE = 2, /* Uknown message type was resceived. */
123 IPC_GLB_REPLY_OUT_OF_RESOURCES = 3, /* No resources to satisfy the request. */
124 IPC_GLB_REPLY_BUSY = 4, /* The system or resource is busy. */
125 IPC_GLB_REPLY_PENDING = 5, /* The action was scheduled for processing. */
126 IPC_GLB_REPLY_FAILURE = 6, /* Critical error happened. */
127 IPC_GLB_REPLY_INVALID_REQUEST = 7, /* Request can not be completed. */
128 IPC_GLB_REPLY_STAGE_UNINITIALIZED = 8, /* Processing stage was uninitialized. */
129 IPC_GLB_REPLY_NOT_FOUND = 9, /* Required resource can not be found. */
130 IPC_GLB_REPLY_SOURCE_NOT_STARTED = 10, /* Source was not started. */
131};
132
133/* Stream Message - Types */
134enum ipc_str_operation {
135 IPC_STR_RESET = 0,
136 IPC_STR_PAUSE = 1,
137 IPC_STR_RESUME = 2,
138 IPC_STR_STAGE_MESSAGE = 3,
139 IPC_STR_NOTIFICATION = 4,
140 IPC_STR_MAX_MESSAGE
141};
142
143/* Stream Stage Message Types */
144enum ipc_stg_operation {
145 IPC_STG_GET_VOLUME = 0,
146 IPC_STG_SET_VOLUME,
147 IPC_STG_SET_WRITE_POSITION,
148 IPC_STG_SET_FX_ENABLE,
149 IPC_STG_SET_FX_DISABLE,
150 IPC_STG_SET_FX_GET_PARAM,
151 IPC_STG_SET_FX_SET_PARAM,
152 IPC_STG_SET_FX_GET_INFO,
153 IPC_STG_MUTE_LOOPBACK,
154 IPC_STG_MAX_MESSAGE
155};
156
157/* Stream Stage Message Types For Notification*/
158enum ipc_stg_operation_notify {
159 IPC_POSITION_CHANGED = 0,
160 IPC_STG_GLITCH,
161 IPC_STG_MAX_NOTIFY
162};
163
164enum ipc_glitch_type {
165 IPC_GLITCH_UNDERRUN = 1,
166 IPC_GLITCH_DECODER_ERROR,
167 IPC_GLITCH_DOUBLED_WRITE_POS,
168 IPC_GLITCH_MAX
169};
170
171/* Debug Control */
172enum ipc_debug_operation {
173 IPC_DEBUG_ENABLE_LOG = 0,
174 IPC_DEBUG_DISABLE_LOG = 1,
175 IPC_DEBUG_REQUEST_LOG_DUMP = 2,
176 IPC_DEBUG_NOTIFY_LOG_DUMP = 3,
177 IPC_DEBUG_MAX_DEBUG_LOG
178};
179
180/* Firmware Ready */
181struct sst_hsw_ipc_fw_ready {
182 u32 inbox_offset;
183 u32 outbox_offset;
184 u32 inbox_size;
185 u32 outbox_size;
186 u32 fw_info_size;
187 u8 fw_info[1];
188} __attribute__((packed));
189
190struct ipc_message {
191 struct list_head list;
192 u32 header;
193
194 /* direction wrt host CPU */
195 char tx_data[IPC_MAX_MAILBOX_BYTES];
196 size_t tx_size;
197 char rx_data[IPC_MAX_MAILBOX_BYTES];
198 size_t rx_size;
199
200 wait_queue_head_t waitq;
201 bool pending;
202 bool complete;
203 bool wait;
204 int errno;
205};
206
207struct sst_hsw_stream;
208struct sst_hsw;
209
210/* Stream infomation */
211struct sst_hsw_stream {
212 /* configuration */
213 struct sst_hsw_ipc_stream_alloc_req request;
214 struct sst_hsw_ipc_stream_alloc_reply reply;
215 struct sst_hsw_ipc_stream_free_req free_req;
216
217 /* Mixer info */
218 u32 mute_volume[SST_HSW_NO_CHANNELS];
219 u32 mute[SST_HSW_NO_CHANNELS];
220
221 /* runtime info */
222 struct sst_hsw *hsw;
223 int host_id;
224 bool commited;
225 bool running;
226
227 /* Notification work */
228 struct work_struct notify_work;
229 u32 header;
230
231 /* Position info from DSP */
232 struct sst_hsw_ipc_stream_set_position wpos;
233 struct sst_hsw_ipc_stream_get_position rpos;
234 struct sst_hsw_ipc_stream_glitch_position glitch;
235
236 /* Volume info */
237 struct sst_hsw_ipc_volume_req vol_req;
238
239 /* driver callback */
240 u32 (*notify_position)(struct sst_hsw_stream *stream, void *data);
241 void *pdata;
242
243 struct list_head node;
244};
245
246/* FW log ring information */
247struct sst_hsw_log_stream {
248 dma_addr_t dma_addr;
249 unsigned char *dma_area;
250 unsigned char *ring_descr;
251 int pages;
252 int size;
253
254 /* Notification work */
255 struct work_struct notify_work;
256 wait_queue_head_t readers_wait_q;
257 struct mutex rw_mutex;
258
259 u32 last_pos;
260 u32 curr_pos;
261 u32 reader_pos;
262
263 /* fw log config */
264 u32 config[SST_HSW_FW_LOG_CONFIG_DWORDS];
265
266 struct sst_hsw *hsw;
267};
268
269/* SST Haswell IPC data */
270struct sst_hsw {
271 struct device *dev;
272 struct sst_dsp *dsp;
273 struct platform_device *pdev_pcm;
274
275 /* FW config */
276 struct sst_hsw_ipc_fw_ready fw_ready;
277 struct sst_hsw_ipc_fw_version version;
278 struct sst_module *scratch;
279 bool fw_done;
280
281 /* stream */
282 struct list_head stream_list;
283
284 /* global mixer */
285 struct sst_hsw_ipc_stream_info_reply mixer_info;
286 enum sst_hsw_volume_curve curve_type;
287 u32 curve_duration;
288 u32 mute[SST_HSW_NO_CHANNELS];
289 u32 mute_volume[SST_HSW_NO_CHANNELS];
290
291 /* DX */
292 struct sst_hsw_ipc_dx_reply dx;
293
294 /* boot */
295 wait_queue_head_t boot_wait;
296 bool boot_complete;
297 bool shutdown;
298
299 /* IPC messaging */
300 struct list_head tx_list;
301 struct list_head rx_list;
302 struct list_head empty_list;
303 wait_queue_head_t wait_txq;
304 struct task_struct *tx_thread;
305 struct kthread_worker kworker;
306 struct kthread_work kwork;
307 bool pending;
308 struct ipc_message *msg;
309
310 /* FW log stream */
311 struct sst_hsw_log_stream log_stream;
312};
313
314#define CREATE_TRACE_POINTS
315#include <trace/events/hswadsp.h>
316
317static inline u32 msg_get_global_type(u32 msg)
318{
319 return (msg & IPC_GLB_TYPE_MASK) >> IPC_GLB_TYPE_SHIFT;
320}
321
322static inline u32 msg_get_global_reply(u32 msg)
323{
324 return (msg & IPC_GLB_REPLY_MASK) >> IPC_GLB_REPLY_SHIFT;
325}
326
327static inline u32 msg_get_stream_type(u32 msg)
328{
329 return (msg & IPC_STR_TYPE_MASK) >> IPC_STR_TYPE_SHIFT;
330}
331
332static inline u32 msg_get_stage_type(u32 msg)
333{
334 return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT;
335}
336
337static inline u32 msg_set_stage_type(u32 msg, u32 type)
338{
339 return (msg & ~IPC_STG_TYPE_MASK) +
340 (type << IPC_STG_TYPE_SHIFT);
341}
342
343static inline u32 msg_get_stream_id(u32 msg)
344{
345 return (msg & IPC_STR_ID_MASK) >> IPC_STR_ID_SHIFT;
346}
347
348static inline u32 msg_get_notify_reason(u32 msg)
349{
350 return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT;
351}
352
353u32 create_channel_map(enum sst_hsw_channel_config config)
354{
355 switch (config) {
356 case SST_HSW_CHANNEL_CONFIG_MONO:
357 return (0xFFFFFFF0 | SST_HSW_CHANNEL_CENTER);
358 case SST_HSW_CHANNEL_CONFIG_STEREO:
359 return (0xFFFFFF00 | SST_HSW_CHANNEL_LEFT
360 | (SST_HSW_CHANNEL_RIGHT << 4));
361 case SST_HSW_CHANNEL_CONFIG_2_POINT_1:
362 return (0xFFFFF000 | SST_HSW_CHANNEL_LEFT
363 | (SST_HSW_CHANNEL_RIGHT << 4)
364 | (SST_HSW_CHANNEL_LFE << 8 ));
365 case SST_HSW_CHANNEL_CONFIG_3_POINT_0:
366 return (0xFFFFF000 | SST_HSW_CHANNEL_LEFT
367 | (SST_HSW_CHANNEL_CENTER << 4)
368 | (SST_HSW_CHANNEL_RIGHT << 8));
369 case SST_HSW_CHANNEL_CONFIG_3_POINT_1:
370 return (0xFFFF0000 | SST_HSW_CHANNEL_LEFT
371 | (SST_HSW_CHANNEL_CENTER << 4)
372 | (SST_HSW_CHANNEL_RIGHT << 8)
373 | (SST_HSW_CHANNEL_LFE << 12));
374 case SST_HSW_CHANNEL_CONFIG_QUATRO:
375 return (0xFFFF0000 | SST_HSW_CHANNEL_LEFT
376 | (SST_HSW_CHANNEL_RIGHT << 4)
377 | (SST_HSW_CHANNEL_LEFT_SURROUND << 8)
378 | (SST_HSW_CHANNEL_RIGHT_SURROUND << 12));
379 case SST_HSW_CHANNEL_CONFIG_4_POINT_0:
380 return (0xFFFF0000 | SST_HSW_CHANNEL_LEFT
381 | (SST_HSW_CHANNEL_CENTER << 4)
382 | (SST_HSW_CHANNEL_RIGHT << 8)
383 | (SST_HSW_CHANNEL_CENTER_SURROUND << 12));
384 case SST_HSW_CHANNEL_CONFIG_5_POINT_0:
385 return (0xFFF00000 | SST_HSW_CHANNEL_LEFT
386 | (SST_HSW_CHANNEL_CENTER << 4)
387 | (SST_HSW_CHANNEL_RIGHT << 8)
388 | (SST_HSW_CHANNEL_LEFT_SURROUND << 12)
389 | (SST_HSW_CHANNEL_RIGHT_SURROUND << 16));
390 case SST_HSW_CHANNEL_CONFIG_5_POINT_1:
391 return (0xFF000000 | SST_HSW_CHANNEL_CENTER
392 | (SST_HSW_CHANNEL_LEFT << 4)
393 | (SST_HSW_CHANNEL_RIGHT << 8)
394 | (SST_HSW_CHANNEL_LEFT_SURROUND << 12)
395 | (SST_HSW_CHANNEL_RIGHT_SURROUND << 16)
396 | (SST_HSW_CHANNEL_LFE << 20));
397 case SST_HSW_CHANNEL_CONFIG_DUAL_MONO:
398 return (0xFFFFFF00 | SST_HSW_CHANNEL_LEFT
399 | (SST_HSW_CHANNEL_LEFT << 4));
400 default:
401 return 0xFFFFFFFF;
402 }
403}
404
405static struct sst_hsw_stream *get_stream_by_id(struct sst_hsw *hsw,
406 int stream_id)
407{
408 struct sst_hsw_stream *stream;
409
410 list_for_each_entry(stream, &hsw->stream_list, node) {
411 if (stream->reply.stream_hw_id == stream_id)
412 return stream;
413 }
414
415 return NULL;
416}
417
418static void ipc_shim_dbg(struct sst_hsw *hsw, const char *text)
419{
420 struct sst_dsp *sst = hsw->dsp;
421 u32 isr, ipcd, imrx, ipcx;
422
423 ipcx = sst_dsp_shim_read_unlocked(sst, SST_IPCX);
424 isr = sst_dsp_shim_read_unlocked(sst, SST_ISRX);
425 ipcd = sst_dsp_shim_read_unlocked(sst, SST_IPCD);
426 imrx = sst_dsp_shim_read_unlocked(sst, SST_IMRX);
427
428 dev_err(hsw->dev, "ipc: --%s-- ipcx 0x%8.8x isr 0x%8.8x ipcd 0x%8.8x imrx 0x%8.8x\n",
429 text, ipcx, isr, ipcd, imrx);
430}
431
432/* locks held by caller */
433static struct ipc_message *msg_get_empty(struct sst_hsw *hsw)
434{
435 struct ipc_message *msg = NULL;
436
437 if (!list_empty(&hsw->empty_list)) {
438 msg = list_first_entry(&hsw->empty_list, struct ipc_message,
439 list);
440 list_del(&msg->list);
441 }
442
443 return msg;
444}
445
446static void ipc_tx_msgs(struct kthread_work *work)
447{
448 struct sst_hsw *hsw =
449 container_of(work, struct sst_hsw, kwork);
450 struct ipc_message *msg;
451 unsigned long flags;
452 u32 ipcx;
453
454 spin_lock_irqsave(&hsw->dsp->spinlock, flags);
455
456 if (list_empty(&hsw->tx_list) || hsw->pending) {
457 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
458 return;
459 }
460
461 /* if the DSP is busy we will TX messages after IRQ */
462 ipcx = sst_dsp_shim_read_unlocked(hsw->dsp, SST_IPCX);
463 if (ipcx & SST_IPCX_BUSY) {
464 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
465 return;
466 }
467
468 msg = list_first_entry(&hsw->tx_list, struct ipc_message, list);
469
470 list_move(&msg->list, &hsw->rx_list);
471
472 /* send the message */
473 sst_dsp_outbox_write(hsw->dsp, msg->tx_data, msg->tx_size);
474 sst_dsp_ipc_msg_tx(hsw->dsp, msg->header | SST_IPCX_BUSY);
475
476 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
477}
478
479/* locks held by caller */
480static void tx_msg_reply_complete(struct sst_hsw *hsw, struct ipc_message *msg)
481{
482 msg->complete = true;
483 trace_ipc_reply("completed", msg->header);
484
485 if (!msg->wait)
486 list_add_tail(&msg->list, &hsw->empty_list);
487 else
488 wake_up(&msg->waitq);
489}
490
491static int tx_wait_done(struct sst_hsw *hsw, struct ipc_message *msg,
492 void *rx_data)
493{
494 unsigned long flags;
495 int ret;
496
497 /* wait for DSP completion (in all cases atm inc pending) */
498 ret = wait_event_timeout(msg->waitq, msg->complete,
499 msecs_to_jiffies(IPC_TIMEOUT_MSECS));
500
501 spin_lock_irqsave(&hsw->dsp->spinlock, flags);
502 if (ret == 0) {
503 ipc_shim_dbg(hsw, "message timeout");
504
505 trace_ipc_error("error message timeout for", msg->header);
506 ret = -ETIMEDOUT;
507 } else {
508
509 /* copy the data returned from DSP */
510 if (msg->rx_size)
511 memcpy(rx_data, msg->rx_data, msg->rx_size);
512 ret = msg->errno;
513 }
514
515 list_add_tail(&msg->list, &hsw->empty_list);
516 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
517 return ret;
518}
519
520static int ipc_tx_message(struct sst_hsw *hsw, u32 header, void *tx_data,
521 size_t tx_bytes, void *rx_data, size_t rx_bytes, int wait)
522{
523 struct ipc_message *msg;
524 unsigned long flags;
525
526 spin_lock_irqsave(&hsw->dsp->spinlock, flags);
527
528 msg = msg_get_empty(hsw);
529 if (msg == NULL) {
530 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
531 return -EBUSY;
532 }
533
534 if (tx_bytes)
535 memcpy(msg->tx_data, tx_data, tx_bytes);
536
537 msg->header = header;
538 msg->tx_size = tx_bytes;
539 msg->rx_size = rx_bytes;
540 msg->wait = wait;
541 msg->errno = 0;
542 msg->pending = false;
543 msg->complete = false;
544
545 list_add_tail(&msg->list, &hsw->tx_list);
546 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
547
548 queue_kthread_work(&hsw->kworker, &hsw->kwork);
549
550 if (wait)
551 return tx_wait_done(hsw, msg, rx_data);
552 else
553 return 0;
554}
555
556static inline int ipc_tx_message_wait(struct sst_hsw *hsw, u32 header,
557 void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes)
558{
559 return ipc_tx_message(hsw, header, tx_data, tx_bytes, rx_data,
560 rx_bytes, 1);
561}
562
563static inline int ipc_tx_message_nowait(struct sst_hsw *hsw, u32 header,
564 void *tx_data, size_t tx_bytes)
565{
566 return ipc_tx_message(hsw, header, tx_data, tx_bytes, NULL, 0, 0);
567}
568
569static void hsw_fw_ready(struct sst_hsw *hsw, u32 header)
570{
571 struct sst_hsw_ipc_fw_ready fw_ready;
572 u32 offset;
573
574 offset = (header & 0x1FFFFFFF) << 3;
575
576 dev_dbg(hsw->dev, "ipc: DSP is ready 0x%8.8x offset %d\n",
577 header, offset);
578
579 /* copy data from the DSP FW ready offset */
580 sst_dsp_read(hsw->dsp, &fw_ready, offset, sizeof(fw_ready));
581
582 sst_dsp_mailbox_init(hsw->dsp, fw_ready.inbox_offset,
583 fw_ready.inbox_size, fw_ready.outbox_offset,
584 fw_ready.outbox_size);
585
586 hsw->boot_complete = true;
587 wake_up(&hsw->boot_wait);
588
589 dev_dbg(hsw->dev, " mailbox upstream 0x%x - size 0x%x\n",
590 fw_ready.inbox_offset, fw_ready.inbox_size);
591 dev_dbg(hsw->dev, " mailbox downstream 0x%x - size 0x%x\n",
592 fw_ready.outbox_offset, fw_ready.outbox_size);
593}
594
595static void hsw_notification_work(struct work_struct *work)
596{
597 struct sst_hsw_stream *stream = container_of(work,
598 struct sst_hsw_stream, notify_work);
599 struct sst_hsw_ipc_stream_glitch_position *glitch = &stream->glitch;
600 struct sst_hsw_ipc_stream_get_position *pos = &stream->rpos;
601 struct sst_hsw *hsw = stream->hsw;
602 u32 reason;
603
604 reason = msg_get_notify_reason(stream->header);
605
606 switch (reason) {
607 case IPC_STG_GLITCH:
608 trace_ipc_notification("DSP stream under/overrun",
609 stream->reply.stream_hw_id);
610 sst_dsp_inbox_read(hsw->dsp, glitch, sizeof(*glitch));
611
612 dev_err(hsw->dev, "glitch %d pos 0x%x write pos 0x%x\n",
613 glitch->glitch_type, glitch->present_pos,
614 glitch->write_pos);
615 break;
616
617 case IPC_POSITION_CHANGED:
618 trace_ipc_notification("DSP stream position changed for",
619 stream->reply.stream_hw_id);
620 sst_dsp_inbox_read(hsw->dsp, pos, sizeof(pos));
621
622 if (stream->notify_position)
623 stream->notify_position(stream, stream->pdata);
624
625 break;
626 default:
627 dev_err(hsw->dev, "error: unknown notification 0x%x\n",
628 stream->header);
629 break;
630 }
631
632 /* tell DSP that notification has been handled */
633 sst_dsp_shim_update_bits_unlocked(hsw->dsp, SST_IPCD,
634 SST_IPCD_BUSY | SST_IPCD_DONE, SST_IPCD_DONE);
635
636 /* unmask busy interrupt */
637 sst_dsp_shim_update_bits_unlocked(hsw->dsp, SST_IMRX, SST_IMRX_BUSY, 0);
638}
639
640static struct ipc_message *reply_find_msg(struct sst_hsw *hsw, u32 header)
641{
642 struct ipc_message *msg;
643
644 /* clear reply bits & status bits */
645 header &= ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
646
647 if (list_empty(&hsw->rx_list)) {
648 dev_err(hsw->dev, "error: rx list empty but received 0x%x\n",
649 header);
650 return NULL;
651 }
652
653 list_for_each_entry(msg, &hsw->rx_list, list) {
654 if (msg->header == header)
655 return msg;
656 }
657
658 return NULL;
659}
660
661static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg)
662{
663 struct sst_hsw_stream *stream;
664 u32 header = msg->header & ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
665 u32 stream_id = msg_get_stream_id(header);
666 u32 stream_msg = msg_get_stream_type(header);
667
668 stream = get_stream_by_id(hsw, stream_id);
669 if (stream == NULL)
670 return;
671
672 switch (stream_msg) {
673 case IPC_STR_STAGE_MESSAGE:
674 case IPC_STR_NOTIFICATION:
675 case IPC_STR_RESET:
676 break;
677 case IPC_STR_PAUSE:
678 stream->running = false;
679 trace_ipc_notification("stream paused",
680 stream->reply.stream_hw_id);
681 break;
682 case IPC_STR_RESUME:
683 stream->running = true;
684 trace_ipc_notification("stream running",
685 stream->reply.stream_hw_id);
686 break;
687 }
688}
689
690static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
691{
692 struct ipc_message *msg;
693 u32 reply = msg_get_global_reply(header);
694
695 trace_ipc_reply("processing -->", header);
696
697 msg = reply_find_msg(hsw, header);
698 if (msg == NULL) {
699 trace_ipc_error("error: can't find message header", header);
700 return -EIO;
701 }
702
703 /* first process the header */
704 switch (reply) {
705 case IPC_GLB_REPLY_PENDING:
706 trace_ipc_pending_reply("received", header);
707 msg->pending = true;
708 hsw->pending = true;
709 return 1;
710 case IPC_GLB_REPLY_SUCCESS:
711 if (msg->pending) {
712 trace_ipc_pending_reply("completed", header);
713 sst_dsp_inbox_read(hsw->dsp, msg->rx_data,
714 msg->rx_size);
715 hsw->pending = false;
716 } else {
717 /* copy data from the DSP */
718 sst_dsp_outbox_read(hsw->dsp, msg->rx_data,
719 msg->rx_size);
720 }
721 break;
722 /* these will be rare - but useful for debug */
723 case IPC_GLB_REPLY_UNKNOWN_MESSAGE_TYPE:
724 trace_ipc_error("error: unknown message type", header);
725 msg->errno = -EBADMSG;
726 break;
727 case IPC_GLB_REPLY_OUT_OF_RESOURCES:
728 trace_ipc_error("error: out of resources", header);
729 msg->errno = -ENOMEM;
730 break;
731 case IPC_GLB_REPLY_BUSY:
732 trace_ipc_error("error: reply busy", header);
733 msg->errno = -EBUSY;
734 break;
735 case IPC_GLB_REPLY_FAILURE:
736 trace_ipc_error("error: reply failure", header);
737 msg->errno = -EINVAL;
738 break;
739 case IPC_GLB_REPLY_STAGE_UNINITIALIZED:
740 trace_ipc_error("error: stage uninitialized", header);
741 msg->errno = -EINVAL;
742 break;
743 case IPC_GLB_REPLY_NOT_FOUND:
744 trace_ipc_error("error: reply not found", header);
745 msg->errno = -EINVAL;
746 break;
747 case IPC_GLB_REPLY_SOURCE_NOT_STARTED:
748 trace_ipc_error("error: source not started", header);
749 msg->errno = -EINVAL;
750 break;
751 case IPC_GLB_REPLY_INVALID_REQUEST:
752 trace_ipc_error("error: invalid request", header);
753 msg->errno = -EINVAL;
754 break;
755 case IPC_GLB_REPLY_ERROR_INVALID_PARAM:
756 trace_ipc_error("error: invalid parameter", header);
757 msg->errno = -EINVAL;
758 break;
759 default:
760 trace_ipc_error("error: unknown reply", header);
761 msg->errno = -EINVAL;
762 break;
763 }
764
765 /* update any stream states */
766 hsw_stream_update(hsw, msg);
767
768 /* wake up and return the error if we have waiters on this message ? */
769 list_del(&msg->list);
770 tx_msg_reply_complete(hsw, msg);
771
772 return 1;
773}
774
775static int hsw_stream_message(struct sst_hsw *hsw, u32 header)
776{
777 u32 stream_msg, stream_id, stage_type;
778 struct sst_hsw_stream *stream;
779 int handled = 0;
780
781 stream_msg = msg_get_stream_type(header);
782 stream_id = msg_get_stream_id(header);
783 stage_type = msg_get_stage_type(header);
784
785 stream = get_stream_by_id(hsw, stream_id);
786 if (stream == NULL)
787 return handled;
788
789 stream->header = header;
790
791 switch (stream_msg) {
792 case IPC_STR_STAGE_MESSAGE:
793 dev_err(hsw->dev, "error: stage msg not implemented 0x%8.8x\n",
794 header);
795 break;
796 case IPC_STR_NOTIFICATION:
797 schedule_work(&stream->notify_work);
798 break;
799 default:
800 /* handle pending message complete request */
801 handled = hsw_process_reply(hsw, header);
802 break;
803 }
804
805 return handled;
806}
807
808static int hsw_log_message(struct sst_hsw *hsw, u32 header)
809{
810 u32 operation = (header & IPC_LOG_OP_MASK) >> IPC_LOG_OP_SHIFT;
811 struct sst_hsw_log_stream *stream = &hsw->log_stream;
812 int ret = 1;
813
814 if (operation != IPC_DEBUG_REQUEST_LOG_DUMP) {
815 dev_err(hsw->dev,
816 "error: log msg not implemented 0x%8.8x\n", header);
817 return 0;
818 }
819
820 mutex_lock(&stream->rw_mutex);
821 stream->last_pos = stream->curr_pos;
822 sst_dsp_inbox_read(
823 hsw->dsp, &stream->curr_pos, sizeof(stream->curr_pos));
824 mutex_unlock(&stream->rw_mutex);
825
826 schedule_work(&stream->notify_work);
827
828 return ret;
829}
830
831static int hsw_process_notification(struct sst_hsw *hsw)
832{
833 struct sst_dsp *sst = hsw->dsp;
834 u32 type, header;
835 int handled = 1;
836
837 header = sst_dsp_shim_read_unlocked(sst, SST_IPCD);
838 type = msg_get_global_type(header);
839
840 trace_ipc_request("processing -->", header);
841
842 /* FW Ready is a special case */
843 if (!hsw->boot_complete && header & IPC_FW_READY) {
844 hsw_fw_ready(hsw, header);
845 return handled;
846 }
847
848 switch (type) {
849 case IPC_GLB_GET_FW_VERSION:
850 case IPC_GLB_ALLOCATE_STREAM:
851 case IPC_GLB_FREE_STREAM:
852 case IPC_GLB_GET_FW_CAPABILITIES:
853 case IPC_GLB_REQUEST_DUMP:
854 case IPC_GLB_GET_DEVICE_FORMATS:
855 case IPC_GLB_SET_DEVICE_FORMATS:
856 case IPC_GLB_ENTER_DX_STATE:
857 case IPC_GLB_GET_MIXER_STREAM_INFO:
858 case IPC_GLB_MAX_IPC_MESSAGE_TYPE:
859 case IPC_GLB_RESTORE_CONTEXT:
860 case IPC_GLB_SHORT_REPLY:
861 dev_err(hsw->dev, "error: message type %d header 0x%x\n",
862 type, header);
863 break;
864 case IPC_GLB_STREAM_MESSAGE:
865 handled = hsw_stream_message(hsw, header);
866 break;
867 case IPC_GLB_DEBUG_LOG_MESSAGE:
868 handled = hsw_log_message(hsw, header);
869 break;
870 default:
871 dev_err(hsw->dev, "error: unexpected type %d hdr 0x%8.8x\n",
872 type, header);
873 break;
874 }
875
876 return handled;
877}
878
879static irqreturn_t hsw_irq_thread(int irq, void *context)
880{
881 struct sst_dsp *sst = (struct sst_dsp *) context;
882 struct sst_hsw *hsw = sst_dsp_get_thread_context(sst);
883 u32 ipcx, ipcd;
884 int handled;
885 unsigned long flags;
886
887 spin_lock_irqsave(&sst->spinlock, flags);
888
889 ipcx = sst_dsp_ipc_msg_rx(hsw->dsp);
890 ipcd = sst_dsp_shim_read_unlocked(sst, SST_IPCD);
891
892 /* reply message from DSP */
893 if (ipcx & SST_IPCX_DONE) {
894
895 /* Handle Immediate reply from DSP Core */
896 handled = hsw_process_reply(hsw, ipcx);
897
898 if (handled > 0) {
899 /* clear DONE bit - tell DSP we have completed */
900 sst_dsp_shim_update_bits_unlocked(sst, SST_IPCX,
901 SST_IPCX_DONE, 0);
902
903 /* unmask Done interrupt */
904 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX,
905 SST_IMRX_DONE, 0);
906 }
907 }
908
909 /* new message from DSP */
910 if (ipcd & SST_IPCD_BUSY) {
911
912 /* Handle Notification and Delayed reply from DSP Core */
913 handled = hsw_process_notification(hsw);
914
915 /* clear BUSY bit and set DONE bit - accept new messages */
916 if (handled > 0) {
917 sst_dsp_shim_update_bits_unlocked(sst, SST_IPCD,
918 SST_IPCD_BUSY | SST_IPCD_DONE, SST_IPCD_DONE);
919
920 /* unmask busy interrupt */
921 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX,
922 SST_IMRX_BUSY, 0);
923 }
924 }
925
926 spin_unlock_irqrestore(&sst->spinlock, flags);
927
928 /* continue to send any remaining messages... */
929 queue_kthread_work(&hsw->kworker, &hsw->kwork);
930
931 return IRQ_HANDLED;
932}
933
934int sst_hsw_fw_get_version(struct sst_hsw *hsw,
935 struct sst_hsw_ipc_fw_version *version)
936{
937 int ret;
938
939 ret = ipc_tx_message_wait(hsw, IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION),
940 NULL, 0, version, sizeof(*version));
941 if (ret < 0)
942 dev_err(hsw->dev, "error: get version failed\n");
943
944 return ret;
945}
946
947/* Mixer Controls */
948int sst_hsw_stream_mute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
949 u32 stage_id, u32 channel)
950{
951 int ret;
952
953 ret = sst_hsw_stream_get_volume(hsw, stream, stage_id, channel,
954 &stream->mute_volume[channel]);
955 if (ret < 0)
956 return ret;
957
958 ret = sst_hsw_stream_set_volume(hsw, stream, stage_id, channel, 0);
959 if (ret < 0) {
960 dev_err(hsw->dev, "error: can't unmute stream %d channel %d\n",
961 stream->reply.stream_hw_id, channel);
962 return ret;
963 }
964
965 stream->mute[channel] = 1;
966 return 0;
967}
968
969int sst_hsw_stream_unmute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
970 u32 stage_id, u32 channel)
971
972{
973 int ret;
974
975 stream->mute[channel] = 0;
976 ret = sst_hsw_stream_set_volume(hsw, stream, stage_id, channel,
977 stream->mute_volume[channel]);
978 if (ret < 0) {
979 dev_err(hsw->dev, "error: can't unmute stream %d channel %d\n",
980 stream->reply.stream_hw_id, channel);
981 return ret;
982 }
983
984 return 0;
985}
986
987int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
988 u32 stage_id, u32 channel, u32 *volume)
989{
990 if (channel > 1)
991 return -EINVAL;
992
993 sst_dsp_read(hsw->dsp, volume,
994 stream->reply.volume_register_address[channel], sizeof(volume));
995
996 return 0;
997}
998
999int sst_hsw_stream_set_volume_curve(struct sst_hsw *hsw,
1000 struct sst_hsw_stream *stream, u64 curve_duration,
1001 enum sst_hsw_volume_curve curve)
1002{
1003 /* curve duration in steps of 100ns */
1004 stream->vol_req.curve_duration = curve_duration;
1005 stream->vol_req.curve_type = curve;
1006
1007 return 0;
1008}
1009
1010/* stream volume */
1011int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
1012 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume)
1013{
1014 struct sst_hsw_ipc_volume_req *req;
1015 u32 header;
1016 int ret;
1017
1018 trace_ipc_request("set stream volume", stream->reply.stream_hw_id);
1019
1020 if (channel > 1)
1021 return -EINVAL;
1022
1023 if (stream->mute[channel]) {
1024 stream->mute_volume[channel] = volume;
1025 return 0;
1026 }
1027
1028 header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
1029 IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
1030 header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
1031 header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
1032 header |= (stage_id << IPC_STG_ID_SHIFT);
1033
1034 req = &stream->vol_req;
1035 req->channel = channel;
1036 req->target_volume = volume;
1037
1038 ret = ipc_tx_message_wait(hsw, header, req, sizeof(*req), NULL, 0);
1039 if (ret < 0) {
1040 dev_err(hsw->dev, "error: set stream volume failed\n");
1041 return ret;
1042 }
1043
1044 return 0;
1045}
1046
1047int sst_hsw_mixer_mute(struct sst_hsw *hsw, u32 stage_id, u32 channel)
1048{
1049 int ret;
1050
1051 ret = sst_hsw_mixer_get_volume(hsw, stage_id, channel,
1052 &hsw->mute_volume[channel]);
1053 if (ret < 0)
1054 return ret;
1055
1056 ret = sst_hsw_mixer_set_volume(hsw, stage_id, channel, 0);
1057 if (ret < 0) {
1058 dev_err(hsw->dev, "error: failed to unmute mixer channel %d\n",
1059 channel);
1060 return ret;
1061 }
1062
1063 hsw->mute[channel] = 1;
1064 return 0;
1065}
1066
1067int sst_hsw_mixer_unmute(struct sst_hsw *hsw, u32 stage_id, u32 channel)
1068{
1069 int ret;
1070
1071 ret = sst_hsw_mixer_set_volume(hsw, stage_id, channel,
1072 hsw->mixer_info.volume_register_address[channel]);
1073 if (ret < 0) {
1074 dev_err(hsw->dev, "error: failed to unmute mixer channel %d\n",
1075 channel);
1076 return ret;
1077 }
1078
1079 hsw->mute[channel] = 0;
1080 return 0;
1081}
1082
1083int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
1084 u32 *volume)
1085{
1086 if (channel > 1)
1087 return -EINVAL;
1088
1089 sst_dsp_read(hsw->dsp, volume,
1090 hsw->mixer_info.volume_register_address[channel],
1091 sizeof(*volume));
1092
1093 return 0;
1094}
1095
1096int sst_hsw_mixer_set_volume_curve(struct sst_hsw *hsw,
1097 u64 curve_duration, enum sst_hsw_volume_curve curve)
1098{
1099 /* curve duration in steps of 100ns */
1100 hsw->curve_duration = curve_duration;
1101 hsw->curve_type = curve;
1102
1103 return 0;
1104}
1105
1106/* global mixer volume */
1107int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
1108 u32 volume)
1109{
1110 struct sst_hsw_ipc_volume_req req;
1111 u32 header;
1112 int ret;
1113
1114 trace_ipc_request("set mixer volume", volume);
1115
1116 /* set both at same time ? */
1117 if (channel == 2) {
1118 if (hsw->mute[0] && hsw->mute[1]) {
1119 hsw->mute_volume[0] = hsw->mute_volume[1] = volume;
1120 return 0;
1121 } else if (hsw->mute[0])
1122 req.channel = 1;
1123 else if (hsw->mute[1])
1124 req.channel = 0;
1125 else
1126 req.channel = 0xffffffff;
1127 } else {
1128 /* set only 1 channel */
1129 if (hsw->mute[channel]) {
1130 hsw->mute_volume[channel] = volume;
1131 return 0;
1132 }
1133 req.channel = channel;
1134 }
1135
1136 header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
1137 IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
1138 header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT);
1139 header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
1140 header |= (stage_id << IPC_STG_ID_SHIFT);
1141
1142 req.curve_duration = hsw->curve_duration;
1143 req.curve_type = hsw->curve_type;
1144 req.target_volume = volume;
1145
1146 ret = ipc_tx_message_wait(hsw, header, &req, sizeof(req), NULL, 0);
1147 if (ret < 0) {
1148 dev_err(hsw->dev, "error: set mixer volume failed\n");
1149 return ret;
1150 }
1151
1152 return 0;
1153}
1154
1155/* Stream API */
1156struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
1157 u32 (*notify_position)(struct sst_hsw_stream *stream, void *data),
1158 void *data)
1159{
1160 struct sst_hsw_stream *stream;
1161
1162 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
1163 if (stream == NULL)
1164 return NULL;
1165
1166 list_add(&stream->node, &hsw->stream_list);
1167 stream->notify_position = notify_position;
1168 stream->pdata = data;
1169 stream->hsw = hsw;
1170 stream->host_id = id;
1171
1172 /* work to process notification messages */
1173 INIT_WORK(&stream->notify_work, hsw_notification_work);
1174
1175 return stream;
1176}
1177
1178int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1179{
1180 u32 header;
1181 int ret = 0;
1182
1183 /* dont free DSP streams that are not commited */
1184 if (!stream->commited)
1185 goto out;
1186
1187 trace_ipc_request("stream free", stream->host_id);
1188
1189 stream->free_req.stream_id = stream->reply.stream_hw_id;
1190 header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM);
1191
1192 ret = ipc_tx_message_wait(hsw, header, &stream->free_req,
1193 sizeof(stream->free_req), NULL, 0);
1194 if (ret < 0) {
1195 dev_err(hsw->dev, "error: free stream %d failed\n",
1196 stream->free_req.stream_id);
1197 return -EAGAIN;
1198 }
1199
1200 trace_hsw_stream_free_req(stream, &stream->free_req);
1201
1202out:
1203 list_del(&stream->node);
1204 kfree(stream);
1205
1206 return ret;
1207}
1208
1209int sst_hsw_stream_set_bits(struct sst_hsw *hsw,
1210 struct sst_hsw_stream *stream, enum sst_hsw_bitdepth bits)
1211{
1212 if (stream->commited) {
1213 dev_err(hsw->dev, "error: stream committed for set bits\n");
1214 return -EINVAL;
1215 }
1216
1217 stream->request.format.bitdepth = bits;
1218 return 0;
1219}
1220
1221int sst_hsw_stream_set_channels(struct sst_hsw *hsw,
1222 struct sst_hsw_stream *stream, int channels)
1223{
1224 if (stream->commited) {
1225 dev_err(hsw->dev, "error: stream committed for set channels\n");
1226 return -EINVAL;
1227 }
1228
1229 /* stereo is only supported atm */
1230 if (channels != 2)
1231 return -EINVAL;
1232
1233 stream->request.format.ch_num = channels;
1234 return 0;
1235}
1236
1237int sst_hsw_stream_set_rate(struct sst_hsw *hsw,
1238 struct sst_hsw_stream *stream, int rate)
1239{
1240 if (stream->commited) {
1241 dev_err(hsw->dev, "error: stream committed for set rate\n");
1242 return -EINVAL;
1243 }
1244
1245 stream->request.format.frequency = rate;
1246 return 0;
1247}
1248
1249int sst_hsw_stream_set_map_config(struct sst_hsw *hsw,
1250 struct sst_hsw_stream *stream, u32 map,
1251 enum sst_hsw_channel_config config)
1252{
1253 if (stream->commited) {
1254 dev_err(hsw->dev, "error: stream committed for set map\n");
1255 return -EINVAL;
1256 }
1257
1258 stream->request.format.map = map;
1259 stream->request.format.config = config;
1260 return 0;
1261}
1262
1263int sst_hsw_stream_set_style(struct sst_hsw *hsw,
1264 struct sst_hsw_stream *stream, enum sst_hsw_interleaving style)
1265{
1266 if (stream->commited) {
1267 dev_err(hsw->dev, "error: stream committed for set style\n");
1268 return -EINVAL;
1269 }
1270
1271 stream->request.format.style = style;
1272 return 0;
1273}
1274
1275int sst_hsw_stream_set_valid(struct sst_hsw *hsw,
1276 struct sst_hsw_stream *stream, u32 bits)
1277{
1278 if (stream->commited) {
1279 dev_err(hsw->dev, "error: stream committed for set valid bits\n");
1280 return -EINVAL;
1281 }
1282
1283 stream->request.format.valid_bit = bits;
1284 return 0;
1285}
1286
1287/* Stream Configuration */
1288int sst_hsw_stream_format(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
1289 enum sst_hsw_stream_path_id path_id,
1290 enum sst_hsw_stream_type stream_type,
1291 enum sst_hsw_stream_format format_id)
1292{
1293 if (stream->commited) {
1294 dev_err(hsw->dev, "error: stream committed for set format\n");
1295 return -EINVAL;
1296 }
1297
1298 stream->request.path_id = path_id;
1299 stream->request.stream_type = stream_type;
1300 stream->request.format_id = format_id;
1301
1302 trace_hsw_stream_alloc_request(stream, &stream->request);
1303
1304 return 0;
1305}
1306
1307int sst_hsw_stream_buffer(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
1308 u32 ring_pt_address, u32 num_pages,
1309 u32 ring_size, u32 ring_offset, u32 ring_first_pfn)
1310{
1311 if (stream->commited) {
1312 dev_err(hsw->dev, "error: stream committed for buffer\n");
1313 return -EINVAL;
1314 }
1315
1316 stream->request.ringinfo.ring_pt_address = ring_pt_address;
1317 stream->request.ringinfo.num_pages = num_pages;
1318 stream->request.ringinfo.ring_size = ring_size;
1319 stream->request.ringinfo.ring_offset = ring_offset;
1320 stream->request.ringinfo.ring_first_pfn = ring_first_pfn;
1321
1322 trace_hsw_stream_buffer(stream);
1323
1324 return 0;
1325}
1326
1327int sst_hsw_stream_set_module_info(struct sst_hsw *hsw,
1328 struct sst_hsw_stream *stream, enum sst_hsw_module_id module_id,
1329 u32 entry_point)
1330{
1331 struct sst_hsw_module_map *map = &stream->request.map;
1332
1333 if (stream->commited) {
1334 dev_err(hsw->dev, "error: stream committed for set module\n");
1335 return -EINVAL;
1336 }
1337
1338 /* only support initial module atm */
1339 map->module_entries_count = 1;
1340 map->module_entries[0].module_id = module_id;
1341 map->module_entries[0].entry_point = entry_point;
1342
1343 return 0;
1344}
1345
1346int sst_hsw_stream_set_pmemory_info(struct sst_hsw *hsw,
1347 struct sst_hsw_stream *stream, u32 offset, u32 size)
1348{
1349 if (stream->commited) {
1350 dev_err(hsw->dev, "error: stream committed for set pmem\n");
1351 return -EINVAL;
1352 }
1353
1354 stream->request.persistent_mem.offset = offset;
1355 stream->request.persistent_mem.size = size;
1356
1357 return 0;
1358}
1359
1360int sst_hsw_stream_set_smemory_info(struct sst_hsw *hsw,
1361 struct sst_hsw_stream *stream, u32 offset, u32 size)
1362{
1363 if (stream->commited) {
1364 dev_err(hsw->dev, "error: stream committed for set smem\n");
1365 return -EINVAL;
1366 }
1367
1368 stream->request.scratch_mem.offset = offset;
1369 stream->request.scratch_mem.size = size;
1370
1371 return 0;
1372}
1373
1374int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1375{
1376 struct sst_hsw_ipc_stream_alloc_req *str_req = &stream->request;
1377 struct sst_hsw_ipc_stream_alloc_reply *reply = &stream->reply;
1378 u32 header;
1379 int ret;
1380
1381 trace_ipc_request("stream alloc", stream->host_id);
1382
1383 header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM);
1384
1385 ret = ipc_tx_message_wait(hsw, header, str_req, sizeof(*str_req),
1386 reply, sizeof(*reply));
1387 if (ret < 0) {
1388 dev_err(hsw->dev, "error: stream commit failed\n");
1389 return ret;
1390 }
1391
1392 stream->commited = 1;
1393 trace_hsw_stream_alloc_reply(stream);
1394
1395 return 0;
1396}
1397
1398/* Stream Information - these calls could be inline but we want the IPC
1399 ABI to be opaque to client PCM drivers to cope with any future ABI changes */
1400int sst_hsw_stream_get_hw_id(struct sst_hsw *hsw,
1401 struct sst_hsw_stream *stream)
1402{
1403 return stream->reply.stream_hw_id;
1404}
1405
1406int sst_hsw_stream_get_mixer_id(struct sst_hsw *hsw,
1407 struct sst_hsw_stream *stream)
1408{
1409 return stream->reply.mixer_hw_id;
1410}
1411
1412u32 sst_hsw_stream_get_read_reg(struct sst_hsw *hsw,
1413 struct sst_hsw_stream *stream)
1414{
1415 return stream->reply.read_position_register_address;
1416}
1417
1418u32 sst_hsw_stream_get_pointer_reg(struct sst_hsw *hsw,
1419 struct sst_hsw_stream *stream)
1420{
1421 return stream->reply.presentation_position_register_address;
1422}
1423
1424u32 sst_hsw_stream_get_peak_reg(struct sst_hsw *hsw,
1425 struct sst_hsw_stream *stream, u32 channel)
1426{
1427 if (channel >= 2)
1428 return 0;
1429
1430 return stream->reply.peak_meter_register_address[channel];
1431}
1432
1433u32 sst_hsw_stream_get_vol_reg(struct sst_hsw *hsw,
1434 struct sst_hsw_stream *stream, u32 channel)
1435{
1436 if (channel >= 2)
1437 return 0;
1438
1439 return stream->reply.volume_register_address[channel];
1440}
1441
1442int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
1443{
1444 struct sst_hsw_ipc_stream_info_reply *reply;
1445 u32 header;
1446 int ret;
1447
1448 reply = &hsw->mixer_info;
1449 header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO);
1450
1451 trace_ipc_request("get global mixer info", 0);
1452
1453 ret = ipc_tx_message_wait(hsw, header, NULL, 0, reply, sizeof(*reply));
1454 if (ret < 0) {
1455 dev_err(hsw->dev, "error: get stream info failed\n");
1456 return ret;
1457 }
1458
1459 trace_hsw_mixer_info_reply(reply);
1460
1461 return 0;
1462}
1463
1464/* Send stream command */
1465static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type,
1466 int stream_id, int wait)
1467{
1468 u32 header;
1469
1470 header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | IPC_STR_TYPE(type);
1471 header |= (stream_id << IPC_STR_ID_SHIFT);
1472
1473 if (wait)
1474 return ipc_tx_message_wait(hsw, header, NULL, 0, NULL, 0);
1475 else
1476 return ipc_tx_message_nowait(hsw, header, NULL, 0);
1477}
1478
1479/* Stream ALSA trigger operations */
1480int sst_hsw_stream_pause(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
1481 int wait)
1482{
1483 int ret;
1484
1485 trace_ipc_request("stream pause", stream->reply.stream_hw_id);
1486
1487 ret = sst_hsw_stream_operations(hsw, IPC_STR_PAUSE,
1488 stream->reply.stream_hw_id, wait);
1489 if (ret < 0)
1490 dev_err(hsw->dev, "error: failed to pause stream %d\n",
1491 stream->reply.stream_hw_id);
1492
1493 return ret;
1494}
1495
1496int sst_hsw_stream_resume(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
1497 int wait)
1498{
1499 int ret;
1500
1501 trace_ipc_request("stream resume", stream->reply.stream_hw_id);
1502
1503 ret = sst_hsw_stream_operations(hsw, IPC_STR_RESUME,
1504 stream->reply.stream_hw_id, wait);
1505 if (ret < 0)
1506 dev_err(hsw->dev, "error: failed to resume stream %d\n",
1507 stream->reply.stream_hw_id);
1508
1509 return ret;
1510}
1511
1512int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1513{
1514 int ret, tries = 10;
1515
1516 /* dont reset streams that are not commited */
1517 if (!stream->commited)
1518 return 0;
1519
1520 /* wait for pause to complete before we reset the stream */
1521 while (stream->running && tries--)
1522 msleep(1);
1523 if (!tries) {
1524 dev_err(hsw->dev, "error: reset stream %d still running\n",
1525 stream->reply.stream_hw_id);
1526 return -EINVAL;
1527 }
1528
1529 trace_ipc_request("stream reset", stream->reply.stream_hw_id);
1530
1531 ret = sst_hsw_stream_operations(hsw, IPC_STR_RESET,
1532 stream->reply.stream_hw_id, 1);
1533 if (ret < 0)
1534 dev_err(hsw->dev, "error: failed to reset stream %d\n",
1535 stream->reply.stream_hw_id);
1536 return ret;
1537}
1538
1539/* Stream pointer positions */
1540int sst_hsw_get_dsp_position(struct sst_hsw *hsw,
1541 struct sst_hsw_stream *stream)
1542{
1543 return stream->rpos.position;
1544}
1545
1546int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
1547 struct sst_hsw_stream *stream, u32 stage_id, u32 position)
1548{
1549 u32 header;
1550 int ret;
1551
1552 trace_stream_write_position(stream->reply.stream_hw_id, position);
1553
1554 header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
1555 IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
1556 header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
1557 header |= (IPC_STG_SET_WRITE_POSITION << IPC_STG_TYPE_SHIFT);
1558 header |= (stage_id << IPC_STG_ID_SHIFT);
1559 stream->wpos.position = position;
1560
1561 ret = ipc_tx_message_nowait(hsw, header, &stream->wpos,
1562 sizeof(stream->wpos));
1563 if (ret < 0)
1564 dev_err(hsw->dev, "error: stream %d set position %d failed\n",
1565 stream->reply.stream_hw_id, position);
1566
1567 return ret;
1568}
1569
1570/* physical BE config */
1571int sst_hsw_device_set_config(struct sst_hsw *hsw,
1572 enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk,
1573 enum sst_hsw_device_mode mode, u32 clock_divider)
1574{
1575 struct sst_hsw_ipc_device_config_req config;
1576 u32 header;
1577 int ret;
1578
1579 trace_ipc_request("set device config", dev);
1580
1581 config.ssp_interface = dev;
1582 config.clock_frequency = mclk;
1583 config.mode = mode;
1584 config.clock_divider = clock_divider;
1585
1586 trace_hsw_device_config_req(&config);
1587
1588 header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS);
1589
1590 ret = ipc_tx_message_wait(hsw, header, &config, sizeof(config),
1591 NULL, 0);
1592 if (ret < 0)
1593 dev_err(hsw->dev, "error: set device formats failed\n");
1594
1595 return ret;
1596}
1597EXPORT_SYMBOL_GPL(sst_hsw_device_set_config);
1598
1599/* DX Config */
1600int sst_hsw_dx_set_state(struct sst_hsw *hsw,
1601 enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx)
1602{
1603 u32 header, state_;
1604 int ret;
1605
1606 header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE);
1607 state_ = state;
1608
1609 trace_ipc_request("PM enter Dx state", state);
1610
1611 ret = ipc_tx_message_wait(hsw, header, &state_, sizeof(state_),
1612 dx, sizeof(dx));
1613 if (ret < 0) {
1614 dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state);
1615 return ret;
1616 }
1617
1618 dev_dbg(hsw->dev, "ipc: got %d entry numbers for state %d\n",
1619 dx->entries_no, state);
1620
1621 memcpy(&hsw->dx, dx, sizeof(*dx));
1622 return 0;
1623}
1624
1625/* Used to save state into hsw->dx_reply */
1626int sst_hsw_dx_get_state(struct sst_hsw *hsw, u32 item,
1627 u32 *offset, u32 *size, u32 *source)
1628{
1629 struct sst_hsw_ipc_dx_memory_item *dx_mem;
1630 struct sst_hsw_ipc_dx_reply *dx_reply;
1631 int entry_no;
1632
1633 dx_reply = &hsw->dx;
1634 entry_no = dx_reply->entries_no;
1635
1636 trace_ipc_request("PM get Dx state", entry_no);
1637
1638 if (item >= entry_no)
1639 return -EINVAL;
1640
1641 dx_mem = &dx_reply->mem_info[item];
1642 *offset = dx_mem->offset;
1643 *size = dx_mem->size;
1644 *source = dx_mem->source;
1645
1646 return 0;
1647}
1648
1649static int msg_empty_list_init(struct sst_hsw *hsw)
1650{
1651 int i;
1652
1653 hsw->msg = kzalloc(sizeof(struct ipc_message) *
1654 IPC_EMPTY_LIST_SIZE, GFP_KERNEL);
1655 if (hsw->msg == NULL)
1656 return -ENOMEM;
1657
1658 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
1659 init_waitqueue_head(&hsw->msg[i].waitq);
1660 list_add(&hsw->msg[i].list, &hsw->empty_list);
1661 }
1662
1663 return 0;
1664}
1665
1666void sst_hsw_set_scratch_module(struct sst_hsw *hsw,
1667 struct sst_module *scratch)
1668{
1669 hsw->scratch = scratch;
1670}
1671
1672struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw)
1673{
1674 return hsw->dsp;
1675}
1676
1677static struct sst_dsp_device hsw_dev = {
1678 .thread = hsw_irq_thread,
1679 .ops = &haswell_ops,
1680};
1681
1682int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
1683{
1684 struct sst_hsw_ipc_fw_version version;
1685 struct sst_hsw *hsw;
1686 struct sst_fw *hsw_sst_fw;
1687 int ret;
1688
1689 dev_dbg(dev, "initialising Audio DSP IPC\n");
1690
1691 hsw = devm_kzalloc(dev, sizeof(*hsw), GFP_KERNEL);
1692 if (hsw == NULL)
1693 return -ENOMEM;
1694
1695 hsw->dev = dev;
1696 INIT_LIST_HEAD(&hsw->stream_list);
1697 INIT_LIST_HEAD(&hsw->tx_list);
1698 INIT_LIST_HEAD(&hsw->rx_list);
1699 INIT_LIST_HEAD(&hsw->empty_list);
1700 init_waitqueue_head(&hsw->boot_wait);
1701 init_waitqueue_head(&hsw->wait_txq);
1702
1703 ret = msg_empty_list_init(hsw);
1704 if (ret < 0)
1705 goto list_err;
1706
1707 /* start the IPC message thread */
1708 init_kthread_worker(&hsw->kworker);
1709 hsw->tx_thread = kthread_run(kthread_worker_fn,
1710 &hsw->kworker,
1711 dev_name(hsw->dev));
1712 if (IS_ERR(hsw->tx_thread)) {
1713 ret = PTR_ERR(hsw->tx_thread);
1714 dev_err(hsw->dev, "error: failed to create message TX task\n");
1715 goto list_err;
1716 }
1717 init_kthread_work(&hsw->kwork, ipc_tx_msgs);
1718
1719 hsw_dev.thread_context = hsw;
1720
1721 /* init SST shim */
1722 hsw->dsp = sst_dsp_new(dev, &hsw_dev, pdata);
1723 if (hsw->dsp == NULL) {
1724 ret = -ENODEV;
1725 goto list_err;
1726 }
1727
1728 /* keep the DSP in reset state for base FW loading */
1729 sst_dsp_reset(hsw->dsp);
1730
1731 hsw_sst_fw = sst_fw_new(hsw->dsp, pdata->fw, hsw);
1732
1733 if (hsw_sst_fw == NULL) {
1734 ret = -ENODEV;
1735 dev_err(dev, "error: failed to load firmware\n");
1736 goto fw_err;
1737 }
1738
1739 /* wait for DSP boot completion */
1740 sst_dsp_boot(hsw->dsp);
1741 ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete,
1742 msecs_to_jiffies(IPC_BOOT_MSECS));
1743 if (ret == 0) {
1744 ret = -EIO;
1745 dev_err(hsw->dev, "error: ADSP boot timeout\n");
1746 goto boot_err;
1747 }
1748
1749 /* get the FW version */
1750 sst_hsw_fw_get_version(hsw, &version);
1751 dev_info(hsw->dev, "FW loaded: type %d - version: %d.%d build %d\n",
1752 version.type, version.major, version.minor, version.build);
1753
1754 /* get the globalmixer */
1755 ret = sst_hsw_mixer_get_info(hsw);
1756 if (ret < 0) {
1757 dev_err(hsw->dev, "error: failed to get stream info\n");
1758 goto boot_err;
1759 }
1760
1761 pdata->dsp = hsw;
1762 return 0;
1763
1764boot_err:
1765 sst_dsp_reset(hsw->dsp);
1766 sst_fw_free(hsw_sst_fw);
1767fw_err:
1768 sst_dsp_free(hsw->dsp);
1769 kfree(hsw->msg);
1770list_err:
1771 return ret;
1772}
1773EXPORT_SYMBOL_GPL(sst_hsw_dsp_init);
1774
1775void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata)
1776{
1777 struct sst_hsw *hsw = pdata->dsp;
1778
1779 sst_dsp_reset(hsw->dsp);
1780 sst_fw_free_all(hsw->dsp);
1781 sst_dsp_free(hsw->dsp);
1782 kfree(hsw->scratch);
1783 kfree(hsw->msg);
1784}
1785EXPORT_SYMBOL_GPL(sst_hsw_dsp_free);
diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h
new file mode 100644
index 000000000000..d517929ccc38
--- /dev/null
+++ b/sound/soc/intel/sst-haswell-ipc.h
@@ -0,0 +1,488 @@
1/*
2 * Intel SST Haswell/Broadwell IPC Support
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef __SST_HASWELL_IPC_H
18#define __SST_HASWELL_IPC_H
19
20#include <linux/types.h>
21#include <linux/kernel.h>
22#include <linux/platform_device.h>
23
24#define SST_HSW_NO_CHANNELS 2
25#define SST_HSW_MAX_DX_REGIONS 14
26
27#define SST_HSW_FW_LOG_CONFIG_DWORDS 12
28#define SST_HSW_GLOBAL_LOG 15
29
30/**
31 * Upfront defined maximum message size that is
32 * expected by the in/out communication pipes in FW.
33 */
34#define SST_HSW_IPC_MAX_PAYLOAD_SIZE 400
35#define SST_HSW_MAX_INFO_SIZE 64
36#define SST_HSW_BUILD_HASH_LENGTH 40
37
38struct sst_hsw;
39struct sst_hsw_stream;
40struct sst_hsw_log_stream;
41struct sst_pdata;
42struct sst_module;
43extern struct sst_ops haswell_ops;
44
45/* Stream Allocate Path ID */
46enum sst_hsw_stream_path_id {
47 SST_HSW_STREAM_PATH_SSP0_OUT = 0,
48 SST_HSW_STREAM_PATH_SSP0_IN = 1,
49 SST_HSW_STREAM_PATH_MAX_PATH_ID = 2,
50};
51
52/* Stream Allocate Stream Type */
53enum sst_hsw_stream_type {
54 SST_HSW_STREAM_TYPE_RENDER = 0,
55 SST_HSW_STREAM_TYPE_SYSTEM = 1,
56 SST_HSW_STREAM_TYPE_CAPTURE = 2,
57 SST_HSW_STREAM_TYPE_LOOPBACK = 3,
58 SST_HSW_STREAM_TYPE_MAX_STREAM_TYPE = 4,
59};
60
61/* Stream Allocate Stream Format */
62enum sst_hsw_stream_format {
63 SST_HSW_STREAM_FORMAT_PCM_FORMAT = 0,
64 SST_HSW_STREAM_FORMAT_MP3_FORMAT = 1,
65 SST_HSW_STREAM_FORMAT_AAC_FORMAT = 2,
66 SST_HSW_STREAM_FORMAT_MAX_FORMAT_ID = 3,
67};
68
69/* Device ID */
70enum sst_hsw_device_id {
71 SST_HSW_DEVICE_SSP_0 = 0,
72 SST_HSW_DEVICE_SSP_1 = 1,
73};
74
75/* Device Master Clock Frequency */
76enum sst_hsw_device_mclk {
77 SST_HSW_DEVICE_MCLK_OFF = 0,
78 SST_HSW_DEVICE_MCLK_FREQ_6_MHZ = 1,
79 SST_HSW_DEVICE_MCLK_FREQ_12_MHZ = 2,
80 SST_HSW_DEVICE_MCLK_FREQ_24_MHZ = 3,
81};
82
83/* Device Clock Master */
84enum sst_hsw_device_mode {
85 SST_HSW_DEVICE_CLOCK_SLAVE = 0,
86 SST_HSW_DEVICE_CLOCK_MASTER = 1,
87};
88
89/* DX Power State */
90enum sst_hsw_dx_state {
91 SST_HSW_DX_STATE_D0 = 0,
92 SST_HSW_DX_STATE_D1 = 1,
93 SST_HSW_DX_STATE_D3 = 3,
94 SST_HSW_DX_STATE_MAX = 3,
95};
96
97/* Audio stream stage IDs */
98enum sst_hsw_fx_stage_id {
99 SST_HSW_STAGE_ID_WAVES = 0,
100 SST_HSW_STAGE_ID_DTS = 1,
101 SST_HSW_STAGE_ID_DOLBY = 2,
102 SST_HSW_STAGE_ID_BOOST = 3,
103 SST_HSW_STAGE_ID_MAX_FX_ID
104};
105
106/* DX State Type */
107enum sst_hsw_dx_type {
108 SST_HSW_DX_TYPE_FW_IMAGE = 0,
109 SST_HSW_DX_TYPE_MEMORY_DUMP = 1
110};
111
112/* Volume Curve Type*/
113enum sst_hsw_volume_curve {
114 SST_HSW_VOLUME_CURVE_NONE = 0,
115 SST_HSW_VOLUME_CURVE_FADE = 1
116};
117
118/* Sample ordering */
119enum sst_hsw_interleaving {
120 SST_HSW_INTERLEAVING_PER_CHANNEL = 0,
121 SST_HSW_INTERLEAVING_PER_SAMPLE = 1,
122};
123
124/* Channel indices */
125enum sst_hsw_channel_index {
126 SST_HSW_CHANNEL_LEFT = 0,
127 SST_HSW_CHANNEL_CENTER = 1,
128 SST_HSW_CHANNEL_RIGHT = 2,
129 SST_HSW_CHANNEL_LEFT_SURROUND = 3,
130 SST_HSW_CHANNEL_CENTER_SURROUND = 3,
131 SST_HSW_CHANNEL_RIGHT_SURROUND = 4,
132 SST_HSW_CHANNEL_LFE = 7,
133 SST_HSW_CHANNEL_INVALID = 0xF,
134};
135
136/* List of supported channel maps. */
137enum sst_hsw_channel_config {
138 SST_HSW_CHANNEL_CONFIG_MONO = 0, /* mono only. */
139 SST_HSW_CHANNEL_CONFIG_STEREO = 1, /* L & R. */
140 SST_HSW_CHANNEL_CONFIG_2_POINT_1 = 2, /* L, R & LFE; PCM only. */
141 SST_HSW_CHANNEL_CONFIG_3_POINT_0 = 3, /* L, C & R; MP3 & AAC only. */
142 SST_HSW_CHANNEL_CONFIG_3_POINT_1 = 4, /* L, C, R & LFE; PCM only. */
143 SST_HSW_CHANNEL_CONFIG_QUATRO = 5, /* L, R, Ls & Rs; PCM only. */
144 SST_HSW_CHANNEL_CONFIG_4_POINT_0 = 6, /* L, C, R & Cs; MP3 & AAC only. */
145 SST_HSW_CHANNEL_CONFIG_5_POINT_0 = 7, /* L, C, R, Ls & Rs. */
146 SST_HSW_CHANNEL_CONFIG_5_POINT_1 = 8, /* L, C, R, Ls, Rs & LFE. */
147 SST_HSW_CHANNEL_CONFIG_DUAL_MONO = 9, /* One channel replicated in two. */
148 SST_HSW_CHANNEL_CONFIG_INVALID,
149};
150
151/* List of supported bit depths. */
152enum sst_hsw_bitdepth {
153 SST_HSW_DEPTH_8BIT = 8,
154 SST_HSW_DEPTH_16BIT = 16,
155 SST_HSW_DEPTH_24BIT = 24, /* Default. */
156 SST_HSW_DEPTH_32BIT = 32,
157 SST_HSW_DEPTH_INVALID = 33,
158};
159
160enum sst_hsw_module_id {
161 SST_HSW_MODULE_BASE_FW = 0x0,
162 SST_HSW_MODULE_MP3 = 0x1,
163 SST_HSW_MODULE_AAC_5_1 = 0x2,
164 SST_HSW_MODULE_AAC_2_0 = 0x3,
165 SST_HSW_MODULE_SRC = 0x4,
166 SST_HSW_MODULE_WAVES = 0x5,
167 SST_HSW_MODULE_DOLBY = 0x6,
168 SST_HSW_MODULE_BOOST = 0x7,
169 SST_HSW_MODULE_LPAL = 0x8,
170 SST_HSW_MODULE_DTS = 0x9,
171 SST_HSW_MODULE_PCM_CAPTURE = 0xA,
172 SST_HSW_MODULE_PCM_SYSTEM = 0xB,
173 SST_HSW_MODULE_PCM_REFERENCE = 0xC,
174 SST_HSW_MODULE_PCM = 0xD,
175 SST_HSW_MODULE_BLUETOOTH_RENDER_MODULE = 0xE,
176 SST_HSW_MODULE_BLUETOOTH_CAPTURE_MODULE = 0xF,
177 SST_HSW_MAX_MODULE_ID,
178};
179
180enum sst_hsw_performance_action {
181 SST_HSW_PERF_START = 0,
182 SST_HSW_PERF_STOP = 1,
183};
184
185/* SST firmware module info */
186struct sst_hsw_module_info {
187 u8 name[SST_HSW_MAX_INFO_SIZE];
188 u8 version[SST_HSW_MAX_INFO_SIZE];
189} __attribute__((packed));
190
191/* Module entry point */
192struct sst_hsw_module_entry {
193 enum sst_hsw_module_id module_id;
194 u32 entry_point;
195} __attribute__((packed));
196
197/* Module map - alignement matches DSP */
198struct sst_hsw_module_map {
199 u8 module_entries_count;
200 struct sst_hsw_module_entry module_entries[1];
201} __attribute__((packed));
202
203struct sst_hsw_memory_info {
204 u32 offset;
205 u32 size;
206} __attribute__((packed));
207
208struct sst_hsw_fx_enable {
209 struct sst_hsw_module_map module_map;
210 struct sst_hsw_memory_info persistent_mem;
211} __attribute__((packed));
212
213struct sst_hsw_get_fx_param {
214 u32 parameter_id;
215 u32 param_size;
216} __attribute__((packed));
217
218struct sst_hsw_perf_action {
219 u32 action;
220} __attribute__((packed));
221
222struct sst_hsw_perf_data {
223 u64 timestamp;
224 u64 cycles;
225 u64 datatime;
226} __attribute__((packed));
227
228/* FW version */
229struct sst_hsw_ipc_fw_version {
230 u8 build;
231 u8 minor;
232 u8 major;
233 u8 type;
234 u8 fw_build_hash[SST_HSW_BUILD_HASH_LENGTH];
235 u32 fw_log_providers_hash;
236} __attribute__((packed));
237
238/* Stream ring info */
239struct sst_hsw_ipc_stream_ring {
240 u32 ring_pt_address;
241 u32 num_pages;
242 u32 ring_size;
243 u32 ring_offset;
244 u32 ring_first_pfn;
245} __attribute__((packed));
246
247/* Debug Dump Log Enable Request */
248struct sst_hsw_ipc_debug_log_enable_req {
249 struct sst_hsw_ipc_stream_ring ringinfo;
250 u32 config[SST_HSW_FW_LOG_CONFIG_DWORDS];
251} __attribute__((packed));
252
253/* Debug Dump Log Reply */
254struct sst_hsw_ipc_debug_log_reply {
255 u32 log_buffer_begining;
256 u32 log_buffer_size;
257} __attribute__((packed));
258
259/* Stream glitch position */
260struct sst_hsw_ipc_stream_glitch_position {
261 u32 glitch_type;
262 u32 present_pos;
263 u32 write_pos;
264} __attribute__((packed));
265
266/* Stream get position */
267struct sst_hsw_ipc_stream_get_position {
268 u32 position;
269 u32 fw_cycle_count;
270} __attribute__((packed));
271
272/* Stream set position */
273struct sst_hsw_ipc_stream_set_position {
274 u32 position;
275 u32 end_of_buffer;
276} __attribute__((packed));
277
278/* Stream Free Request */
279struct sst_hsw_ipc_stream_free_req {
280 u8 stream_id;
281 u8 reserved[3];
282} __attribute__((packed));
283
284/* Set Volume Request */
285struct sst_hsw_ipc_volume_req {
286 u32 channel;
287 u32 target_volume;
288 u64 curve_duration;
289 u32 curve_type;
290} __attribute__((packed));
291
292/* Device Configuration Request */
293struct sst_hsw_ipc_device_config_req {
294 u32 ssp_interface;
295 u32 clock_frequency;
296 u32 mode;
297 u16 clock_divider;
298 u16 reserved;
299} __attribute__((packed));
300
301/* Audio Data formats */
302struct sst_hsw_audio_data_format_ipc {
303 u32 frequency;
304 u32 bitdepth;
305 u32 map;
306 u32 config;
307 u32 style;
308 u8 ch_num;
309 u8 valid_bit;
310 u8 reserved[2];
311} __attribute__((packed));
312
313/* Stream Allocate Request */
314struct sst_hsw_ipc_stream_alloc_req {
315 u8 path_id;
316 u8 stream_type;
317 u8 format_id;
318 u8 reserved;
319 struct sst_hsw_audio_data_format_ipc format;
320 struct sst_hsw_ipc_stream_ring ringinfo;
321 struct sst_hsw_module_map map;
322 struct sst_hsw_memory_info persistent_mem;
323 struct sst_hsw_memory_info scratch_mem;
324 u32 number_of_notifications;
325} __attribute__((packed));
326
327/* Stream Allocate Reply */
328struct sst_hsw_ipc_stream_alloc_reply {
329 u32 stream_hw_id;
330 u32 mixer_hw_id; // returns rate ????
331 u32 read_position_register_address;
332 u32 presentation_position_register_address;
333 u32 peak_meter_register_address[SST_HSW_NO_CHANNELS];
334 u32 volume_register_address[SST_HSW_NO_CHANNELS];
335} __attribute__((packed));
336
337/* Get Mixer Stream Info */
338struct sst_hsw_ipc_stream_info_reply {
339 u32 mixer_hw_id;
340 u32 peak_meter_register_address[SST_HSW_NO_CHANNELS];
341 u32 volume_register_address[SST_HSW_NO_CHANNELS];
342} __attribute__((packed));
343
344/* DX State Request */
345struct sst_hsw_ipc_dx_req {
346 u8 state;
347 u8 reserved[3];
348} __attribute__((packed));
349
350/* DX State Reply Memory Info Item */
351struct sst_hsw_ipc_dx_memory_item {
352 u32 offset;
353 u32 size;
354 u32 source;
355} __attribute__((packed));
356
357/* DX State Reply */
358struct sst_hsw_ipc_dx_reply {
359 u32 entries_no;
360 struct sst_hsw_ipc_dx_memory_item mem_info[SST_HSW_MAX_DX_REGIONS];
361} __attribute__((packed));
362
363struct sst_hsw_ipc_fw_version;
364
365/* SST Init & Free */
366struct sst_hsw *sst_hsw_new(struct device *dev, const u8 *fw, size_t fw_length,
367 u32 fw_offset);
368void sst_hsw_free(struct sst_hsw *hsw);
369int sst_hsw_fw_get_version(struct sst_hsw *hsw,
370 struct sst_hsw_ipc_fw_version *version);
371u32 create_channel_map(enum sst_hsw_channel_config config);
372
373/* Stream Mixer Controls - */
374int sst_hsw_stream_mute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
375 u32 stage_id, u32 channel);
376int sst_hsw_stream_unmute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
377 u32 stage_id, u32 channel);
378
379int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
380 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume);
381int sst_hsw_stream_get_volume(struct sst_hsw *hsw,
382 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 *volume);
383
384int sst_hsw_stream_set_volume_curve(struct sst_hsw *hsw,
385 struct sst_hsw_stream *stream, u64 curve_duration,
386 enum sst_hsw_volume_curve curve);
387
388/* Global Mixer Controls - */
389int sst_hsw_mixer_mute(struct sst_hsw *hsw, u32 stage_id, u32 channel);
390int sst_hsw_mixer_unmute(struct sst_hsw *hsw, u32 stage_id, u32 channel);
391
392int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
393 u32 volume);
394int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
395 u32 *volume);
396
397int sst_hsw_mixer_set_volume_curve(struct sst_hsw *hsw,
398 u64 curve_duration, enum sst_hsw_volume_curve curve);
399
400/* Stream API */
401struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
402 u32 (*get_write_position)(struct sst_hsw_stream *stream, void *data),
403 void *data);
404
405int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream);
406
407/* Stream Configuration */
408int sst_hsw_stream_format(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
409 enum sst_hsw_stream_path_id path_id,
410 enum sst_hsw_stream_type stream_type,
411 enum sst_hsw_stream_format format_id);
412
413int sst_hsw_stream_buffer(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
414 u32 ring_pt_address, u32 num_pages,
415 u32 ring_size, u32 ring_offset, u32 ring_first_pfn);
416
417int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream);
418
419int sst_hsw_stream_set_valid(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
420 u32 bits);
421int sst_hsw_stream_set_rate(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
422 int rate);
423int sst_hsw_stream_set_bits(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
424 enum sst_hsw_bitdepth bits);
425int sst_hsw_stream_set_channels(struct sst_hsw *hsw,
426 struct sst_hsw_stream *stream, int channels);
427int sst_hsw_stream_set_map_config(struct sst_hsw *hsw,
428 struct sst_hsw_stream *stream, u32 map,
429 enum sst_hsw_channel_config config);
430int sst_hsw_stream_set_style(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
431 enum sst_hsw_interleaving style);
432int sst_hsw_stream_set_module_info(struct sst_hsw *hsw,
433 struct sst_hsw_stream *stream, enum sst_hsw_module_id module_id,
434 u32 entry_point);
435int sst_hsw_stream_set_pmemory_info(struct sst_hsw *hsw,
436 struct sst_hsw_stream *stream, u32 offset, u32 size);
437int sst_hsw_stream_set_smemory_info(struct sst_hsw *hsw,
438 struct sst_hsw_stream *stream, u32 offset, u32 size);
439int sst_hsw_stream_get_hw_id(struct sst_hsw *hsw,
440 struct sst_hsw_stream *stream);
441int sst_hsw_stream_get_mixer_id(struct sst_hsw *hsw,
442 struct sst_hsw_stream *stream);
443u32 sst_hsw_stream_get_read_reg(struct sst_hsw *hsw,
444 struct sst_hsw_stream *stream);
445u32 sst_hsw_stream_get_pointer_reg(struct sst_hsw *hsw,
446 struct sst_hsw_stream *stream);
447u32 sst_hsw_stream_get_peak_reg(struct sst_hsw *hsw,
448 struct sst_hsw_stream *stream, u32 channel);
449u32 sst_hsw_stream_get_vol_reg(struct sst_hsw *hsw,
450 struct sst_hsw_stream *stream, u32 channel);
451int sst_hsw_mixer_get_info(struct sst_hsw *hsw);
452
453/* Stream ALSA trigger operations */
454int sst_hsw_stream_pause(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
455 int wait);
456int sst_hsw_stream_resume(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
457 int wait);
458int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream);
459
460/* Stream pointer positions */
461int sst_hsw_stream_get_read_pos(struct sst_hsw *hsw,
462 struct sst_hsw_stream *stream, u32 *position);
463int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw,
464 struct sst_hsw_stream *stream, u32 *position);
465int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
466 struct sst_hsw_stream *stream, u32 stage_id, u32 position);
467int sst_hsw_get_dsp_position(struct sst_hsw *hsw,
468 struct sst_hsw_stream *stream);
469
470/* HW port config */
471int sst_hsw_device_set_config(struct sst_hsw *hsw,
472 enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk,
473 enum sst_hsw_device_mode mode, u32 clock_divider);
474
475/* DX Config */
476int sst_hsw_dx_set_state(struct sst_hsw *hsw,
477 enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx);
478int sst_hsw_dx_get_state(struct sst_hsw *hsw, u32 item,
479 u32 *offset, u32 *size, u32 *source);
480
481/* init */
482int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata);
483void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata);
484struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw);
485void sst_hsw_set_scratch_module(struct sst_hsw *hsw,
486 struct sst_module *scratch);
487
488#endif
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c
new file mode 100644
index 000000000000..0a32dd13a23d
--- /dev/null
+++ b/sound/soc/intel/sst-haswell-pcm.c
@@ -0,0 +1,872 @@
1/*
2 * Intel SST Haswell/Broadwell PCM Support
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/dma-mapping.h>
19#include <linux/slab.h>
20#include <linux/module.h>
21#include <linux/delay.h>
22#include <asm/page.h>
23#include <asm/pgtable.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/dmaengine_pcm.h>
28#include <sound/soc.h>
29#include <sound/tlv.h>
30#include <sound/compress_driver.h>
31
32#include "sst-haswell-ipc.h"
33#include "sst-dsp-priv.h"
34#include "sst-dsp.h"
35
36#define HSW_PCM_COUNT 6
37#define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */
38
39/* simple volume table */
40static const u32 volume_map[] = {
41 HSW_VOLUME_MAX >> 30,
42 HSW_VOLUME_MAX >> 29,
43 HSW_VOLUME_MAX >> 28,
44 HSW_VOLUME_MAX >> 27,
45 HSW_VOLUME_MAX >> 26,
46 HSW_VOLUME_MAX >> 25,
47 HSW_VOLUME_MAX >> 24,
48 HSW_VOLUME_MAX >> 23,
49 HSW_VOLUME_MAX >> 22,
50 HSW_VOLUME_MAX >> 21,
51 HSW_VOLUME_MAX >> 20,
52 HSW_VOLUME_MAX >> 19,
53 HSW_VOLUME_MAX >> 18,
54 HSW_VOLUME_MAX >> 17,
55 HSW_VOLUME_MAX >> 16,
56 HSW_VOLUME_MAX >> 15,
57 HSW_VOLUME_MAX >> 14,
58 HSW_VOLUME_MAX >> 13,
59 HSW_VOLUME_MAX >> 12,
60 HSW_VOLUME_MAX >> 11,
61 HSW_VOLUME_MAX >> 10,
62 HSW_VOLUME_MAX >> 9,
63 HSW_VOLUME_MAX >> 8,
64 HSW_VOLUME_MAX >> 7,
65 HSW_VOLUME_MAX >> 6,
66 HSW_VOLUME_MAX >> 5,
67 HSW_VOLUME_MAX >> 4,
68 HSW_VOLUME_MAX >> 3,
69 HSW_VOLUME_MAX >> 2,
70 HSW_VOLUME_MAX >> 1,
71 HSW_VOLUME_MAX >> 0,
72};
73
74#define HSW_PCM_PERIODS_MAX 64
75#define HSW_PCM_PERIODS_MIN 2
76
77static const struct snd_pcm_hardware hsw_pcm_hardware = {
78 .info = SNDRV_PCM_INFO_MMAP |
79 SNDRV_PCM_INFO_MMAP_VALID |
80 SNDRV_PCM_INFO_INTERLEAVED |
81 SNDRV_PCM_INFO_PAUSE |
82 SNDRV_PCM_INFO_RESUME |
83 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
84 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE |
85 SNDRV_PCM_FMTBIT_S32_LE,
86 .period_bytes_min = PAGE_SIZE,
87 .period_bytes_max = (HSW_PCM_PERIODS_MAX / HSW_PCM_PERIODS_MIN) * PAGE_SIZE,
88 .periods_min = HSW_PCM_PERIODS_MIN,
89 .periods_max = HSW_PCM_PERIODS_MAX,
90 .buffer_bytes_max = HSW_PCM_PERIODS_MAX * PAGE_SIZE,
91};
92
93/* private data for each PCM DSP stream */
94struct hsw_pcm_data {
95 int dai_id;
96 struct sst_hsw_stream *stream;
97 u32 volume[2];
98 struct snd_pcm_substream *substream;
99 struct snd_compr_stream *cstream;
100 unsigned int wpos;
101 struct mutex mutex;
102};
103
104/* private data for the driver */
105struct hsw_priv_data {
106 /* runtime DSP */
107 struct sst_hsw *hsw;
108
109 /* page tables */
110 unsigned char *pcm_pg[HSW_PCM_COUNT][2];
111
112 /* DAI data */
113 struct hsw_pcm_data pcm[HSW_PCM_COUNT];
114};
115
116static inline u32 hsw_mixer_to_ipc(unsigned int value)
117{
118 if (value >= ARRAY_SIZE(volume_map))
119 return volume_map[0];
120 else
121 return volume_map[value];
122}
123
124static inline unsigned int hsw_ipc_to_mixer(u32 value)
125{
126 int i;
127
128 for (i = 0; i < ARRAY_SIZE(volume_map); i++) {
129 if (volume_map[i] >= value)
130 return i;
131 }
132
133 return i - 1;
134}
135
136static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
137 struct snd_ctl_elem_value *ucontrol)
138{
139 struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol);
140 struct soc_mixer_control *mc =
141 (struct soc_mixer_control *)kcontrol->private_value;
142 struct hsw_priv_data *pdata =
143 snd_soc_platform_get_drvdata(platform);
144 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
145 struct sst_hsw *hsw = pdata->hsw;
146 u32 volume;
147
148 mutex_lock(&pcm_data->mutex);
149
150 if (!pcm_data->stream) {
151 pcm_data->volume[0] =
152 hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
153 pcm_data->volume[1] =
154 hsw_mixer_to_ipc(ucontrol->value.integer.value[1]);
155 mutex_unlock(&pcm_data->mutex);
156 return 0;
157 }
158
159 if (ucontrol->value.integer.value[0] ==
160 ucontrol->value.integer.value[1]) {
161 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
162 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 2, volume);
163 } else {
164 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
165 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 0, volume);
166 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[1]);
167 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 1, volume);
168 }
169
170 mutex_unlock(&pcm_data->mutex);
171 return 0;
172}
173
174static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
175 struct snd_ctl_elem_value *ucontrol)
176{
177 struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol);
178 struct soc_mixer_control *mc =
179 (struct soc_mixer_control *)kcontrol->private_value;
180 struct hsw_priv_data *pdata =
181 snd_soc_platform_get_drvdata(platform);
182 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
183 struct sst_hsw *hsw = pdata->hsw;
184 u32 volume;
185
186 mutex_lock(&pcm_data->mutex);
187
188 if (!pcm_data->stream) {
189 ucontrol->value.integer.value[0] =
190 hsw_ipc_to_mixer(pcm_data->volume[0]);
191 ucontrol->value.integer.value[1] =
192 hsw_ipc_to_mixer(pcm_data->volume[1]);
193 mutex_unlock(&pcm_data->mutex);
194 return 0;
195 }
196
197 sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 0, &volume);
198 ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume);
199 sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 1, &volume);
200 ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume);
201 mutex_unlock(&pcm_data->mutex);
202
203 return 0;
204}
205
206static int hsw_volume_put(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol)
208{
209 struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol);
210 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
211 struct sst_hsw *hsw = pdata->hsw;
212 u32 volume;
213
214 if (ucontrol->value.integer.value[0] ==
215 ucontrol->value.integer.value[1]) {
216
217 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
218 sst_hsw_mixer_set_volume(hsw, 0, 2, volume);
219
220 } else {
221 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
222 sst_hsw_mixer_set_volume(hsw, 0, 0, volume);
223
224 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[1]);
225 sst_hsw_mixer_set_volume(hsw, 0, 1, volume);
226 }
227
228 return 0;
229}
230
231static int hsw_volume_get(struct snd_kcontrol *kcontrol,
232 struct snd_ctl_elem_value *ucontrol)
233{
234 struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol);
235 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
236 struct sst_hsw *hsw = pdata->hsw;
237 unsigned int volume = 0;
238
239 sst_hsw_mixer_get_volume(hsw, 0, 0, &volume);
240 ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume);
241
242 sst_hsw_mixer_get_volume(hsw, 0, 1, &volume);
243 ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume);
244
245 return 0;
246}
247
248/* TLV used by both global and stream volumes */
249static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1);
250
251/* System Pin has no volume control */
252static const struct snd_kcontrol_new hsw_volume_controls[] = {
253 /* Global DSP volume */
254 SOC_DOUBLE_EXT_TLV("Master Playback Volume", 0, 0, 8,
255 ARRAY_SIZE(volume_map) -1, 0,
256 hsw_volume_get, hsw_volume_put, hsw_vol_tlv),
257 /* Offload 0 volume */
258 SOC_DOUBLE_EXT_TLV("Media0 Playback Volume", 1, 0, 8,
259 ARRAY_SIZE(volume_map), 0,
260 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
261 /* Offload 1 volume */
262 SOC_DOUBLE_EXT_TLV("Media1 Playback Volume", 2, 0, 8,
263 ARRAY_SIZE(volume_map), 0,
264 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
265 /* Loopback volume */
266 SOC_DOUBLE_EXT_TLV("Loopback Capture Volume", 3, 0, 8,
267 ARRAY_SIZE(volume_map), 0,
268 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
269 /* Mic Capture volume */
270 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8,
271 ARRAY_SIZE(volume_map), 0,
272 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
273};
274
275/* Create DMA buffer page table for DSP */
276static int create_adsp_page_table(struct hsw_priv_data *pdata,
277 struct snd_soc_pcm_runtime *rtd,
278 unsigned char *dma_area, size_t size, int pcm, int stream)
279{
280 int i, pages;
281
282 if (size % PAGE_SIZE)
283 pages = (size / PAGE_SIZE) + 1;
284 else
285 pages = size / PAGE_SIZE;
286
287 dev_dbg(rtd->dev, "generating page table for %p size 0x%zu pages %d\n",
288 dma_area, size, pages);
289
290 for (i = 0; i < pages; i++) {
291 u32 idx = (((i << 2) + i)) >> 1;
292 u32 pfn = (virt_to_phys(dma_area + i * PAGE_SIZE)) >> PAGE_SHIFT;
293 u32 *pg_table;
294
295 dev_dbg(rtd->dev, "pfn i %i idx %d pfn %x\n", i, idx, pfn);
296
297 pg_table = (u32*)(pdata->pcm_pg[pcm][stream] + idx);
298
299 if (i & 1)
300 *pg_table |= (pfn << 4);
301 else
302 *pg_table |= pfn;
303 }
304
305 return 0;
306}
307
308/* this may get called several times by oss emulation */
309static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
310 struct snd_pcm_hw_params *params)
311{
312 struct snd_soc_pcm_runtime *rtd = substream->private_data;
313 struct snd_pcm_runtime *runtime = substream->runtime;
314 struct hsw_priv_data *pdata =
315 snd_soc_platform_get_drvdata(rtd->platform);
316 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
317 struct sst_hsw *hsw = pdata->hsw;
318 struct sst_module *module_data;
319 struct sst_dsp *dsp;
320 enum sst_hsw_stream_type stream_type;
321 enum sst_hsw_stream_path_id path_id;
322 u32 rate, bits, map, pages, module_id;
323 u8 channels;
324 int ret;
325
326 /* stream direction */
327 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
328 path_id = SST_HSW_STREAM_PATH_SSP0_OUT;
329 else
330 path_id = SST_HSW_STREAM_PATH_SSP0_IN;
331
332 /* DSP stream type depends on DAI ID */
333 switch (rtd->cpu_dai->id) {
334 case 0:
335 stream_type = SST_HSW_STREAM_TYPE_SYSTEM;
336 module_id = SST_HSW_MODULE_PCM_SYSTEM;
337 break;
338 case 1:
339 case 2:
340 stream_type = SST_HSW_STREAM_TYPE_RENDER;
341 module_id = SST_HSW_MODULE_PCM;
342 break;
343 case 3:
344 /* path ID needs to be OUT for loopback */
345 stream_type = SST_HSW_STREAM_TYPE_LOOPBACK;
346 path_id = SST_HSW_STREAM_PATH_SSP0_OUT;
347 module_id = SST_HSW_MODULE_PCM_REFERENCE;
348 break;
349 case 4:
350 stream_type = SST_HSW_STREAM_TYPE_CAPTURE;
351 module_id = SST_HSW_MODULE_PCM_CAPTURE;
352 break;
353 default:
354 dev_err(rtd->dev, "error: invalid DAI ID %d\n",
355 rtd->cpu_dai->id);
356 return -EINVAL;
357 };
358
359 ret = sst_hsw_stream_format(hsw, pcm_data->stream,
360 path_id, stream_type, SST_HSW_STREAM_FORMAT_PCM_FORMAT);
361 if (ret < 0) {
362 dev_err(rtd->dev, "error: failed to set format %d\n", ret);
363 return ret;
364 }
365
366 rate = params_rate(params);
367 ret = sst_hsw_stream_set_rate(hsw, pcm_data->stream, rate);
368 if (ret < 0) {
369 dev_err(rtd->dev, "error: could not set rate %d\n", rate);
370 return ret;
371 }
372
373 switch (params_format(params)) {
374 case SNDRV_PCM_FORMAT_S16_LE:
375 bits = SST_HSW_DEPTH_16BIT;
376 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 16);
377 break;
378 case SNDRV_PCM_FORMAT_S24_LE:
379 bits = SST_HSW_DEPTH_24BIT;
380 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 32);
381 break;
382 default:
383 dev_err(rtd->dev, "error: invalid format %d\n",
384 params_format(params));
385 return -EINVAL;
386 }
387
388 ret = sst_hsw_stream_set_bits(hsw, pcm_data->stream, bits);
389 if (ret < 0) {
390 dev_err(rtd->dev, "error: could not set bits %d\n", bits);
391 return ret;
392 }
393
394 /* we only support stereo atm */
395 channels = params_channels(params);
396 if (channels != 2) {
397 dev_err(rtd->dev, "error: invalid channels %d\n", channels);
398 return -EINVAL;
399 }
400
401 map = create_channel_map(SST_HSW_CHANNEL_CONFIG_STEREO);
402 sst_hsw_stream_set_map_config(hsw, pcm_data->stream,
403 map, SST_HSW_CHANNEL_CONFIG_STEREO);
404
405 ret = sst_hsw_stream_set_channels(hsw, pcm_data->stream, channels);
406 if (ret < 0) {
407 dev_err(rtd->dev, "error: could not set channels %d\n",
408 channels);
409 return ret;
410 }
411
412 ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
413 if (ret < 0) {
414 dev_err(rtd->dev, "error: could not allocate %d bytes for PCM %d\n",
415 params_buffer_bytes(params), ret);
416 return ret;
417 }
418
419 ret = create_adsp_page_table(pdata, rtd, runtime->dma_area,
420 runtime->dma_bytes, rtd->cpu_dai->id, substream->stream);
421 if (ret < 0)
422 return ret;
423
424 sst_hsw_stream_set_style(hsw, pcm_data->stream,
425 SST_HSW_INTERLEAVING_PER_CHANNEL);
426
427 if (runtime->dma_bytes % PAGE_SIZE)
428 pages = (runtime->dma_bytes / PAGE_SIZE) + 1;
429 else
430 pages = runtime->dma_bytes / PAGE_SIZE;
431
432 ret = sst_hsw_stream_buffer(hsw, pcm_data->stream,
433 virt_to_phys(pdata->pcm_pg[rtd->cpu_dai->id][substream->stream]),
434 pages, runtime->dma_bytes, 0,
435 (u32)(virt_to_phys(runtime->dma_area) >> PAGE_SHIFT));
436 if (ret < 0) {
437 dev_err(rtd->dev, "error: failed to set DMA buffer %d\n", ret);
438 return ret;
439 }
440
441 dsp = sst_hsw_get_dsp(hsw);
442
443 module_data = sst_module_get_from_id(dsp, module_id);
444 if (module_data == NULL) {
445 dev_err(rtd->dev, "error: failed to get module config\n");
446 return -EINVAL;
447 }
448
449 /* we use hardcoded memory offsets atm, will be updated for new FW */
450 if (stream_type == SST_HSW_STREAM_TYPE_CAPTURE) {
451 sst_hsw_stream_set_module_info(hsw, pcm_data->stream,
452 SST_HSW_MODULE_PCM_CAPTURE, module_data->entry);
453 sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
454 0x449400, 0x4000);
455 sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
456 0x400000, 0);
457 } else { /* stream_type == SST_HSW_STREAM_TYPE_SYSTEM */
458 sst_hsw_stream_set_module_info(hsw, pcm_data->stream,
459 SST_HSW_MODULE_PCM_SYSTEM, module_data->entry);
460
461 sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
462 module_data->offset, module_data->size);
463 sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
464 0x44d400, 0x3800);
465
466 sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
467 module_data->offset, module_data->size);
468 sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
469 0x400000, 0);
470 }
471
472 ret = sst_hsw_stream_commit(hsw, pcm_data->stream);
473 if (ret < 0) {
474 dev_err(rtd->dev, "error: failed to commit stream %d\n", ret);
475 return ret;
476 }
477
478 ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1);
479 if (ret < 0)
480 dev_err(rtd->dev, "error: failed to pause %d\n", ret);
481
482 return 0;
483}
484
485static int hsw_pcm_hw_free(struct snd_pcm_substream *substream)
486{
487 snd_pcm_lib_free_pages(substream);
488 return 0;
489}
490
491static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
492{
493 struct snd_soc_pcm_runtime *rtd = substream->private_data;
494 struct hsw_priv_data *pdata =
495 snd_soc_platform_get_drvdata(rtd->platform);
496 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
497 struct sst_hsw *hsw = pdata->hsw;
498
499 switch (cmd) {
500 case SNDRV_PCM_TRIGGER_START:
501 case SNDRV_PCM_TRIGGER_RESUME:
502 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
503 sst_hsw_stream_resume(hsw, pcm_data->stream, 0);
504 break;
505 case SNDRV_PCM_TRIGGER_STOP:
506 case SNDRV_PCM_TRIGGER_SUSPEND:
507 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
508 sst_hsw_stream_pause(hsw, pcm_data->stream, 0);
509 break;
510 default:
511 break;
512 }
513
514 return 0;
515}
516
517static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data)
518{
519 struct hsw_pcm_data *pcm_data = data;
520 struct snd_pcm_substream *substream = pcm_data->substream;
521 struct snd_pcm_runtime *runtime = substream->runtime;
522 struct snd_soc_pcm_runtime *rtd = substream->private_data;
523 u32 pos;
524
525 pos = frames_to_bytes(runtime,
526 (runtime->control->appl_ptr % runtime->buffer_size));
527
528 dev_dbg(rtd->dev, "PCM: App pointer %d bytes\n", pos);
529
530 /* let alsa know we have play a period */
531 snd_pcm_period_elapsed(substream);
532 return pos;
533}
534
535static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
536{
537 struct snd_soc_pcm_runtime *rtd = substream->private_data;
538 struct snd_pcm_runtime *runtime = substream->runtime;
539 struct hsw_priv_data *pdata =
540 snd_soc_platform_get_drvdata(rtd->platform);
541 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
542 struct sst_hsw *hsw = pdata->hsw;
543 snd_pcm_uframes_t offset;
544
545 offset = bytes_to_frames(runtime,
546 sst_hsw_get_dsp_position(hsw, pcm_data->stream));
547
548 dev_dbg(rtd->dev, "PCM: DMA pointer %zu bytes\n",
549 frames_to_bytes(runtime, (u32)offset));
550 return offset;
551}
552
553static int hsw_pcm_open(struct snd_pcm_substream *substream)
554{
555 struct snd_soc_pcm_runtime *rtd = substream->private_data;
556 struct hsw_priv_data *pdata =
557 snd_soc_platform_get_drvdata(rtd->platform);
558 struct hsw_pcm_data *pcm_data;
559 struct sst_hsw *hsw = pdata->hsw;
560
561 pcm_data = &pdata->pcm[rtd->cpu_dai->id];
562
563 mutex_lock(&pcm_data->mutex);
564
565 snd_soc_pcm_set_drvdata(rtd, pcm_data);
566 pcm_data->substream = substream;
567
568 snd_soc_set_runtime_hwparams(substream, &hsw_pcm_hardware);
569
570 pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id,
571 hsw_notify_pointer, pcm_data);
572 if (pcm_data->stream == NULL) {
573 dev_err(rtd->dev, "error: failed to create stream\n");
574 mutex_unlock(&pcm_data->mutex);
575 return -EINVAL;
576 }
577
578 /* Set previous saved volume */
579 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
580 0, pcm_data->volume[0]);
581 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
582 1, pcm_data->volume[1]);
583
584 mutex_unlock(&pcm_data->mutex);
585 return 0;
586}
587
588static int hsw_pcm_close(struct snd_pcm_substream *substream)
589{
590 struct snd_soc_pcm_runtime *rtd = substream->private_data;
591 struct hsw_priv_data *pdata =
592 snd_soc_platform_get_drvdata(rtd->platform);
593 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
594 struct sst_hsw *hsw = pdata->hsw;
595 int ret;
596
597 mutex_lock(&pcm_data->mutex);
598 ret = sst_hsw_stream_reset(hsw, pcm_data->stream);
599 if (ret < 0) {
600 dev_dbg(rtd->dev, "error: reset stream failed %d\n", ret);
601 goto out;
602 }
603
604 ret = sst_hsw_stream_free(hsw, pcm_data->stream);
605 if (ret < 0) {
606 dev_dbg(rtd->dev, "error: free stream failed %d\n", ret);
607 goto out;
608 }
609 pcm_data->stream = NULL;
610
611out:
612 mutex_unlock(&pcm_data->mutex);
613 return ret;
614}
615
616static struct snd_pcm_ops hsw_pcm_ops = {
617 .open = hsw_pcm_open,
618 .close = hsw_pcm_close,
619 .ioctl = snd_pcm_lib_ioctl,
620 .hw_params = hsw_pcm_hw_params,
621 .hw_free = hsw_pcm_hw_free,
622 .trigger = hsw_pcm_trigger,
623 .pointer = hsw_pcm_pointer,
624 .mmap = snd_pcm_lib_default_mmap,
625};
626
627static void hsw_pcm_free(struct snd_pcm *pcm)
628{
629 snd_pcm_lib_preallocate_free_for_all(pcm);
630}
631
632static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
633{
634 struct snd_pcm *pcm = rtd->pcm;
635 int ret = 0;
636
637 ret = dma_coerce_mask_and_coherent(rtd->card->dev, DMA_BIT_MASK(32));
638 if (ret)
639 return ret;
640
641 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
642 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
643 ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
644 SNDRV_DMA_TYPE_DEV,
645 rtd->card->dev,
646 hsw_pcm_hardware.buffer_bytes_max,
647 hsw_pcm_hardware.buffer_bytes_max);
648 if (ret) {
649 dev_err(rtd->dev, "dma buffer allocation failed %d\n",
650 ret);
651 return ret;
652 }
653 }
654
655 return ret;
656}
657
658#define HSW_FORMATS \
659 (SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE |\
660 SNDRV_PCM_FMTBIT_S32_LE)
661
662static struct snd_soc_dai_driver hsw_dais[] = {
663 {
664 .name = "System Pin",
665 .playback = {
666 .stream_name = "System Playback",
667 .channels_min = 2,
668 .channels_max = 2,
669 .rates = SNDRV_PCM_RATE_48000,
670 .formats = SNDRV_PCM_FMTBIT_S16_LE,
671 },
672 },
673 {
674 /* PCM */
675 .name = "Offload0 Pin",
676 .playback = {
677 .stream_name = "Offload0 Playback",
678 .channels_min = 2,
679 .channels_max = 2,
680 .rates = SNDRV_PCM_RATE_8000_192000,
681 .formats = HSW_FORMATS,
682 },
683 },
684 {
685 /* PCM */
686 .name = "Offload1 Pin",
687 .playback = {
688 .stream_name = "Offload1 Playback",
689 .channels_min = 2,
690 .channels_max = 2,
691 .rates = SNDRV_PCM_RATE_8000_192000,
692 .formats = HSW_FORMATS,
693 },
694 },
695 {
696 .name = "Loopback Pin",
697 .capture = {
698 .stream_name = "Loopback Capture",
699 .channels_min = 2,
700 .channels_max = 2,
701 .rates = SNDRV_PCM_RATE_8000_192000,
702 .formats = HSW_FORMATS,
703 },
704 },
705 {
706 .name = "Capture Pin",
707 .capture = {
708 .stream_name = "Analog Capture",
709 .channels_min = 2,
710 .channels_max = 2,
711 .rates = SNDRV_PCM_RATE_8000_192000,
712 .formats = HSW_FORMATS,
713 },
714 },
715};
716
717static const struct snd_soc_dapm_widget widgets[] = {
718
719 /* Backend DAIs */
720 SND_SOC_DAPM_AIF_IN("SSP0 CODEC IN", NULL, 0, SND_SOC_NOPM, 0, 0),
721 SND_SOC_DAPM_AIF_OUT("SSP0 CODEC OUT", NULL, 0, SND_SOC_NOPM, 0, 0),
722 SND_SOC_DAPM_AIF_IN("SSP1 BT IN", NULL, 0, SND_SOC_NOPM, 0, 0),
723 SND_SOC_DAPM_AIF_OUT("SSP1 BT OUT", NULL, 0, SND_SOC_NOPM, 0, 0),
724
725 /* Global Playback Mixer */
726 SND_SOC_DAPM_MIXER("Playback VMixer", SND_SOC_NOPM, 0, 0, NULL, 0),
727};
728
729static const struct snd_soc_dapm_route graph[] = {
730
731 /* Playback Mixer */
732 {"Playback VMixer", NULL, "System Playback"},
733 {"Playback VMixer", NULL, "Offload0 Playback"},
734 {"Playback VMixer", NULL, "Offload1 Playback"},
735
736 {"SSP0 CODEC OUT", NULL, "Playback VMixer"},
737
738 {"Analog Capture", NULL, "SSP0 CODEC IN"},
739};
740
741static int hsw_pcm_probe(struct snd_soc_platform *platform)
742{
743 struct sst_pdata *pdata = dev_get_platdata(platform->dev);
744 struct hsw_priv_data *priv_data;
745 int i;
746
747 if (!pdata)
748 return -ENODEV;
749
750 priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data), GFP_KERNEL);
751 priv_data->hsw = pdata->dsp;
752 snd_soc_platform_set_drvdata(platform, priv_data);
753
754 /* allocate DSP buffer page tables */
755 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
756
757 mutex_init(&priv_data->pcm[i].mutex);
758
759 /* playback */
760 if (hsw_dais[i].playback.channels_min) {
761 priv_data->pcm_pg[i][0] = kzalloc(PAGE_SIZE, GFP_DMA);
762 if (priv_data->pcm_pg[i][0] == NULL)
763 goto err;
764 }
765
766 /* capture */
767 if (hsw_dais[i].capture.channels_min) {
768 priv_data->pcm_pg[i][1] = kzalloc(PAGE_SIZE, GFP_DMA);
769 if (priv_data->pcm_pg[i][1] == NULL)
770 goto err;
771 }
772 }
773
774 return 0;
775
776err:
777 for (;i >= 0; i--) {
778 if (hsw_dais[i].playback.channels_min)
779 kfree(priv_data->pcm_pg[i][0]);
780 if (hsw_dais[i].capture.channels_min)
781 kfree(priv_data->pcm_pg[i][1]);
782 }
783 return -ENOMEM;
784}
785
786static int hsw_pcm_remove(struct snd_soc_platform *platform)
787{
788 struct hsw_priv_data *priv_data =
789 snd_soc_platform_get_drvdata(platform);
790 int i;
791
792 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
793 if (hsw_dais[i].playback.channels_min)
794 kfree(priv_data->pcm_pg[i][0]);
795 if (hsw_dais[i].capture.channels_min)
796 kfree(priv_data->pcm_pg[i][1]);
797 }
798
799 return 0;
800}
801
802static struct snd_soc_platform_driver hsw_soc_platform = {
803 .probe = hsw_pcm_probe,
804 .remove = hsw_pcm_remove,
805 .ops = &hsw_pcm_ops,
806 .pcm_new = hsw_pcm_new,
807 .pcm_free = hsw_pcm_free,
808 .controls = hsw_volume_controls,
809 .num_controls = ARRAY_SIZE(hsw_volume_controls),
810 .dapm_widgets = widgets,
811 .num_dapm_widgets = ARRAY_SIZE(widgets),
812 .dapm_routes = graph,
813 .num_dapm_routes = ARRAY_SIZE(graph),
814};
815
816static const struct snd_soc_component_driver hsw_dai_component = {
817 .name = "haswell-dai",
818};
819
820static int hsw_pcm_dev_probe(struct platform_device *pdev)
821{
822 struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
823 int ret;
824
825 ret = sst_hsw_dsp_init(&pdev->dev, sst_pdata);
826 if (ret < 0)
827 return -ENODEV;
828
829 ret = snd_soc_register_platform(&pdev->dev, &hsw_soc_platform);
830 if (ret < 0)
831 goto err_plat;
832
833 ret = snd_soc_register_component(&pdev->dev, &hsw_dai_component,
834 hsw_dais, ARRAY_SIZE(hsw_dais));
835 if (ret < 0)
836 goto err_comp;
837
838 return 0;
839
840err_comp:
841 snd_soc_unregister_platform(&pdev->dev);
842err_plat:
843 sst_hsw_dsp_free(&pdev->dev, sst_pdata);
844 return 0;
845}
846
847static int hsw_pcm_dev_remove(struct platform_device *pdev)
848{
849 struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
850
851 snd_soc_unregister_platform(&pdev->dev);
852 snd_soc_unregister_component(&pdev->dev);
853 sst_hsw_dsp_free(&pdev->dev, sst_pdata);
854
855 return 0;
856}
857
858static struct platform_driver hsw_pcm_driver = {
859 .driver = {
860 .name = "haswell-pcm-audio",
861 .owner = THIS_MODULE,
862 },
863
864 .probe = hsw_pcm_dev_probe,
865 .remove = hsw_pcm_dev_remove,
866};
867module_platform_driver(hsw_pcm_driver);
868
869MODULE_AUTHOR("Liam Girdwood, Xingchao Wang");
870MODULE_DESCRIPTION("Haswell/Lynxpoint + Broadwell/Wildcatpoint PCM");
871MODULE_LICENSE("GPL v2");
872MODULE_ALIAS("platform:haswell-pcm-audio");
diff --git a/sound/soc/intel/sst_dsp.h b/sound/soc/intel/sst-mfld-dsp.h
index 0fce1de284ff..3b63edc04b7f 100644
--- a/sound/soc/intel/sst_dsp.h
+++ b/sound/soc/intel/sst-mfld-dsp.h
@@ -1,7 +1,7 @@
1#ifndef __SST_DSP_H__ 1#ifndef __SST_MFLD_DSP_H__
2#define __SST_DSP_H__ 2#define __SST_MFLD_DSP_H__
3/* 3/*
4 * sst_dsp.h - Intel SST Driver for audio engine 4 * sst_mfld_dsp.h - Intel SST Driver for audio engine
5 * 5 *
6 * Copyright (C) 2008-12 Intel Corporation 6 * Copyright (C) 2008-12 Intel Corporation
7 * Authors: Vinod Koul <vinod.koul@linux.intel.com> 7 * Authors: Vinod Koul <vinod.koul@linux.intel.com>
@@ -131,4 +131,4 @@ struct snd_sst_params {
131 struct snd_sst_alloc_params_ext aparams; 131 struct snd_sst_alloc_params_ext aparams;
132}; 132};
133 133
134#endif /* __SST_DSP_H__ */ 134#endif /* __SST_MFLD_DSP_H__ */
diff --git a/sound/soc/intel/sst_platform.c b/sound/soc/intel/sst-mfld-platform.c
index f465a8180863..840306c2ef14 100644
--- a/sound/soc/intel/sst_platform.c
+++ b/sound/soc/intel/sst-mfld-platform.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * sst_platform.c - Intel MID Platform driver 2 * sst_mfld_platform.c - Intel MID Platform driver
3 * 3 *
4 * Copyright (C) 2010-2013 Intel Corp 4 * Copyright (C) 2010-2013 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com> 5 * Author: Vinod Koul <vinod.koul@intel.com>
@@ -33,7 +33,7 @@
33#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
34#include <sound/soc.h> 34#include <sound/soc.h>
35#include <sound/compress_driver.h> 35#include <sound/compress_driver.h>
36#include "sst_platform.h" 36#include "sst-mfld-platform.h"
37 37
38static struct sst_device *sst; 38static struct sst_device *sst;
39static DEFINE_MUTEX(sst_lock); 39static DEFINE_MUTEX(sst_lock);
@@ -709,7 +709,7 @@ static int sst_platform_remove(struct platform_device *pdev)
709 709
710static struct platform_driver sst_platform_driver = { 710static struct platform_driver sst_platform_driver = {
711 .driver = { 711 .driver = {
712 .name = "sst-platform", 712 .name = "sst-mfld-platform",
713 .owner = THIS_MODULE, 713 .owner = THIS_MODULE,
714 }, 714 },
715 .probe = sst_platform_probe, 715 .probe = sst_platform_probe,
@@ -722,4 +722,4 @@ MODULE_DESCRIPTION("ASoC Intel(R) MID Platform driver");
722MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>"); 722MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
723MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>"); 723MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
724MODULE_LICENSE("GPL v2"); 724MODULE_LICENSE("GPL v2");
725MODULE_ALIAS("platform:sst-platform"); 725MODULE_ALIAS("platform:sst-mfld-platform");
diff --git a/sound/soc/intel/sst_platform.h b/sound/soc/intel/sst-mfld-platform.h
index bee64fb7d2ef..0c4e2ddcecb1 100644
--- a/sound/soc/intel/sst_platform.h
+++ b/sound/soc/intel/sst-mfld-platform.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * sst_platform.h - Intel MID Platform driver header file 2 * sst_mfld_platform.h - Intel MID Platform driver header file
3 * 3 *
4 * Copyright (C) 2010 Intel Corp 4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com> 5 * Author: Vinod Koul <vinod.koul@intel.com>
@@ -27,7 +27,7 @@
27#ifndef __SST_PLATFORMDRV_H__ 27#ifndef __SST_PLATFORMDRV_H__
28#define __SST_PLATFORMDRV_H__ 28#define __SST_PLATFORMDRV_H__
29 29
30#include "sst_dsp.h" 30#include "sst-mfld-dsp.h"
31 31
32#define SST_MONO 1 32#define SST_MONO 1
33#define SST_STEREO 2 33#define SST_STEREO 2
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 22ad9c5654b5..e00659351a4e 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -58,7 +58,7 @@ config SND_OMAP_SOC_OSK5912
58 tristate "SoC Audio support for omap osk5912" 58 tristate "SoC Audio support for omap osk5912"
59 depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C 59 depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C
60 select SND_OMAP_SOC_MCBSP 60 select SND_OMAP_SOC_MCBSP
61 select SND_SOC_TLV320AIC23 61 select SND_SOC_TLV320AIC23_I2C
62 help 62 help
63 Say Y if you want to add support for SoC audio on osk5912. 63 Say Y if you want to add support for SoC audio on osk5912.
64 64
@@ -66,7 +66,7 @@ config SND_OMAP_SOC_AM3517EVM
66 tristate "SoC Audio support for OMAP3517 / AM3517 EVM" 66 tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
67 depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C 67 depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
68 select SND_OMAP_SOC_MCBSP 68 select SND_OMAP_SOC_MCBSP
69 select SND_SOC_TLV320AIC23 69 select SND_SOC_TLV320AIC23_I2C
70 help 70 help
71 Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517 71 Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
72 EVM. 72 EVM.
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 629446482a91..f141435b0b4a 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -103,60 +103,62 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
103 if (!codec->hw_write) 103 if (!codec->hw_write)
104 return -EUNATCH; 104 return -EUNATCH;
105 105
106 if (ucontrol->value.enumerated.item[0] >= control->max) 106 if (ucontrol->value.enumerated.item[0] >= control->items)
107 return -EINVAL; 107 return -EINVAL;
108 108
109 mutex_lock(&codec->mutex); 109 snd_soc_dapm_mutex_lock(dapm);
110 110
111 /* Translate selection to bitmap */ 111 /* Translate selection to bitmap */
112 pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]]; 112 pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]];
113 113
114 /* Setup pins after corresponding bits if changed */ 114 /* Setup pins after corresponding bits if changed */
115 pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE)); 115 pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE));
116
116 if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) { 117 if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) {
117 changed = 1; 118 changed = 1;
118 if (pin) 119 if (pin)
119 snd_soc_dapm_enable_pin(dapm, "Mouthpiece"); 120 snd_soc_dapm_enable_pin_unlocked(dapm, "Mouthpiece");
120 else 121 else
121 snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); 122 snd_soc_dapm_disable_pin_unlocked(dapm, "Mouthpiece");
122 } 123 }
123 pin = !!(pins & (1 << AMS_DELTA_EARPIECE)); 124 pin = !!(pins & (1 << AMS_DELTA_EARPIECE));
124 if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) { 125 if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) {
125 changed = 1; 126 changed = 1;
126 if (pin) 127 if (pin)
127 snd_soc_dapm_enable_pin(dapm, "Earpiece"); 128 snd_soc_dapm_enable_pin_unlocked(dapm, "Earpiece");
128 else 129 else
129 snd_soc_dapm_disable_pin(dapm, "Earpiece"); 130 snd_soc_dapm_disable_pin_unlocked(dapm, "Earpiece");
130 } 131 }
131 pin = !!(pins & (1 << AMS_DELTA_MICROPHONE)); 132 pin = !!(pins & (1 << AMS_DELTA_MICROPHONE));
132 if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) { 133 if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) {
133 changed = 1; 134 changed = 1;
134 if (pin) 135 if (pin)
135 snd_soc_dapm_enable_pin(dapm, "Microphone"); 136 snd_soc_dapm_enable_pin_unlocked(dapm, "Microphone");
136 else 137 else
137 snd_soc_dapm_disable_pin(dapm, "Microphone"); 138 snd_soc_dapm_disable_pin_unlocked(dapm, "Microphone");
138 } 139 }
139 pin = !!(pins & (1 << AMS_DELTA_SPEAKER)); 140 pin = !!(pins & (1 << AMS_DELTA_SPEAKER));
140 if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) { 141 if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) {
141 changed = 1; 142 changed = 1;
142 if (pin) 143 if (pin)
143 snd_soc_dapm_enable_pin(dapm, "Speaker"); 144 snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker");
144 else 145 else
145 snd_soc_dapm_disable_pin(dapm, "Speaker"); 146 snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker");
146 } 147 }
147 pin = !!(pins & (1 << AMS_DELTA_AGC)); 148 pin = !!(pins & (1 << AMS_DELTA_AGC));
148 if (pin != ams_delta_audio_agc) { 149 if (pin != ams_delta_audio_agc) {
149 ams_delta_audio_agc = pin; 150 ams_delta_audio_agc = pin;
150 changed = 1; 151 changed = 1;
151 if (pin) 152 if (pin)
152 snd_soc_dapm_enable_pin(dapm, "AGCIN"); 153 snd_soc_dapm_enable_pin_unlocked(dapm, "AGCIN");
153 else 154 else
154 snd_soc_dapm_disable_pin(dapm, "AGCIN"); 155 snd_soc_dapm_disable_pin_unlocked(dapm, "AGCIN");
155 } 156 }
157
156 if (changed) 158 if (changed)
157 snd_soc_dapm_sync(dapm); 159 snd_soc_dapm_sync_unlocked(dapm);
158 160
159 mutex_unlock(&codec->mutex); 161 snd_soc_dapm_mutex_unlock(dapm);
160 162
161 return changed; 163 return changed;
162} 164}
@@ -194,13 +196,11 @@ static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol,
194 return 0; 196 return 0;
195} 197}
196 198
197static const struct soc_enum ams_delta_audio_enum[] = { 199static const SOC_ENUM_SINGLE_EXT_DECL(ams_delta_audio_enum,
198 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ams_delta_audio_mode), 200 ams_delta_audio_mode);
199 ams_delta_audio_mode),
200};
201 201
202static const struct snd_kcontrol_new ams_delta_audio_controls[] = { 202static const struct snd_kcontrol_new ams_delta_audio_controls[] = {
203 SOC_ENUM_EXT("Audio Mode", ams_delta_audio_enum[0], 203 SOC_ENUM_EXT("Audio Mode", ams_delta_audio_enum,
204 ams_delta_get_audio_mode, ams_delta_set_audio_mode), 204 ams_delta_get_audio_mode, ams_delta_set_audio_mode),
205}; 205};
206 206
@@ -315,12 +315,17 @@ static void cx81801_close(struct tty_struct *tty)
315 v253_ops.close(tty); 315 v253_ops.close(tty);
316 316
317 /* Revert back to default audio input/output constellation */ 317 /* Revert back to default audio input/output constellation */
318 snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); 318 snd_soc_dapm_mutex_lock(dapm);
319 snd_soc_dapm_enable_pin(dapm, "Earpiece"); 319
320 snd_soc_dapm_enable_pin(dapm, "Microphone"); 320 snd_soc_dapm_disable_pin_unlocked(dapm, "Mouthpiece");
321 snd_soc_dapm_disable_pin(dapm, "Speaker"); 321 snd_soc_dapm_enable_pin_unlocked(dapm, "Earpiece");
322 snd_soc_dapm_disable_pin(dapm, "AGCIN"); 322 snd_soc_dapm_enable_pin_unlocked(dapm, "Microphone");
323 snd_soc_dapm_sync(dapm); 323 snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker");
324 snd_soc_dapm_disable_pin_unlocked(dapm, "AGCIN");
325
326 snd_soc_dapm_sync_unlocked(dapm);
327
328 snd_soc_dapm_mutex_unlock(codec);
324} 329}
325 330
326/* Line discipline .hangup() */ 331/* Line discipline .hangup() */
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 3fde9e402710..fd4d9c809e50 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -68,26 +68,30 @@ static void n810_ext_control(struct snd_soc_dapm_context *dapm)
68 break; 68 break;
69 } 69 }
70 70
71 snd_soc_dapm_mutex_lock(dapm);
72
71 if (n810_spk_func) 73 if (n810_spk_func)
72 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 74 snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk");
73 else 75 else
74 snd_soc_dapm_disable_pin(dapm, "Ext Spk"); 76 snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk");
75 77
76 if (hp) 78 if (hp)
77 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 79 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
78 else 80 else
79 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 81 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
80 if (line1l) 82 if (line1l)
81 snd_soc_dapm_enable_pin(dapm, "LINE1L"); 83 snd_soc_dapm_enable_pin_unlocked(dapm, "LINE1L");
82 else 84 else
83 snd_soc_dapm_disable_pin(dapm, "LINE1L"); 85 snd_soc_dapm_disable_pin_unlocked(dapm, "LINE1L");
84 86
85 if (n810_dmic_func) 87 if (n810_dmic_func)
86 snd_soc_dapm_enable_pin(dapm, "DMic"); 88 snd_soc_dapm_enable_pin_unlocked(dapm, "DMic");
87 else 89 else
88 snd_soc_dapm_disable_pin(dapm, "DMic"); 90 snd_soc_dapm_disable_pin_unlocked(dapm, "DMic");
91
92 snd_soc_dapm_sync_unlocked(dapm);
89 93
90 snd_soc_dapm_sync(dapm); 94 snd_soc_dapm_mutex_unlock(dapm);
91} 95}
92 96
93static int n810_startup(struct snd_pcm_substream *substream) 97static int n810_startup(struct snd_pcm_substream *substream)
@@ -305,7 +309,9 @@ static int __init n810_soc_init(void)
305 int err; 309 int err;
306 struct device *dev; 310 struct device *dev;
307 311
308 if (!(machine_is_nokia_n810() || machine_is_nokia_n810_wimax())) 312 if (!of_have_populated_dt() ||
313 (!of_machine_is_compatible("nokia,n810") &&
314 !of_machine_is_compatible("nokia,n810-wimax")))
309 return -ENODEV; 315 return -ENODEV;
310 316
311 n810_snd_device = platform_device_alloc("soc-audio", -1); 317 n810_snd_device = platform_device_alloc("soc-audio", -1);
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 611179c3bca4..7fb3d4b10370 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -74,26 +74,30 @@ static void rx51_ext_control(struct snd_soc_dapm_context *dapm)
74 break; 74 break;
75 } 75 }
76 76
77 snd_soc_dapm_mutex_lock(dapm);
78
77 if (rx51_spk_func) 79 if (rx51_spk_func)
78 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 80 snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk");
79 else 81 else
80 snd_soc_dapm_disable_pin(dapm, "Ext Spk"); 82 snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk");
81 if (rx51_dmic_func) 83 if (rx51_dmic_func)
82 snd_soc_dapm_enable_pin(dapm, "DMic"); 84 snd_soc_dapm_enable_pin_unlocked(dapm, "DMic");
83 else 85 else
84 snd_soc_dapm_disable_pin(dapm, "DMic"); 86 snd_soc_dapm_disable_pin_unlocked(dapm, "DMic");
85 if (hp) 87 if (hp)
86 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 88 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
87 else 89 else
88 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 90 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
89 if (hs) 91 if (hs)
90 snd_soc_dapm_enable_pin(dapm, "HS Mic"); 92 snd_soc_dapm_enable_pin_unlocked(dapm, "HS Mic");
91 else 93 else
92 snd_soc_dapm_disable_pin(dapm, "HS Mic"); 94 snd_soc_dapm_disable_pin_unlocked(dapm, "HS Mic");
93 95
94 gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout); 96 gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout);
95 97
96 snd_soc_dapm_sync(dapm); 98 snd_soc_dapm_sync_unlocked(dapm);
99
100 snd_soc_dapm_mutex_unlock(dapm);
97} 101}
98 102
99static int rx51_startup(struct snd_pcm_substream *substream) 103static int rx51_startup(struct snd_pcm_substream *substream)
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 916ff63d85d0..5a88136aa800 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -47,51 +47,55 @@ static int corgi_spk_func;
47 47
48static void corgi_ext_control(struct snd_soc_dapm_context *dapm) 48static void corgi_ext_control(struct snd_soc_dapm_context *dapm)
49{ 49{
50 snd_soc_dapm_mutex_lock(dapm);
51
50 /* set up jack connection */ 52 /* set up jack connection */
51 switch (corgi_jack_func) { 53 switch (corgi_jack_func) {
52 case CORGI_HP: 54 case CORGI_HP:
53 /* set = unmute headphone */ 55 /* set = unmute headphone */
54 gpio_set_value(CORGI_GPIO_MUTE_L, 1); 56 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
55 gpio_set_value(CORGI_GPIO_MUTE_R, 1); 57 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
56 snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 58 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
57 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 59 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
58 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 60 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
59 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 61 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
60 break; 62 break;
61 case CORGI_MIC: 63 case CORGI_MIC:
62 /* reset = mute headphone */ 64 /* reset = mute headphone */
63 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 65 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
64 gpio_set_value(CORGI_GPIO_MUTE_R, 0); 66 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
65 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 67 snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
66 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 68 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
67 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 69 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
68 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 70 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
69 break; 71 break;
70 case CORGI_LINE: 72 case CORGI_LINE:
71 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 73 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
72 gpio_set_value(CORGI_GPIO_MUTE_R, 0); 74 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
73 snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 75 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
74 snd_soc_dapm_enable_pin(dapm, "Line Jack"); 76 snd_soc_dapm_enable_pin_unlocked(dapm, "Line Jack");
75 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 77 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
76 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 78 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
77 break; 79 break;
78 case CORGI_HEADSET: 80 case CORGI_HEADSET:
79 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 81 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
80 gpio_set_value(CORGI_GPIO_MUTE_R, 1); 82 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
81 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 83 snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
82 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 84 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
83 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 85 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
84 snd_soc_dapm_enable_pin(dapm, "Headset Jack"); 86 snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack");
85 break; 87 break;
86 } 88 }
87 89
88 if (corgi_spk_func == CORGI_SPK_ON) 90 if (corgi_spk_func == CORGI_SPK_ON)
89 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 91 snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk");
90 else 92 else
91 snd_soc_dapm_disable_pin(dapm, "Ext Spk"); 93 snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk");
92 94
93 /* signal a DAPM event */ 95 /* signal a DAPM event */
94 snd_soc_dapm_sync(dapm); 96 snd_soc_dapm_sync_unlocked(dapm);
97
98 snd_soc_dapm_mutex_unlock(dapm);
95} 99}
96 100
97static int corgi_startup(struct snd_pcm_substream *substream) 101static int corgi_startup(struct snd_pcm_substream *substream)
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index aeb08f5f3e1c..41ab6678b65d 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -45,27 +45,31 @@ static void magician_ext_control(struct snd_soc_codec *codec)
45{ 45{
46 struct snd_soc_dapm_context *dapm = &codec->dapm; 46 struct snd_soc_dapm_context *dapm = &codec->dapm;
47 47
48 snd_soc_dapm_mutex_lock(dapm);
49
48 if (magician_spk_switch) 50 if (magician_spk_switch)
49 snd_soc_dapm_enable_pin(dapm, "Speaker"); 51 snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker");
50 else 52 else
51 snd_soc_dapm_disable_pin(dapm, "Speaker"); 53 snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker");
52 if (magician_hp_switch) 54 if (magician_hp_switch)
53 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 55 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
54 else 56 else
55 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 57 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
56 58
57 switch (magician_in_sel) { 59 switch (magician_in_sel) {
58 case MAGICIAN_MIC: 60 case MAGICIAN_MIC:
59 snd_soc_dapm_disable_pin(dapm, "Headset Mic"); 61 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Mic");
60 snd_soc_dapm_enable_pin(dapm, "Call Mic"); 62 snd_soc_dapm_enable_pin_unlocked(dapm, "Call Mic");
61 break; 63 break;
62 case MAGICIAN_MIC_EXT: 64 case MAGICIAN_MIC_EXT:
63 snd_soc_dapm_disable_pin(dapm, "Call Mic"); 65 snd_soc_dapm_disable_pin_unlocked(dapm, "Call Mic");
64 snd_soc_dapm_enable_pin(dapm, "Headset Mic"); 66 snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Mic");
65 break; 67 break;
66 } 68 }
67 69
68 snd_soc_dapm_sync(dapm); 70 snd_soc_dapm_sync_unlocked(dapm);
71
72 snd_soc_dapm_mutex_unlock(dapm);
69} 73}
70 74
71static int magician_startup(struct snd_pcm_substream *substream) 75static int magician_startup(struct snd_pcm_substream *substream)
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index d1b6bf9c8583..1373b017a951 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -46,61 +46,66 @@ static int spitz_mic_gpio;
46 46
47static void spitz_ext_control(struct snd_soc_dapm_context *dapm) 47static void spitz_ext_control(struct snd_soc_dapm_context *dapm)
48{ 48{
49 snd_soc_dapm_mutex_lock(dapm);
50
49 if (spitz_spk_func == SPITZ_SPK_ON) 51 if (spitz_spk_func == SPITZ_SPK_ON)
50 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 52 snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk");
51 else 53 else
52 snd_soc_dapm_disable_pin(dapm, "Ext Spk"); 54 snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk");
53 55
54 /* set up jack connection */ 56 /* set up jack connection */
55 switch (spitz_jack_func) { 57 switch (spitz_jack_func) {
56 case SPITZ_HP: 58 case SPITZ_HP:
57 /* enable and unmute hp jack, disable mic bias */ 59 /* enable and unmute hp jack, disable mic bias */
58 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 60 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
59 snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 61 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
60 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 62 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
61 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 63 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
62 gpio_set_value(SPITZ_GPIO_MUTE_L, 1); 64 gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
63 gpio_set_value(SPITZ_GPIO_MUTE_R, 1); 65 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
64 break; 66 break;
65 case SPITZ_MIC: 67 case SPITZ_MIC:
66 /* enable mic jack and bias, mute hp */ 68 /* enable mic jack and bias, mute hp */
67 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 69 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
68 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 70 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
69 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 71 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
70 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 72 snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
71 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 73 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
72 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 74 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
73 break; 75 break;
74 case SPITZ_LINE: 76 case SPITZ_LINE:
75 /* enable line jack, disable mic bias and mute hp */ 77 /* enable line jack, disable mic bias and mute hp */
76 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 78 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
77 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 79 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
78 snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 80 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
79 snd_soc_dapm_enable_pin(dapm, "Line Jack"); 81 snd_soc_dapm_enable_pin_unlocked(dapm, "Line Jack");
80 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 82 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
81 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 83 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
82 break; 84 break;
83 case SPITZ_HEADSET: 85 case SPITZ_HEADSET:
84 /* enable and unmute headset jack enable mic bias, mute L hp */ 86 /* enable and unmute headset jack enable mic bias, mute L hp */
85 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 87 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
86 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 88 snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
87 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 89 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
88 snd_soc_dapm_enable_pin(dapm, "Headset Jack"); 90 snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack");
89 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 91 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
90 gpio_set_value(SPITZ_GPIO_MUTE_R, 1); 92 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
91 break; 93 break;
92 case SPITZ_HP_OFF: 94 case SPITZ_HP_OFF:
93 95
94 /* jack removed, everything off */ 96 /* jack removed, everything off */
95 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 97 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
96 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 98 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
97 snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 99 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
98 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 100 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
99 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 101 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
100 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 102 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
101 break; 103 break;
102 } 104 }
103 snd_soc_dapm_sync(dapm); 105
106 snd_soc_dapm_sync_unlocked(dapm);
107
108 snd_soc_dapm_mutex_unlock(dapm);
104} 109}
105 110
106static int spitz_startup(struct snd_pcm_substream *substream) 111static int spitz_startup(struct snd_pcm_substream *substream)
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index d6f38d7ecc1c..cead1658d10a 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -48,31 +48,35 @@ static void tosa_ext_control(struct snd_soc_codec *codec)
48{ 48{
49 struct snd_soc_dapm_context *dapm = &codec->dapm; 49 struct snd_soc_dapm_context *dapm = &codec->dapm;
50 50
51 snd_soc_dapm_mutex_lock(dapm);
52
51 /* set up jack connection */ 53 /* set up jack connection */
52 switch (tosa_jack_func) { 54 switch (tosa_jack_func) {
53 case TOSA_HP: 55 case TOSA_HP:
54 snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); 56 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic (Internal)");
55 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 57 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
56 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 58 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
57 break; 59 break;
58 case TOSA_MIC_INT: 60 case TOSA_MIC_INT:
59 snd_soc_dapm_enable_pin(dapm, "Mic (Internal)"); 61 snd_soc_dapm_enable_pin_unlocked(dapm, "Mic (Internal)");
60 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 62 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
61 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 63 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
62 break; 64 break;
63 case TOSA_HEADSET: 65 case TOSA_HEADSET:
64 snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); 66 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic (Internal)");
65 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 67 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
66 snd_soc_dapm_enable_pin(dapm, "Headset Jack"); 68 snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack");
67 break; 69 break;
68 } 70 }
69 71
70 if (tosa_spk_func == TOSA_SPK_ON) 72 if (tosa_spk_func == TOSA_SPK_ON)
71 snd_soc_dapm_enable_pin(dapm, "Speaker"); 73 snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker");
72 else 74 else
73 snd_soc_dapm_disable_pin(dapm, "Speaker"); 75 snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker");
76
77 snd_soc_dapm_sync_unlocked(dapm);
74 78
75 snd_soc_dapm_sync(dapm); 79 snd_soc_dapm_mutex_unlock(dapm);
76} 80}
77 81
78static int tosa_startup(struct snd_pcm_substream *substream) 82static int tosa_startup(struct snd_pcm_substream *substream)
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 454f41cfc828..f2e289180e46 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -59,7 +59,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750
59 select SND_SOC_WM8750 59 select SND_SOC_WM8750
60 select SND_S3C2412_SOC_I2S 60 select SND_S3C2412_SOC_I2S
61 help 61 help
62 Sat Y if you want to add support for SoC audio on the Jive. 62 Say Y if you want to add support for SoC audio on the Jive.
63 63
64config SND_SOC_SAMSUNG_SMDK_WM8580 64config SND_SOC_SAMSUNG_SMDK_WM8580
65 tristate "SoC I2S Audio support for WM8580 on SMDK" 65 tristate "SoC I2S Audio support for WM8580 on SMDK"
@@ -117,7 +117,7 @@ config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23
117 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" 117 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
118 depends on SND_SOC_SAMSUNG && ARCH_S3C24XX 118 depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
119 select SND_S3C24XX_I2S 119 select SND_S3C24XX_I2S
120 select SND_SOC_TLV320AIC23 120 select SND_SOC_TLV320AIC23_I2C
121 select SND_SOC_SAMSUNG_SIMTEC 121 select SND_SOC_SAMSUNG_SIMTEC
122 122
123config SND_SOC_SAMSUNG_SIMTEC_HERMES 123config SND_SOC_SAMSUNG_SIMTEC_HERMES
@@ -145,11 +145,11 @@ config SND_SOC_SAMSUNG_RX1950_UDA1380
145 145
146config SND_SOC_SAMSUNG_SMDK_WM9713 146config SND_SOC_SAMSUNG_SMDK_WM9713
147 tristate "SoC AC97 Audio support for SMDK with WM9713" 147 tristate "SoC AC97 Audio support for SMDK with WM9713"
148 depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 || MACH_SMDKV310 || MACH_SMDKC210) 148 depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110)
149 select SND_SOC_WM9713 149 select SND_SOC_WM9713
150 select SND_SAMSUNG_AC97 150 select SND_SAMSUNG_AC97
151 help 151 help
152 Sat Y if you want to add support for SoC audio on the SMDK. 152 Say Y if you want to add support for SoC audio on the SMDK.
153 153
154config SND_SOC_SMARTQ 154config SND_SOC_SMARTQ
155 tristate "SoC I2S Audio support for SmartQ board" 155 tristate "SoC I2S Audio support for SmartQ board"
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile
index 0ff492df7929..7d0051ced838 100644
--- a/sound/soc/sh/rcar/Makefile
+++ b/sound/soc/sh/rcar/Makefile
@@ -1,2 +1,2 @@
1snd-soc-rcar-objs := core.o gen.o scu.o adg.o ssi.o 1snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o
2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file 2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index a53235c4d1b0..953f1cce982d 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -25,15 +25,165 @@ struct rsnd_adg {
25}; 25};
26 26
27#define for_each_rsnd_clk(pos, adg, i) \ 27#define for_each_rsnd_clk(pos, adg, i) \
28 for (i = 0, (pos) = adg->clk[i]; \ 28 for (i = 0; \
29 i < CLKMAX; \ 29 (i < CLKMAX) && \
30 i++, (pos) = adg->clk[i]) 30 ((pos) = adg->clk[i]); \
31 i++)
31#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg) 32#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
32 33
33static int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, 34
34 struct rsnd_mod *mod, 35static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
35 unsigned int src_rate, 36{
36 unsigned int dst_rate) 37 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
38 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
39 int id = rsnd_mod_id(mod);
40 int ws = id;
41
42 if (rsnd_ssi_is_pin_sharing(rsnd_ssi_mod_get(priv, id))) {
43 switch (id) {
44 case 1:
45 case 2:
46 ws = 0;
47 break;
48 case 4:
49 ws = 3;
50 break;
51 case 8:
52 ws = 7;
53 break;
54 }
55 }
56
57 return (0x6 + ws) << 8;
58}
59
60static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai,
61 struct rsnd_mod *mod,
62 struct rsnd_dai_stream *io,
63 u32 timsel)
64{
65 int is_play = rsnd_dai_is_play(rdai, io);
66 int id = rsnd_mod_id(mod);
67 int shift = (id % 2) ? 16 : 0;
68 u32 mask, ws;
69 u32 in, out;
70
71 ws = rsnd_adg_ssi_ws_timing_gen2(io);
72
73 in = (is_play) ? timsel : ws;
74 out = (is_play) ? ws : timsel;
75
76 in = in << shift;
77 out = out << shift;
78 mask = 0xffff << shift;
79
80 switch (id / 2) {
81 case 0:
82 rsnd_mod_bset(mod, SRCIN_TIMSEL0, mask, in);
83 rsnd_mod_bset(mod, SRCOUT_TIMSEL0, mask, out);
84 break;
85 case 1:
86 rsnd_mod_bset(mod, SRCIN_TIMSEL1, mask, in);
87 rsnd_mod_bset(mod, SRCOUT_TIMSEL1, mask, out);
88 break;
89 case 2:
90 rsnd_mod_bset(mod, SRCIN_TIMSEL2, mask, in);
91 rsnd_mod_bset(mod, SRCOUT_TIMSEL2, mask, out);
92 break;
93 case 3:
94 rsnd_mod_bset(mod, SRCIN_TIMSEL3, mask, in);
95 rsnd_mod_bset(mod, SRCOUT_TIMSEL3, mask, out);
96 break;
97 case 4:
98 rsnd_mod_bset(mod, SRCIN_TIMSEL4, mask, in);
99 rsnd_mod_bset(mod, SRCOUT_TIMSEL4, mask, out);
100 break;
101 }
102
103 return 0;
104}
105
106int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
107 struct rsnd_dai *rdai,
108 struct rsnd_dai_stream *io,
109 unsigned int src_rate,
110 unsigned int dst_rate)
111{
112 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
113 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
114 struct device *dev = rsnd_priv_to_dev(priv);
115 int idx, sel, div, step, ret;
116 u32 val, en;
117 unsigned int min, diff;
118 unsigned int sel_rate [] = {
119 clk_get_rate(adg->clk[CLKA]), /* 0000: CLKA */
120 clk_get_rate(adg->clk[CLKB]), /* 0001: CLKB */
121 clk_get_rate(adg->clk[CLKC]), /* 0010: CLKC */
122 adg->rbga_rate_for_441khz_div_6,/* 0011: RBGA */
123 adg->rbgb_rate_for_48khz_div_6, /* 0100: RBGB */
124 };
125
126 min = ~0;
127 val = 0;
128 en = 0;
129 for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) {
130 idx = 0;
131 step = 2;
132
133 if (!sel_rate[sel])
134 continue;
135
136 for (div = 2; div <= 98304; div += step) {
137 diff = abs(src_rate - sel_rate[sel] / div);
138 if (min > diff) {
139 val = (sel << 8) | idx;
140 min = diff;
141 en = 1 << (sel + 1); /* fixme */
142 }
143
144 /*
145 * step of 0_0000 / 0_0001 / 0_1101
146 * are out of order
147 */
148 if ((idx > 2) && (idx % 2))
149 step *= 2;
150 if (idx == 0x1c) {
151 div += step;
152 step *= 2;
153 }
154 idx++;
155 }
156 }
157
158 if (min == ~0) {
159 dev_err(dev, "no Input clock\n");
160 return -EIO;
161 }
162
163 ret = rsnd_adg_set_src_timsel_gen2(rdai, mod, io, val);
164 if (ret < 0) {
165 dev_err(dev, "timsel error\n");
166 return ret;
167 }
168
169 rsnd_mod_bset(mod, DIV_EN, en, en);
170
171 return 0;
172}
173
174int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
175 struct rsnd_dai *rdai,
176 struct rsnd_dai_stream *io)
177{
178 u32 val = rsnd_adg_ssi_ws_timing_gen2(io);
179
180 return rsnd_adg_set_src_timsel_gen2(rdai, mod, io, val);
181}
182
183int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
184 struct rsnd_mod *mod,
185 unsigned int src_rate,
186 unsigned int dst_rate)
37{ 187{
38 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 188 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
39 struct device *dev = rsnd_priv_to_dev(priv); 189 struct device *dev = rsnd_priv_to_dev(priv);
@@ -91,18 +241,6 @@ find_rate:
91 return 0; 241 return 0;
92} 242}
93 243
94int rsnd_adg_set_convert_clk(struct rsnd_priv *priv,
95 struct rsnd_mod *mod,
96 unsigned int src_rate,
97 unsigned int dst_rate)
98{
99 if (rsnd_is_gen1(priv))
100 return rsnd_adg_set_convert_clk_gen1(priv, mod,
101 src_rate, dst_rate);
102
103 return -EINVAL;
104}
105
106static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val) 244static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val)
107{ 245{
108 int id = rsnd_mod_id(mod); 246 int id = rsnd_mod_id(mod);
@@ -254,13 +392,13 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
254} 392}
255 393
256int rsnd_adg_probe(struct platform_device *pdev, 394int rsnd_adg_probe(struct platform_device *pdev,
257 struct rcar_snd_info *info,
258 struct rsnd_priv *priv) 395 struct rsnd_priv *priv)
259{ 396{
260 struct rsnd_adg *adg; 397 struct rsnd_adg *adg;
261 struct device *dev = rsnd_priv_to_dev(priv); 398 struct device *dev = rsnd_priv_to_dev(priv);
262 struct clk *clk; 399 struct clk *clk, *clk_orig;
263 int i; 400 int i;
401 bool use_old_style = false;
264 402
265 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); 403 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
266 if (!adg) { 404 if (!adg) {
@@ -268,10 +406,39 @@ int rsnd_adg_probe(struct platform_device *pdev,
268 return -ENOMEM; 406 return -ENOMEM;
269 } 407 }
270 408
271 adg->clk[CLKA] = clk_get(NULL, "audio_clk_a"); 409 clk_orig = devm_clk_get(dev, NULL);
272 adg->clk[CLKB] = clk_get(NULL, "audio_clk_b"); 410 adg->clk[CLKA] = devm_clk_get(dev, "clk_a");
273 adg->clk[CLKC] = clk_get(NULL, "audio_clk_c"); 411 adg->clk[CLKB] = devm_clk_get(dev, "clk_b");
274 adg->clk[CLKI] = clk_get(NULL, "audio_clk_internal"); 412 adg->clk[CLKC] = devm_clk_get(dev, "clk_c");
413 adg->clk[CLKI] = devm_clk_get(dev, "clk_i");
414
415 /*
416 * It request device dependent audio clock.
417 * But above all clks will indicate rsnd module clock
418 * if platform doesn't it
419 */
420 for_each_rsnd_clk(clk, adg, i) {
421 if (clk_orig == clk) {
422 dev_warn(dev,
423 "doesn't have device dependent clock, use independent clock\n");
424 use_old_style = true;
425 break;
426 }
427 }
428
429 /*
430 * note:
431 * these exist in order to keep compatible with
432 * platform which has device independent audio clock,
433 * but will be removed soon
434 */
435 if (use_old_style) {
436 adg->clk[CLKA] = devm_clk_get(NULL, "audio_clk_a");
437 adg->clk[CLKB] = devm_clk_get(NULL, "audio_clk_b");
438 adg->clk[CLKC] = devm_clk_get(NULL, "audio_clk_c");
439 adg->clk[CLKI] = devm_clk_get(NULL, "audio_clk_internal");
440 }
441
275 for_each_rsnd_clk(clk, adg, i) { 442 for_each_rsnd_clk(clk, adg, i) {
276 if (IS_ERR(clk)) { 443 if (IS_ERR(clk)) {
277 dev_err(dev, "Audio clock failed\n"); 444 dev_err(dev, "Audio clock failed\n");
@@ -287,14 +454,3 @@ int rsnd_adg_probe(struct platform_device *pdev,
287 454
288 return 0; 455 return 0;
289} 456}
290
291void rsnd_adg_remove(struct platform_device *pdev,
292 struct rsnd_priv *priv)
293{
294 struct rsnd_adg *adg = priv->adg;
295 struct clk *clk;
296 int i;
297
298 for_each_rsnd_clk(clk, adg, i)
299 clk_put(clk);
300}
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 743de5e3b1e1..6a1b45df8101 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -73,13 +73,13 @@
73 * | +- ssi[2] 73 * | +- ssi[2]
74 * | ... 74 * | ...
75 * | 75 * |
76 * | ** these control scu 76 * | ** these control src
77 * | 77 * |
78 * +- scu 78 * +- src
79 * | 79 * |
80 * +- scu[0] 80 * +- src[0]
81 * +- scu[1] 81 * +- src[1]
82 * +- scu[2] 82 * +- src[2]
83 * ... 83 * ...
84 * 84 *
85 * 85 *
@@ -107,6 +107,11 @@
107 (!(priv->info->func) ? 0 : \ 107 (!(priv->info->func) ? 0 : \
108 priv->info->func(param)) 108 priv->info->func(param))
109 109
110#define rsnd_is_enable_path(io, name) \
111 ((io)->info ? (io)->info->name : NULL)
112#define rsnd_info_id(priv, io, name) \
113 ((io)->info->name - priv->info->name##_info)
114
110/* 115/*
111 * rsnd_mod functions 116 * rsnd_mod functions
112 */ 117 */
@@ -121,17 +126,19 @@ char *rsnd_mod_name(struct rsnd_mod *mod)
121void rsnd_mod_init(struct rsnd_priv *priv, 126void rsnd_mod_init(struct rsnd_priv *priv,
122 struct rsnd_mod *mod, 127 struct rsnd_mod *mod,
123 struct rsnd_mod_ops *ops, 128 struct rsnd_mod_ops *ops,
129 enum rsnd_mod_type type,
124 int id) 130 int id)
125{ 131{
126 mod->priv = priv; 132 mod->priv = priv;
127 mod->id = id; 133 mod->id = id;
128 mod->ops = ops; 134 mod->ops = ops;
129 INIT_LIST_HEAD(&mod->list); 135 mod->type = type;
130} 136}
131 137
132/* 138/*
133 * rsnd_dma functions 139 * rsnd_dma functions
134 */ 140 */
141static void __rsnd_dma_start(struct rsnd_dma *dma);
135static void rsnd_dma_continue(struct rsnd_dma *dma) 142static void rsnd_dma_continue(struct rsnd_dma *dma)
136{ 143{
137 /* push next A or B plane */ 144 /* push next A or B plane */
@@ -142,8 +149,9 @@ static void rsnd_dma_continue(struct rsnd_dma *dma)
142void rsnd_dma_start(struct rsnd_dma *dma) 149void rsnd_dma_start(struct rsnd_dma *dma)
143{ 150{
144 /* push both A and B plane*/ 151 /* push both A and B plane*/
152 dma->offset = 0;
145 dma->submit_loop = 2; 153 dma->submit_loop = 2;
146 schedule_work(&dma->work); 154 __rsnd_dma_start(dma);
147} 155}
148 156
149void rsnd_dma_stop(struct rsnd_dma *dma) 157void rsnd_dma_stop(struct rsnd_dma *dma)
@@ -156,12 +164,26 @@ void rsnd_dma_stop(struct rsnd_dma *dma)
156static void rsnd_dma_complete(void *data) 164static void rsnd_dma_complete(void *data)
157{ 165{
158 struct rsnd_dma *dma = (struct rsnd_dma *)data; 166 struct rsnd_dma *dma = (struct rsnd_dma *)data;
159 struct rsnd_priv *priv = dma->priv; 167 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
168 struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma));
169 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
160 unsigned long flags; 170 unsigned long flags;
161 171
162 rsnd_lock(priv, flags); 172 rsnd_lock(priv, flags);
163 173
164 dma->complete(dma); 174 /*
175 * Renesas sound Gen1 needs 1 DMAC,
176 * Gen2 needs 2 DMAC.
177 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
178 * But, Audio-DMAC-peri-peri doesn't have interrupt,
179 * and this driver is assuming that here.
180 *
181 * If Audio-DMAC-peri-peri has interrpt,
182 * rsnd_dai_pointer_update() will be called twice,
183 * ant it will breaks io->byte_pos
184 */
185
186 rsnd_dai_pointer_update(io, io->byte_per_period);
165 187
166 if (dma->submit_loop) 188 if (dma->submit_loop)
167 rsnd_dma_continue(dma); 189 rsnd_dma_continue(dma);
@@ -169,20 +191,23 @@ static void rsnd_dma_complete(void *data)
169 rsnd_unlock(priv, flags); 191 rsnd_unlock(priv, flags);
170} 192}
171 193
172static void rsnd_dma_do_work(struct work_struct *work) 194static void __rsnd_dma_start(struct rsnd_dma *dma)
173{ 195{
174 struct rsnd_dma *dma = container_of(work, struct rsnd_dma, work); 196 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
175 struct rsnd_priv *priv = dma->priv; 197 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
198 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
199 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
176 struct device *dev = rsnd_priv_to_dev(priv); 200 struct device *dev = rsnd_priv_to_dev(priv);
177 struct dma_async_tx_descriptor *desc; 201 struct dma_async_tx_descriptor *desc;
178 dma_addr_t buf; 202 dma_addr_t buf;
179 size_t len; 203 size_t len = io->byte_per_period;
180 int i; 204 int i;
181 205
182 for (i = 0; i < dma->submit_loop; i++) { 206 for (i = 0; i < dma->submit_loop; i++) {
183 207
184 if (dma->inquiry(dma, &buf, &len) < 0) 208 buf = runtime->dma_addr +
185 return; 209 rsnd_dai_pointer_offset(io, dma->offset + len);
210 dma->offset = len;
186 211
187 desc = dmaengine_prep_slave_single( 212 desc = dmaengine_prep_slave_single(
188 dma->chan, buf, len, dma->dir, 213 dma->chan, buf, len, dma->dir,
@@ -204,16 +229,20 @@ static void rsnd_dma_do_work(struct work_struct *work)
204 } 229 }
205} 230}
206 231
232static void rsnd_dma_do_work(struct work_struct *work)
233{
234 struct rsnd_dma *dma = container_of(work, struct rsnd_dma, work);
235
236 __rsnd_dma_start(dma);
237}
238
207int rsnd_dma_available(struct rsnd_dma *dma) 239int rsnd_dma_available(struct rsnd_dma *dma)
208{ 240{
209 return !!dma->chan; 241 return !!dma->chan;
210} 242}
211 243
212int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, 244int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
213 int is_play, int id, 245 int is_play, int id)
214 int (*inquiry)(struct rsnd_dma *dma,
215 dma_addr_t *buf, int *len),
216 int (*complete)(struct rsnd_dma *dma))
217{ 246{
218 struct device *dev = rsnd_priv_to_dev(priv); 247 struct device *dev = rsnd_priv_to_dev(priv);
219 struct dma_slave_config cfg; 248 struct dma_slave_config cfg;
@@ -246,9 +275,6 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
246 goto rsnd_dma_init_err; 275 goto rsnd_dma_init_err;
247 276
248 dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; 277 dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
249 dma->priv = priv;
250 dma->inquiry = inquiry;
251 dma->complete = complete;
252 INIT_WORK(&dma->work, rsnd_dma_do_work); 278 INIT_WORK(&dma->work, rsnd_dma_do_work);
253 279
254 return 0; 280 return 0;
@@ -271,26 +297,42 @@ void rsnd_dma_quit(struct rsnd_priv *priv,
271/* 297/*
272 * rsnd_dai functions 298 * rsnd_dai functions
273 */ 299 */
274#define rsnd_dai_call(rdai, io, fn) \ 300#define __rsnd_mod_call(mod, func, rdai, io) \
275({ \ 301({ \
276 struct rsnd_mod *mod, *n; \ 302 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \
277 int ret = 0; \ 303 struct device *dev = rsnd_priv_to_dev(priv); \
278 for_each_rsnd_mod(mod, n, io) { \ 304 dev_dbg(dev, "%s [%d] %s\n", \
279 ret = rsnd_mod_call(mod, fn, rdai, io); \ 305 rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \
280 if (ret < 0) \ 306 (mod)->ops->func(mod, rdai, io); \
281 break; \ 307})
282 } \ 308
283 ret; \ 309#define rsnd_mod_call(mod, func, rdai, io) \
310 (!(mod) ? -ENODEV : \
311 !((mod)->ops->func) ? 0 : \
312 __rsnd_mod_call(mod, func, (rdai), (io)))
313
314#define rsnd_dai_call(rdai, io, fn) \
315({ \
316 struct rsnd_mod *mod; \
317 int ret = 0, i; \
318 for (i = 0; i < RSND_MOD_MAX; i++) { \
319 mod = (io)->mod[i]; \
320 if (!mod) \
321 continue; \
322 ret = rsnd_mod_call(mod, fn, (rdai), (io)); \
323 if (ret < 0) \
324 break; \
325 } \
326 ret; \
284}) 327})
285 328
286int rsnd_dai_connect(struct rsnd_dai *rdai, 329static int rsnd_dai_connect(struct rsnd_mod *mod,
287 struct rsnd_mod *mod, 330 struct rsnd_dai_stream *io)
288 struct rsnd_dai_stream *io)
289{ 331{
290 if (!mod) 332 if (!mod)
291 return -EIO; 333 return -EIO;
292 334
293 if (!list_empty(&mod->list)) { 335 if (io->mod[mod->type]) {
294 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 336 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
295 struct device *dev = rsnd_priv_to_dev(priv); 337 struct device *dev = rsnd_priv_to_dev(priv);
296 338
@@ -300,14 +342,8 @@ int rsnd_dai_connect(struct rsnd_dai *rdai,
300 return -EIO; 342 return -EIO;
301 } 343 }
302 344
303 list_add_tail(&mod->list, &io->head); 345 io->mod[mod->type] = mod;
304 346 mod->io = io;
305 return 0;
306}
307
308int rsnd_dai_disconnect(struct rsnd_mod *mod)
309{
310 list_del_init(&mod->list);
311 347
312 return 0; 348 return 0;
313} 349}
@@ -316,7 +352,7 @@ int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai)
316{ 352{
317 int id = rdai - priv->rdai; 353 int id = rdai - priv->rdai;
318 354
319 if ((id < 0) || (id >= rsnd_dai_nr(priv))) 355 if ((id < 0) || (id >= rsnd_rdai_nr(priv)))
320 return -EINVAL; 356 return -EINVAL;
321 357
322 return id; 358 return id;
@@ -324,7 +360,7 @@ int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai)
324 360
325struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id) 361struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id)
326{ 362{
327 if ((id < 0) || (id >= rsnd_dai_nr(priv))) 363 if ((id < 0) || (id >= rsnd_rdai_nr(priv)))
328 return NULL; 364 return NULL;
329 365
330 return priv->rdai + id; 366 return priv->rdai + id;
@@ -382,10 +418,6 @@ static int rsnd_dai_stream_init(struct rsnd_dai_stream *io,
382{ 418{
383 struct snd_pcm_runtime *runtime = substream->runtime; 419 struct snd_pcm_runtime *runtime = substream->runtime;
384 420
385 if (!list_empty(&io->head))
386 return -EIO;
387
388 INIT_LIST_HEAD(&io->head);
389 io->substream = substream; 421 io->substream = substream;
390 io->byte_pos = 0; 422 io->byte_pos = 0;
391 io->period_pos = 0; 423 io->period_pos = 0;
@@ -440,10 +472,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
440 if (ret < 0) 472 if (ret < 0)
441 goto dai_trigger_end; 473 goto dai_trigger_end;
442 474
443 ret = rsnd_gen_path_init(priv, rdai, io);
444 if (ret < 0)
445 goto dai_trigger_end;
446
447 ret = rsnd_dai_call(rdai, io, init); 475 ret = rsnd_dai_call(rdai, io, init);
448 if (ret < 0) 476 if (ret < 0)
449 goto dai_trigger_end; 477 goto dai_trigger_end;
@@ -461,10 +489,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
461 if (ret < 0) 489 if (ret < 0)
462 goto dai_trigger_end; 490 goto dai_trigger_end;
463 491
464 ret = rsnd_gen_path_exit(priv, rdai, io);
465 if (ret < 0)
466 goto dai_trigger_end;
467
468 ret = rsnd_platform_call(priv, dai, stop, ssi_id); 492 ret = rsnd_platform_call(priv, dai, stop, ssi_id);
469 if (ret < 0) 493 if (ret < 0)
470 goto dai_trigger_end; 494 goto dai_trigger_end;
@@ -540,24 +564,86 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
540 .set_fmt = rsnd_soc_dai_set_fmt, 564 .set_fmt = rsnd_soc_dai_set_fmt,
541}; 565};
542 566
567static int rsnd_path_init(struct rsnd_priv *priv,
568 struct rsnd_dai *rdai,
569 struct rsnd_dai_stream *io)
570{
571 struct rsnd_mod *mod;
572 struct rsnd_dai_platform_info *dai_info = rdai->info;
573 int ret;
574 int ssi_id = -1;
575 int src_id = -1;
576
577 /*
578 * Gen1 is created by SRU/SSI, and this SRU is base module of
579 * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU)
580 *
581 * Easy image is..
582 * Gen1 SRU = Gen2 SCU + SSIU + etc
583 *
584 * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
585 * using fixed path.
586 */
587 if (dai_info) {
588 if (rsnd_is_enable_path(io, ssi))
589 ssi_id = rsnd_info_id(priv, io, ssi);
590 if (rsnd_is_enable_path(io, src))
591 src_id = rsnd_info_id(priv, io, src);
592 } else {
593 /* get SSI's ID */
594 mod = rsnd_ssi_mod_get_frm_dai(priv,
595 rsnd_dai_id(priv, rdai),
596 rsnd_dai_is_play(rdai, io));
597 if (!mod)
598 return 0;
599 ssi_id = src_id = rsnd_mod_id(mod);
600 }
601
602 ret = 0;
603
604 /* SRC */
605 if (src_id >= 0) {
606 mod = rsnd_src_mod_get(priv, src_id);
607 ret = rsnd_dai_connect(mod, io);
608 if (ret < 0)
609 return ret;
610 }
611
612 /* SSI */
613 if (ssi_id >= 0) {
614 mod = rsnd_ssi_mod_get(priv, ssi_id);
615 ret = rsnd_dai_connect(mod, io);
616 if (ret < 0)
617 return ret;
618 }
619
620 return ret;
621}
622
543static int rsnd_dai_probe(struct platform_device *pdev, 623static int rsnd_dai_probe(struct platform_device *pdev,
544 struct rcar_snd_info *info,
545 struct rsnd_priv *priv) 624 struct rsnd_priv *priv)
546{ 625{
547 struct snd_soc_dai_driver *drv; 626 struct snd_soc_dai_driver *drv;
627 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
548 struct rsnd_dai *rdai; 628 struct rsnd_dai *rdai;
549 struct rsnd_mod *pmod, *cmod; 629 struct rsnd_mod *pmod, *cmod;
550 struct device *dev = rsnd_priv_to_dev(priv); 630 struct device *dev = rsnd_priv_to_dev(priv);
551 int dai_nr; 631 int dai_nr = info->dai_info_nr;
552 int i; 632 int i;
553 633
554 /* get max dai nr */ 634 /*
555 for (dai_nr = 0; dai_nr < 32; dai_nr++) { 635 * dai_nr should be set via dai_info_nr,
556 pmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 1); 636 * but allow it to keeping compatible
557 cmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 0); 637 */
638 if (!dai_nr) {
639 /* get max dai nr */
640 for (dai_nr = 0; dai_nr < 32; dai_nr++) {
641 pmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 1);
642 cmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 0);
558 643
559 if (!pmod && !cmod) 644 if (!pmod && !cmod)
560 break; 645 break;
646 }
561 } 647 }
562 648
563 if (!dai_nr) { 649 if (!dai_nr) {
@@ -572,7 +658,13 @@ static int rsnd_dai_probe(struct platform_device *pdev,
572 return -ENOMEM; 658 return -ENOMEM;
573 } 659 }
574 660
661 priv->rdai_nr = dai_nr;
662 priv->daidrv = drv;
663 priv->rdai = rdai;
664
575 for (i = 0; i < dai_nr; i++) { 665 for (i = 0; i < dai_nr; i++) {
666 if (info->dai_info)
667 rdai[i].info = &info->dai_info[i];
576 668
577 pmod = rsnd_ssi_mod_get_frm_dai(priv, i, 1); 669 pmod = rsnd_ssi_mod_get_frm_dai(priv, i, 1);
578 cmod = rsnd_ssi_mod_get_frm_dai(priv, i, 0); 670 cmod = rsnd_ssi_mod_get_frm_dai(priv, i, 0);
@@ -580,9 +672,6 @@ static int rsnd_dai_probe(struct platform_device *pdev,
580 /* 672 /*
581 * init rsnd_dai 673 * init rsnd_dai
582 */ 674 */
583 INIT_LIST_HEAD(&rdai[i].playback.head);
584 INIT_LIST_HEAD(&rdai[i].capture.head);
585
586 snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i); 675 snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i);
587 676
588 /* 677 /*
@@ -595,12 +684,20 @@ static int rsnd_dai_probe(struct platform_device *pdev,
595 drv[i].playback.formats = RSND_FMTS; 684 drv[i].playback.formats = RSND_FMTS;
596 drv[i].playback.channels_min = 2; 685 drv[i].playback.channels_min = 2;
597 drv[i].playback.channels_max = 2; 686 drv[i].playback.channels_max = 2;
687
688 if (info->dai_info)
689 rdai[i].playback.info = &info->dai_info[i].playback;
690 rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
598 } 691 }
599 if (cmod) { 692 if (cmod) {
600 drv[i].capture.rates = RSND_RATES; 693 drv[i].capture.rates = RSND_RATES;
601 drv[i].capture.formats = RSND_FMTS; 694 drv[i].capture.formats = RSND_FMTS;
602 drv[i].capture.channels_min = 2; 695 drv[i].capture.channels_min = 2;
603 drv[i].capture.channels_max = 2; 696 drv[i].capture.channels_max = 2;
697
698 if (info->dai_info)
699 rdai[i].capture.info = &info->dai_info[i].capture;
700 rsnd_path_init(priv, &rdai[i], &rdai[i].capture);
604 } 701 }
605 702
606 dev_dbg(dev, "%s (%s/%s)\n", rdai[i].name, 703 dev_dbg(dev, "%s (%s/%s)\n", rdai[i].name,
@@ -608,18 +705,9 @@ static int rsnd_dai_probe(struct platform_device *pdev,
608 cmod ? "capture" : " -- "); 705 cmod ? "capture" : " -- ");
609 } 706 }
610 707
611 priv->dai_nr = dai_nr;
612 priv->daidrv = drv;
613 priv->rdai = rdai;
614
615 return 0; 708 return 0;
616} 709}
617 710
618static void rsnd_dai_remove(struct platform_device *pdev,
619 struct rsnd_priv *priv)
620{
621}
622
623/* 711/*
624 * pcm ops 712 * pcm ops
625 */ 713 */
@@ -713,7 +801,16 @@ static int rsnd_probe(struct platform_device *pdev)
713 struct rcar_snd_info *info; 801 struct rcar_snd_info *info;
714 struct rsnd_priv *priv; 802 struct rsnd_priv *priv;
715 struct device *dev = &pdev->dev; 803 struct device *dev = &pdev->dev;
716 int ret; 804 struct rsnd_dai *rdai;
805 int (*probe_func[])(struct platform_device *pdev,
806 struct rsnd_priv *priv) = {
807 rsnd_gen_probe,
808 rsnd_ssi_probe,
809 rsnd_src_probe,
810 rsnd_adg_probe,
811 rsnd_dai_probe,
812 };
813 int ret, i;
717 814
718 info = pdev->dev.platform_data; 815 info = pdev->dev.platform_data;
719 if (!info) { 816 if (!info) {
@@ -737,25 +834,21 @@ static int rsnd_probe(struct platform_device *pdev)
737 /* 834 /*
738 * init each module 835 * init each module
739 */ 836 */
740 ret = rsnd_gen_probe(pdev, info, priv); 837 for (i = 0; i < ARRAY_SIZE(probe_func); i++) {
741 if (ret < 0) 838 ret = probe_func[i](pdev, priv);
742 return ret; 839 if (ret)
743 840 return ret;
744 ret = rsnd_scu_probe(pdev, info, priv); 841 }
745 if (ret < 0)
746 return ret;
747 842
748 ret = rsnd_adg_probe(pdev, info, priv); 843 for_each_rsnd_dai(rdai, priv, i) {
749 if (ret < 0) 844 ret = rsnd_dai_call(rdai, &rdai->playback, probe);
750 return ret; 845 if (ret)
846 return ret;
751 847
752 ret = rsnd_ssi_probe(pdev, info, priv); 848 ret = rsnd_dai_call(rdai, &rdai->capture, probe);
753 if (ret < 0) 849 if (ret)
754 return ret; 850 return ret;
755 851 }
756 ret = rsnd_dai_probe(pdev, info, priv);
757 if (ret < 0)
758 return ret;
759 852
760 /* 853 /*
761 * asoc register 854 * asoc register
@@ -767,7 +860,7 @@ static int rsnd_probe(struct platform_device *pdev)
767 } 860 }
768 861
769 ret = snd_soc_register_component(dev, &rsnd_soc_component, 862 ret = snd_soc_register_component(dev, &rsnd_soc_component,
770 priv->daidrv, rsnd_dai_nr(priv)); 863 priv->daidrv, rsnd_rdai_nr(priv));
771 if (ret < 0) { 864 if (ret < 0) {
772 dev_err(dev, "cannot snd dai register\n"); 865 dev_err(dev, "cannot snd dai register\n");
773 goto exit_snd_soc; 866 goto exit_snd_soc;
@@ -789,17 +882,20 @@ exit_snd_soc:
789static int rsnd_remove(struct platform_device *pdev) 882static int rsnd_remove(struct platform_device *pdev)
790{ 883{
791 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev); 884 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev);
885 struct rsnd_dai *rdai;
886 int ret, i;
792 887
793 pm_runtime_disable(&pdev->dev); 888 pm_runtime_disable(&pdev->dev);
794 889
795 /* 890 for_each_rsnd_dai(rdai, priv, i) {
796 * remove each module 891 ret = rsnd_dai_call(rdai, &rdai->playback, remove);
797 */ 892 if (ret)
798 rsnd_ssi_remove(pdev, priv); 893 return ret;
799 rsnd_adg_remove(pdev, priv); 894
800 rsnd_scu_remove(pdev, priv); 895 ret = rsnd_dai_call(rdai, &rdai->capture, remove);
801 rsnd_dai_remove(pdev, priv); 896 if (ret)
802 rsnd_gen_remove(pdev, priv); 897 return ret;
898 }
803 899
804 return 0; 900 return 0;
805} 901}
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index add088bd4b2a..9094970dbdfb 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -155,62 +155,6 @@ static int rsnd_gen_regmap_init(struct rsnd_priv *priv,
155 return 0; 155 return 0;
156} 156}
157 157
158int rsnd_gen_path_init(struct rsnd_priv *priv,
159 struct rsnd_dai *rdai,
160 struct rsnd_dai_stream *io)
161{
162 struct rsnd_mod *mod;
163 int ret;
164 int id;
165
166 /*
167 * Gen1 is created by SRU/SSI, and this SRU is base module of
168 * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU)
169 *
170 * Easy image is..
171 * Gen1 SRU = Gen2 SCU + SSIU + etc
172 *
173 * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
174 * using fixed path.
175 *
176 * Then, SSI id = SCU id here
177 */
178
179 /* get SSI's ID */
180 mod = rsnd_ssi_mod_get_frm_dai(priv,
181 rsnd_dai_id(priv, rdai),
182 rsnd_dai_is_play(rdai, io));
183 id = rsnd_mod_id(mod);
184
185 /* SSI */
186 mod = rsnd_ssi_mod_get(priv, id);
187 ret = rsnd_dai_connect(rdai, mod, io);
188 if (ret < 0)
189 return ret;
190
191 /* SCU */
192 mod = rsnd_scu_mod_get(priv, id);
193 ret = rsnd_dai_connect(rdai, mod, io);
194
195 return ret;
196}
197
198int rsnd_gen_path_exit(struct rsnd_priv *priv,
199 struct rsnd_dai *rdai,
200 struct rsnd_dai_stream *io)
201{
202 struct rsnd_mod *mod, *n;
203 int ret = 0;
204
205 /*
206 * remove all mod from rdai
207 */
208 for_each_rsnd_mod(mod, n, io)
209 ret |= rsnd_dai_disconnect(mod);
210
211 return ret;
212}
213
214/* 158/*
215 * Gen2 159 * Gen2
216 */ 160 */
@@ -229,14 +173,40 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
229 RSND_GEN2_S_REG(gen, SSIU, SSI_MODE0, 0x800), 173 RSND_GEN2_S_REG(gen, SSIU, SSI_MODE0, 0x800),
230 RSND_GEN2_S_REG(gen, SSIU, SSI_MODE1, 0x804), 174 RSND_GEN2_S_REG(gen, SSIU, SSI_MODE1, 0x804),
231 /* FIXME: it needs SSI_MODE2/3 in the future */ 175 /* FIXME: it needs SSI_MODE2/3 in the future */
176 RSND_GEN2_M_REG(gen, SSIU, SSI_BUSIF_MODE, 0x0, 0x80),
177 RSND_GEN2_M_REG(gen, SSIU, SSI_BUSIF_ADINR,0x4, 0x80),
178 RSND_GEN2_M_REG(gen, SSIU, SSI_CTRL, 0x10, 0x80),
232 RSND_GEN2_M_REG(gen, SSIU, INT_ENABLE, 0x18, 0x80), 179 RSND_GEN2_M_REG(gen, SSIU, INT_ENABLE, 0x18, 0x80),
233 180
181 RSND_GEN2_M_REG(gen, SCU, SRC_BUSIF_MODE, 0x0, 0x20),
182 RSND_GEN2_M_REG(gen, SCU, SRC_ROUTE_MODE0,0xc, 0x20),
183 RSND_GEN2_M_REG(gen, SCU, SRC_CTRL, 0x10, 0x20),
184 RSND_GEN2_M_REG(gen, SCU, SRC_SWRSR, 0x200, 0x40),
185 RSND_GEN2_M_REG(gen, SCU, SRC_SRCIR, 0x204, 0x40),
186 RSND_GEN2_M_REG(gen, SCU, SRC_ADINR, 0x214, 0x40),
187 RSND_GEN2_M_REG(gen, SCU, SRC_IFSCR, 0x21c, 0x40),
188 RSND_GEN2_M_REG(gen, SCU, SRC_IFSVR, 0x220, 0x40),
189 RSND_GEN2_M_REG(gen, SCU, SRC_SRCCR, 0x224, 0x40),
190 RSND_GEN2_M_REG(gen, SCU, SRC_BSDSR, 0x22c, 0x40),
191 RSND_GEN2_M_REG(gen, SCU, SRC_BSISR, 0x238, 0x40),
192
234 RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00), 193 RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00),
235 RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04), 194 RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04),
236 RSND_GEN2_S_REG(gen, ADG, SSICKR, 0x08), 195 RSND_GEN2_S_REG(gen, ADG, SSICKR, 0x08),
237 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c), 196 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c),
238 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10), 197 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10),
239 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL2, 0x14), 198 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL2, 0x14),
199 RSND_GEN2_S_REG(gen, ADG, DIV_EN, 0x30),
200 RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL0, 0x34),
201 RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL1, 0x38),
202 RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL2, 0x3c),
203 RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL3, 0x40),
204 RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL4, 0x44),
205 RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL0, 0x48),
206 RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL1, 0x4c),
207 RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL2, 0x50),
208 RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL3, 0x54),
209 RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL4, 0x58),
240 210
241 RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40), 211 RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40),
242 RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40), 212 RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40),
@@ -249,7 +219,6 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
249} 219}
250 220
251static int rsnd_gen2_probe(struct platform_device *pdev, 221static int rsnd_gen2_probe(struct platform_device *pdev,
252 struct rcar_snd_info *info,
253 struct rsnd_priv *priv) 222 struct rsnd_priv *priv)
254{ 223{
255 struct device *dev = rsnd_priv_to_dev(priv); 224 struct device *dev = rsnd_priv_to_dev(priv);
@@ -283,7 +252,7 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
283 return ret; 252 return ret;
284 253
285 dev_dbg(dev, "Gen2 device probed\n"); 254 dev_dbg(dev, "Gen2 device probed\n");
286 dev_dbg(dev, "SRU : %08x => %p\n", scu_res->start, 255 dev_dbg(dev, "SCU : %08x => %p\n", scu_res->start,
287 gen->base[RSND_GEN2_SCU]); 256 gen->base[RSND_GEN2_SCU]);
288 dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, 257 dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start,
289 gen->base[RSND_GEN2_ADG]); 258 gen->base[RSND_GEN2_ADG]);
@@ -317,7 +286,7 @@ static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
317 RSND_GEN1_S_REG(gen, SRU, SRC_ROUTE_CTRL, 0xc0), 286 RSND_GEN1_S_REG(gen, SRU, SRC_ROUTE_CTRL, 0xc0),
318 RSND_GEN1_S_REG(gen, SRU, SSI_MODE0, 0xD0), 287 RSND_GEN1_S_REG(gen, SRU, SSI_MODE0, 0xD0),
319 RSND_GEN1_S_REG(gen, SRU, SSI_MODE1, 0xD4), 288 RSND_GEN1_S_REG(gen, SRU, SSI_MODE1, 0xD4),
320 RSND_GEN1_M_REG(gen, SRU, BUSIF_MODE, 0x20, 0x4), 289 RSND_GEN1_M_REG(gen, SRU, SRC_BUSIF_MODE, 0x20, 0x4),
321 RSND_GEN1_M_REG(gen, SRU, SRC_ROUTE_MODE0,0x50, 0x8), 290 RSND_GEN1_M_REG(gen, SRU, SRC_ROUTE_MODE0,0x50, 0x8),
322 RSND_GEN1_M_REG(gen, SRU, SRC_SWRSR, 0x200, 0x40), 291 RSND_GEN1_M_REG(gen, SRU, SRC_SWRSR, 0x200, 0x40),
323 RSND_GEN1_M_REG(gen, SRU, SRC_SRCIR, 0x204, 0x40), 292 RSND_GEN1_M_REG(gen, SRU, SRC_SRCIR, 0x204, 0x40),
@@ -347,7 +316,6 @@ static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
347} 316}
348 317
349static int rsnd_gen1_probe(struct platform_device *pdev, 318static int rsnd_gen1_probe(struct platform_device *pdev,
350 struct rcar_snd_info *info,
351 struct rsnd_priv *priv) 319 struct rsnd_priv *priv)
352{ 320{
353 struct device *dev = rsnd_priv_to_dev(priv); 321 struct device *dev = rsnd_priv_to_dev(priv);
@@ -392,7 +360,6 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
392 * Gen 360 * Gen
393 */ 361 */
394int rsnd_gen_probe(struct platform_device *pdev, 362int rsnd_gen_probe(struct platform_device *pdev,
395 struct rcar_snd_info *info,
396 struct rsnd_priv *priv) 363 struct rsnd_priv *priv)
397{ 364{
398 struct device *dev = rsnd_priv_to_dev(priv); 365 struct device *dev = rsnd_priv_to_dev(priv);
@@ -409,17 +376,12 @@ int rsnd_gen_probe(struct platform_device *pdev,
409 376
410 ret = -ENODEV; 377 ret = -ENODEV;
411 if (rsnd_is_gen1(priv)) 378 if (rsnd_is_gen1(priv))
412 ret = rsnd_gen1_probe(pdev, info, priv); 379 ret = rsnd_gen1_probe(pdev, priv);
413 else if (rsnd_is_gen2(priv)) 380 else if (rsnd_is_gen2(priv))
414 ret = rsnd_gen2_probe(pdev, info, priv); 381 ret = rsnd_gen2_probe(pdev, priv);
415 382
416 if (ret < 0) 383 if (ret < 0)
417 dev_err(dev, "unknown generation R-Car sound device\n"); 384 dev_err(dev, "unknown generation R-Car sound device\n");
418 385
419 return ret; 386 return ret;
420} 387}
421
422void rsnd_gen_remove(struct platform_device *pdev,
423 struct rsnd_priv *priv)
424{
425}
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 4ca66cd899c8..c46e0afa54ae 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -32,15 +32,9 @@
32 */ 32 */
33enum rsnd_reg { 33enum rsnd_reg {
34 /* SRU/SCU/SSIU */ 34 /* SRU/SCU/SSIU */
35 RSND_REG_SRC_ROUTE_SEL, /* for Gen1 */
36 RSND_REG_SRC_TMG_SEL0, /* for Gen1 */
37 RSND_REG_SRC_TMG_SEL1, /* for Gen1 */
38 RSND_REG_SRC_TMG_SEL2, /* for Gen1 */
39 RSND_REG_SRC_ROUTE_CTRL, /* for Gen1 */
40 RSND_REG_SSI_MODE0, 35 RSND_REG_SSI_MODE0,
41 RSND_REG_SSI_MODE1, 36 RSND_REG_SSI_MODE1,
42 RSND_REG_BUSIF_MODE, 37 RSND_REG_SRC_BUSIF_MODE,
43 RSND_REG_INT_ENABLE, /* for Gen2 */
44 RSND_REG_SRC_ROUTE_MODE0, 38 RSND_REG_SRC_ROUTE_MODE0,
45 RSND_REG_SRC_SWRSR, 39 RSND_REG_SRC_SWRSR,
46 RSND_REG_SRC_SRCIR, 40 RSND_REG_SRC_SRCIR,
@@ -48,7 +42,6 @@ enum rsnd_reg {
48 RSND_REG_SRC_IFSCR, 42 RSND_REG_SRC_IFSCR,
49 RSND_REG_SRC_IFSVR, 43 RSND_REG_SRC_IFSVR,
50 RSND_REG_SRC_SRCCR, 44 RSND_REG_SRC_SRCCR,
51 RSND_REG_SRC_MNFSR,
52 45
53 /* ADG */ 46 /* ADG */
54 RSND_REG_BRRA, 47 RSND_REG_BRRA,
@@ -56,10 +49,6 @@ enum rsnd_reg {
56 RSND_REG_SSICKR, 49 RSND_REG_SSICKR,
57 RSND_REG_AUDIO_CLK_SEL0, 50 RSND_REG_AUDIO_CLK_SEL0,
58 RSND_REG_AUDIO_CLK_SEL1, 51 RSND_REG_AUDIO_CLK_SEL1,
59 RSND_REG_AUDIO_CLK_SEL2,
60 RSND_REG_AUDIO_CLK_SEL3, /* for Gen1 */
61 RSND_REG_AUDIO_CLK_SEL4, /* for Gen1 */
62 RSND_REG_AUDIO_CLK_SEL5, /* for Gen1 */
63 52
64 /* SSI */ 53 /* SSI */
65 RSND_REG_SSICR, 54 RSND_REG_SSICR,
@@ -68,9 +57,62 @@ enum rsnd_reg {
68 RSND_REG_SSIRDR, 57 RSND_REG_SSIRDR,
69 RSND_REG_SSIWSR, 58 RSND_REG_SSIWSR,
70 59
60 /* SHARE see below */
61 RSND_REG_SHARE01,
62 RSND_REG_SHARE02,
63 RSND_REG_SHARE03,
64 RSND_REG_SHARE04,
65 RSND_REG_SHARE05,
66 RSND_REG_SHARE06,
67 RSND_REG_SHARE07,
68 RSND_REG_SHARE08,
69 RSND_REG_SHARE09,
70 RSND_REG_SHARE10,
71 RSND_REG_SHARE11,
72 RSND_REG_SHARE12,
73 RSND_REG_SHARE13,
74 RSND_REG_SHARE14,
75 RSND_REG_SHARE15,
76 RSND_REG_SHARE16,
77 RSND_REG_SHARE17,
78 RSND_REG_SHARE18,
79 RSND_REG_SHARE19,
80
71 RSND_REG_MAX, 81 RSND_REG_MAX,
72}; 82};
73 83
84/* Gen1 only */
85#define RSND_REG_SRC_ROUTE_SEL RSND_REG_SHARE01
86#define RSND_REG_SRC_TMG_SEL0 RSND_REG_SHARE02
87#define RSND_REG_SRC_TMG_SEL1 RSND_REG_SHARE03
88#define RSND_REG_SRC_TMG_SEL2 RSND_REG_SHARE04
89#define RSND_REG_SRC_ROUTE_CTRL RSND_REG_SHARE05
90#define RSND_REG_SRC_MNFSR RSND_REG_SHARE06
91#define RSND_REG_AUDIO_CLK_SEL3 RSND_REG_SHARE07
92#define RSND_REG_AUDIO_CLK_SEL4 RSND_REG_SHARE08
93#define RSND_REG_AUDIO_CLK_SEL5 RSND_REG_SHARE09
94
95/* Gen2 only */
96#define RSND_REG_SRC_CTRL RSND_REG_SHARE01
97#define RSND_REG_SSI_CTRL RSND_REG_SHARE02
98#define RSND_REG_SSI_BUSIF_MODE RSND_REG_SHARE03
99#define RSND_REG_SSI_BUSIF_ADINR RSND_REG_SHARE04
100#define RSND_REG_INT_ENABLE RSND_REG_SHARE05
101#define RSND_REG_SRC_BSDSR RSND_REG_SHARE06
102#define RSND_REG_SRC_BSISR RSND_REG_SHARE07
103#define RSND_REG_DIV_EN RSND_REG_SHARE08
104#define RSND_REG_SRCIN_TIMSEL0 RSND_REG_SHARE09
105#define RSND_REG_SRCIN_TIMSEL1 RSND_REG_SHARE10
106#define RSND_REG_SRCIN_TIMSEL2 RSND_REG_SHARE11
107#define RSND_REG_SRCIN_TIMSEL3 RSND_REG_SHARE12
108#define RSND_REG_SRCIN_TIMSEL4 RSND_REG_SHARE13
109#define RSND_REG_SRCOUT_TIMSEL0 RSND_REG_SHARE14
110#define RSND_REG_SRCOUT_TIMSEL1 RSND_REG_SHARE15
111#define RSND_REG_SRCOUT_TIMSEL2 RSND_REG_SHARE16
112#define RSND_REG_SRCOUT_TIMSEL3 RSND_REG_SHARE17
113#define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18
114#define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19
115
74struct rsnd_priv; 116struct rsnd_priv;
75struct rsnd_mod; 117struct rsnd_mod;
76struct rsnd_dai; 118struct rsnd_dai;
@@ -96,24 +138,20 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
96 * R-Car DMA 138 * R-Car DMA
97 */ 139 */
98struct rsnd_dma { 140struct rsnd_dma {
99 struct rsnd_priv *priv;
100 struct sh_dmae_slave slave; 141 struct sh_dmae_slave slave;
101 struct work_struct work; 142 struct work_struct work;
102 struct dma_chan *chan; 143 struct dma_chan *chan;
103 enum dma_data_direction dir; 144 enum dma_data_direction dir;
104 int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len);
105 int (*complete)(struct rsnd_dma *dma);
106 145
107 int submit_loop; 146 int submit_loop;
147 int offset; /* it cares A/B plane */
108}; 148};
109 149
110void rsnd_dma_start(struct rsnd_dma *dma); 150void rsnd_dma_start(struct rsnd_dma *dma);
111void rsnd_dma_stop(struct rsnd_dma *dma); 151void rsnd_dma_stop(struct rsnd_dma *dma);
112int rsnd_dma_available(struct rsnd_dma *dma); 152int rsnd_dma_available(struct rsnd_dma *dma);
113int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, 153int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
114 int is_play, int id, 154 int is_play, int id);
115 int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len),
116 int (*complete)(struct rsnd_dma *dma));
117void rsnd_dma_quit(struct rsnd_priv *priv, 155void rsnd_dma_quit(struct rsnd_priv *priv,
118 struct rsnd_dma *dma); 156 struct rsnd_dma *dma);
119 157
@@ -121,9 +159,20 @@ void rsnd_dma_quit(struct rsnd_priv *priv,
121/* 159/*
122 * R-Car sound mod 160 * R-Car sound mod
123 */ 161 */
162enum rsnd_mod_type {
163 RSND_MOD_SRC = 0,
164 RSND_MOD_SSI,
165 RSND_MOD_MAX,
166};
124 167
125struct rsnd_mod_ops { 168struct rsnd_mod_ops {
126 char *name; 169 char *name;
170 int (*probe)(struct rsnd_mod *mod,
171 struct rsnd_dai *rdai,
172 struct rsnd_dai_stream *io);
173 int (*remove)(struct rsnd_mod *mod,
174 struct rsnd_dai *rdai,
175 struct rsnd_dai_stream *io);
127 int (*init)(struct rsnd_mod *mod, 176 int (*init)(struct rsnd_mod *mod,
128 struct rsnd_dai *rdai, 177 struct rsnd_dai *rdai,
129 struct rsnd_dai_stream *io); 178 struct rsnd_dai_stream *io);
@@ -138,28 +187,26 @@ struct rsnd_mod_ops {
138 struct rsnd_dai_stream *io); 187 struct rsnd_dai_stream *io);
139}; 188};
140 189
190struct rsnd_dai_stream;
141struct rsnd_mod { 191struct rsnd_mod {
142 int id; 192 int id;
193 enum rsnd_mod_type type;
143 struct rsnd_priv *priv; 194 struct rsnd_priv *priv;
144 struct rsnd_mod_ops *ops; 195 struct rsnd_mod_ops *ops;
145 struct list_head list; /* connect to rsnd_dai playback/capture */
146 struct rsnd_dma dma; 196 struct rsnd_dma dma;
197 struct rsnd_dai_stream *io;
147}; 198};
148 199
149#define rsnd_mod_to_priv(mod) ((mod)->priv) 200#define rsnd_mod_to_priv(mod) ((mod)->priv)
150#define rsnd_mod_to_dma(mod) (&(mod)->dma) 201#define rsnd_mod_to_dma(mod) (&(mod)->dma)
151#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) 202#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
203#define rsnd_mod_to_io(mod) ((mod)->io)
152#define rsnd_mod_id(mod) ((mod)->id) 204#define rsnd_mod_id(mod) ((mod)->id)
153#define for_each_rsnd_mod(pos, n, io) \
154 list_for_each_entry_safe(pos, n, &(io)->head, list)
155#define rsnd_mod_call(mod, func, rdai, io) \
156 (!(mod) ? -ENODEV : \
157 !((mod)->ops->func) ? 0 : \
158 (mod)->ops->func(mod, rdai, io))
159 205
160void rsnd_mod_init(struct rsnd_priv *priv, 206void rsnd_mod_init(struct rsnd_priv *priv,
161 struct rsnd_mod *mod, 207 struct rsnd_mod *mod,
162 struct rsnd_mod_ops *ops, 208 struct rsnd_mod_ops *ops,
209 enum rsnd_mod_type type,
163 int id); 210 int id);
164char *rsnd_mod_name(struct rsnd_mod *mod); 211char *rsnd_mod_name(struct rsnd_mod *mod);
165 212
@@ -168,13 +215,16 @@ char *rsnd_mod_name(struct rsnd_mod *mod);
168 */ 215 */
169#define RSND_DAI_NAME_SIZE 16 216#define RSND_DAI_NAME_SIZE 16
170struct rsnd_dai_stream { 217struct rsnd_dai_stream {
171 struct list_head head; /* head of rsnd_mod list */
172 struct snd_pcm_substream *substream; 218 struct snd_pcm_substream *substream;
219 struct rsnd_mod *mod[RSND_MOD_MAX];
220 struct rsnd_dai_path_info *info; /* rcar_snd.h */
173 int byte_pos; 221 int byte_pos;
174 int period_pos; 222 int period_pos;
175 int byte_per_period; 223 int byte_per_period;
176 int next_period_byte; 224 int next_period_byte;
177}; 225};
226#define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI])
227#define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC])
178 228
179struct rsnd_dai { 229struct rsnd_dai {
180 char name[RSND_DAI_NAME_SIZE]; 230 char name[RSND_DAI_NAME_SIZE];
@@ -189,16 +239,14 @@ struct rsnd_dai {
189 unsigned int data_alignment:1; 239 unsigned int data_alignment:1;
190}; 240};
191 241
192#define rsnd_dai_nr(priv) ((priv)->dai_nr) 242#define rsnd_rdai_nr(priv) ((priv)->rdai_nr)
193#define for_each_rsnd_dai(rdai, priv, i) \ 243#define for_each_rsnd_dai(rdai, priv, i) \
194 for (i = 0, (rdai) = rsnd_dai_get(priv, i); \ 244 for (i = 0; \
195 i < rsnd_dai_nr(priv); \ 245 (i < rsnd_rdai_nr(priv)) && \
196 i++, (rdai) = rsnd_dai_get(priv, i)) 246 ((rdai) = rsnd_dai_get(priv, i)); \
247 i++)
197 248
198struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id); 249struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id);
199int rsnd_dai_disconnect(struct rsnd_mod *mod);
200int rsnd_dai_connect(struct rsnd_dai *rdai, struct rsnd_mod *mod,
201 struct rsnd_dai_stream *io);
202int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io); 250int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io);
203int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai); 251int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai);
204#define rsnd_dai_get_platform_info(rdai) ((rdai)->info) 252#define rsnd_dai_get_platform_info(rdai) ((rdai)->info)
@@ -206,21 +254,13 @@ int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai);
206 254
207void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); 255void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt);
208int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); 256int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional);
257#define rsnd_dai_is_clk_master(rdai) ((rdai)->clk_master)
209 258
210/* 259/*
211 * R-Car Gen1/Gen2 260 * R-Car Gen1/Gen2
212 */ 261 */
213int rsnd_gen_probe(struct platform_device *pdev, 262int rsnd_gen_probe(struct platform_device *pdev,
214 struct rcar_snd_info *info,
215 struct rsnd_priv *priv); 263 struct rsnd_priv *priv);
216void rsnd_gen_remove(struct platform_device *pdev,
217 struct rsnd_priv *priv);
218int rsnd_gen_path_init(struct rsnd_priv *priv,
219 struct rsnd_dai *rdai,
220 struct rsnd_dai_stream *io);
221int rsnd_gen_path_exit(struct rsnd_priv *priv,
222 struct rsnd_dai *rdai,
223 struct rsnd_dai_stream *io);
224void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, 264void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
225 struct rsnd_mod *mod, 265 struct rsnd_mod *mod,
226 enum rsnd_reg reg); 266 enum rsnd_reg reg);
@@ -233,14 +273,19 @@ void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
233int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); 273int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod);
234int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); 274int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate);
235int rsnd_adg_probe(struct platform_device *pdev, 275int rsnd_adg_probe(struct platform_device *pdev,
236 struct rcar_snd_info *info,
237 struct rsnd_priv *priv);
238void rsnd_adg_remove(struct platform_device *pdev,
239 struct rsnd_priv *priv); 276 struct rsnd_priv *priv);
240int rsnd_adg_set_convert_clk(struct rsnd_priv *priv, 277int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
241 struct rsnd_mod *mod, 278 struct rsnd_mod *mod,
242 unsigned int src_rate, 279 unsigned int src_rate,
243 unsigned int dst_rate); 280 unsigned int dst_rate);
281int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
282 struct rsnd_dai *rdai,
283 struct rsnd_dai_stream *io,
284 unsigned int src_rate,
285 unsigned int dst_rate);
286int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
287 struct rsnd_dai *rdai,
288 struct rsnd_dai_stream *io);
244 289
245/* 290/*
246 * R-Car sound priv 291 * R-Car sound priv
@@ -257,10 +302,10 @@ struct rsnd_priv {
257 void *gen; 302 void *gen;
258 303
259 /* 304 /*
260 * below value will be filled on rsnd_scu_probe() 305 * below value will be filled on rsnd_src_probe()
261 */ 306 */
262 void *scu; 307 void *src;
263 int scu_nr; 308 int src_nr;
264 309
265 /* 310 /*
266 * below value will be filled on rsnd_adg_probe() 311 * below value will be filled on rsnd_adg_probe()
@@ -270,46 +315,62 @@ struct rsnd_priv {
270 /* 315 /*
271 * below value will be filled on rsnd_ssi_probe() 316 * below value will be filled on rsnd_ssi_probe()
272 */ 317 */
273 void *ssiu; 318 void *ssi;
319 int ssi_nr;
274 320
275 /* 321 /*
276 * below value will be filled on rsnd_dai_probe() 322 * below value will be filled on rsnd_dai_probe()
277 */ 323 */
278 struct snd_soc_dai_driver *daidrv; 324 struct snd_soc_dai_driver *daidrv;
279 struct rsnd_dai *rdai; 325 struct rsnd_dai *rdai;
280 int dai_nr; 326 int rdai_nr;
281}; 327};
282 328
283#define rsnd_priv_to_dev(priv) ((priv)->dev) 329#define rsnd_priv_to_dev(priv) ((priv)->dev)
330#define rsnd_priv_to_info(priv) ((priv)->info)
284#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) 331#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags)
285#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) 332#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags)
286 333
334#define rsnd_info_is_playback(priv, type) \
335({ \
336 struct rcar_snd_info *info = rsnd_priv_to_info(priv); \
337 int i, is_play = 0; \
338 for (i = 0; i < info->dai_info_nr; i++) { \
339 if (info->dai_info[i].playback.type == (type)->info) { \
340 is_play = 1; \
341 break; \
342 } \
343 } \
344 is_play; \
345})
346
287/* 347/*
288 * R-Car SCU 348 * R-Car SRC
289 */ 349 */
290int rsnd_scu_probe(struct platform_device *pdev, 350int rsnd_src_probe(struct platform_device *pdev,
291 struct rcar_snd_info *info,
292 struct rsnd_priv *priv); 351 struct rsnd_priv *priv);
293void rsnd_scu_remove(struct platform_device *pdev, 352struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id);
294 struct rsnd_priv *priv); 353unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
295struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id); 354 struct rsnd_dai_stream *io,
296bool rsnd_scu_hpbif_is_enable(struct rsnd_mod *mod);
297unsigned int rsnd_scu_get_ssi_rate(struct rsnd_priv *priv,
298 struct rsnd_mod *ssi_mod,
299 struct snd_pcm_runtime *runtime); 355 struct snd_pcm_runtime *runtime);
356int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
357 struct rsnd_dai *rdai,
358 struct rsnd_dai_stream *io);
359int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod,
360 struct rsnd_dai *rdai,
361 struct rsnd_dai_stream *io);
300 362
301#define rsnd_scu_nr(priv) ((priv)->scu_nr) 363#define rsnd_src_nr(priv) ((priv)->src_nr)
302 364
303/* 365/*
304 * R-Car SSI 366 * R-Car SSI
305 */ 367 */
306int rsnd_ssi_probe(struct platform_device *pdev, 368int rsnd_ssi_probe(struct platform_device *pdev,
307 struct rcar_snd_info *info,
308 struct rsnd_priv *priv);
309void rsnd_ssi_remove(struct platform_device *pdev,
310 struct rsnd_priv *priv); 369 struct rsnd_priv *priv);
311struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 370struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
312struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, 371struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv,
313 int dai_id, int is_play); 372 int dai_id, int is_play);
373int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
374int rsnd_ssi_is_play(struct rsnd_mod *mod);
314 375
315#endif 376#endif
diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c
deleted file mode 100644
index 9bb08bb1d455..000000000000
--- a/sound/soc/sh/rcar/scu.c
+++ /dev/null
@@ -1,384 +0,0 @@
1/*
2 * Renesas R-Car SCU support
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include "rsnd.h"
12
13struct rsnd_scu {
14 struct rsnd_scu_platform_info *info; /* rcar_snd.h */
15 struct rsnd_mod mod;
16 struct clk *clk;
17};
18
19#define rsnd_scu_mode_flags(p) ((p)->info->flags)
20#define rsnd_scu_convert_rate(p) ((p)->info->convert_rate)
21
22#define RSND_SCU_NAME_SIZE 16
23
24/*
25 * ADINR
26 */
27#define OTBL_24 (0 << 16)
28#define OTBL_22 (2 << 16)
29#define OTBL_20 (4 << 16)
30#define OTBL_18 (6 << 16)
31#define OTBL_16 (8 << 16)
32
33/*
34 * image of SRC (Sampling Rate Converter)
35 *
36 * 96kHz <-> +-----+ 48kHz +-----+ 48kHz +-------+
37 * 48kHz <-> | SRC | <------> | SSI | <-----> | codec |
38 * 44.1kHz <-> +-----+ +-----+ +-------+
39 * ...
40 *
41 */
42
43#define rsnd_mod_to_scu(_mod) \
44 container_of((_mod), struct rsnd_scu, mod)
45
46#define for_each_rsnd_scu(pos, priv, i) \
47 for ((i) = 0; \
48 ((i) < rsnd_scu_nr(priv)) && \
49 ((pos) = (struct rsnd_scu *)(priv)->scu + i); \
50 i++)
51
52/* Gen1 only */
53static int rsnd_src_set_route_if_gen1(struct rsnd_priv *priv,
54 struct rsnd_mod *mod,
55 struct rsnd_dai *rdai,
56 struct rsnd_dai_stream *io)
57{
58 struct scu_route_config {
59 u32 mask;
60 int shift;
61 } routes[] = {
62 { 0xF, 0, }, /* 0 */
63 { 0xF, 4, }, /* 1 */
64 { 0xF, 8, }, /* 2 */
65 { 0x7, 12, }, /* 3 */
66 { 0x7, 16, }, /* 4 */
67 { 0x7, 20, }, /* 5 */
68 { 0x7, 24, }, /* 6 */
69 { 0x3, 28, }, /* 7 */
70 { 0x3, 30, }, /* 8 */
71 };
72 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
73 u32 mask;
74 u32 val;
75 int shift;
76 int id;
77
78 /*
79 * Gen1 only
80 */
81 if (!rsnd_is_gen1(priv))
82 return 0;
83
84 id = rsnd_mod_id(mod);
85 if (id < 0 || id >= ARRAY_SIZE(routes))
86 return -EIO;
87
88 /*
89 * SRC_ROUTE_SELECT
90 */
91 val = rsnd_dai_is_play(rdai, io) ? 0x1 : 0x2;
92 val = val << routes[id].shift;
93 mask = routes[id].mask << routes[id].shift;
94
95 rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val);
96
97 /*
98 * SRC_TIMING_SELECT
99 */
100 shift = (id % 4) * 8;
101 mask = 0x1F << shift;
102
103 /*
104 * ADG is used as source clock if SRC was used,
105 * then, SSI WS is used as destination clock.
106 * SSI WS is used as source clock if SRC is not used
107 * (when playback, source/destination become reverse when capture)
108 */
109 if (rsnd_scu_convert_rate(scu)) /* use ADG */
110 val = 0;
111 else if (8 == id) /* use SSI WS, but SRU8 is special */
112 val = id << shift;
113 else /* use SSI WS */
114 val = (id + 1) << shift;
115
116 switch (id / 4) {
117 case 0:
118 rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val);
119 break;
120 case 1:
121 rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val);
122 break;
123 case 2:
124 rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val);
125 break;
126 }
127
128 return 0;
129}
130
131unsigned int rsnd_scu_get_ssi_rate(struct rsnd_priv *priv,
132 struct rsnd_mod *ssi_mod,
133 struct snd_pcm_runtime *runtime)
134{
135 struct rsnd_scu *scu;
136 unsigned int rate;
137
138 /* this function is assuming SSI id = SCU id here */
139 scu = rsnd_mod_to_scu(rsnd_scu_mod_get(priv, rsnd_mod_id(ssi_mod)));
140
141 /*
142 * return convert rate if SRC is used,
143 * otherwise, return runtime->rate as usual
144 */
145 rate = rsnd_scu_convert_rate(scu);
146 if (!rate)
147 rate = runtime->rate;
148
149 return rate;
150}
151
152static int rsnd_scu_convert_rate_ctrl(struct rsnd_priv *priv,
153 struct rsnd_mod *mod,
154 struct rsnd_dai *rdai,
155 struct rsnd_dai_stream *io)
156{
157 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
158 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
159 u32 convert_rate = rsnd_scu_convert_rate(scu);
160 u32 adinr = runtime->channels;
161
162 /* set/clear soft reset */
163 rsnd_mod_write(mod, SRC_SWRSR, 0);
164 rsnd_mod_write(mod, SRC_SWRSR, 1);
165
166 /* Initialize the operation of the SRC internal circuits */
167 rsnd_mod_write(mod, SRC_SRCIR, 1);
168
169 /* Set channel number and output bit length */
170 switch (runtime->sample_bits) {
171 case 16:
172 adinr |= OTBL_16;
173 break;
174 case 32:
175 adinr |= OTBL_24;
176 break;
177 default:
178 return -EIO;
179 }
180 rsnd_mod_write(mod, SRC_ADINR, adinr);
181
182 if (convert_rate) {
183 u32 fsrate = 0x0400000 / convert_rate * runtime->rate;
184 int ret;
185
186 /* Enable the initial value of IFS */
187 rsnd_mod_write(mod, SRC_IFSCR, 1);
188
189 /* Set initial value of IFS */
190 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
191
192 /* Select SRC mode (fixed value) */
193 rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
194
195 /* Set the restriction value of the FS ratio (98%) */
196 rsnd_mod_write(mod, SRC_MNFSR, fsrate / 100 * 98);
197
198 if (rsnd_is_gen1(priv)) {
199 /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
200 }
201
202 /* set convert clock */
203 ret = rsnd_adg_set_convert_clk(priv, mod,
204 runtime->rate,
205 convert_rate);
206 if (ret < 0)
207 return ret;
208 }
209
210 /* Cancel the initialization and operate the SRC function */
211 rsnd_mod_write(mod, SRC_SRCIR, 0);
212
213 /* use DMA transfer */
214 rsnd_mod_write(mod, BUSIF_MODE, 1);
215
216 return 0;
217}
218
219static int rsnd_scu_transfer_start(struct rsnd_priv *priv,
220 struct rsnd_mod *mod,
221 struct rsnd_dai *rdai,
222 struct rsnd_dai_stream *io)
223{
224 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
225 int id = rsnd_mod_id(mod);
226 u32 val;
227
228 if (rsnd_is_gen1(priv)) {
229 val = (1 << id);
230 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, val, val);
231 }
232
233 if (rsnd_scu_convert_rate(scu))
234 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
235
236 return 0;
237}
238
239static int rsnd_scu_transfer_stop(struct rsnd_priv *priv,
240 struct rsnd_mod *mod,
241 struct rsnd_dai *rdai,
242 struct rsnd_dai_stream *io)
243{
244 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
245 int id = rsnd_mod_id(mod);
246 u32 mask;
247
248 if (rsnd_is_gen1(priv)) {
249 mask = (1 << id);
250 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, mask, 0);
251 }
252
253 if (rsnd_scu_convert_rate(scu))
254 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0);
255
256 return 0;
257}
258
259bool rsnd_scu_hpbif_is_enable(struct rsnd_mod *mod)
260{
261 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
262 u32 flags = rsnd_scu_mode_flags(scu);
263
264 return !!(flags & RSND_SCU_USE_HPBIF);
265}
266
267static int rsnd_scu_start(struct rsnd_mod *mod,
268 struct rsnd_dai *rdai,
269 struct rsnd_dai_stream *io)
270{
271 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
272 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
273 struct device *dev = rsnd_priv_to_dev(priv);
274 int ret;
275
276 /*
277 * SCU will be used if it has RSND_SCU_USE_HPBIF flags
278 */
279 if (!rsnd_scu_hpbif_is_enable(mod)) {
280 /* it use PIO transter */
281 dev_dbg(dev, "%s%d is not used\n",
282 rsnd_mod_name(mod), rsnd_mod_id(mod));
283
284 return 0;
285 }
286
287 clk_enable(scu->clk);
288
289 /* it use DMA transter */
290
291 ret = rsnd_src_set_route_if_gen1(priv, mod, rdai, io);
292 if (ret < 0)
293 return ret;
294
295 ret = rsnd_scu_convert_rate_ctrl(priv, mod, rdai, io);
296 if (ret < 0)
297 return ret;
298
299 ret = rsnd_scu_transfer_start(priv, mod, rdai, io);
300 if (ret < 0)
301 return ret;
302
303 dev_dbg(dev, "%s%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
304
305 return 0;
306}
307
308static int rsnd_scu_stop(struct rsnd_mod *mod,
309 struct rsnd_dai *rdai,
310 struct rsnd_dai_stream *io)
311{
312 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
313 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
314
315 if (!rsnd_scu_hpbif_is_enable(mod))
316 return 0;
317
318 rsnd_scu_transfer_stop(priv, mod, rdai, io);
319
320 clk_disable(scu->clk);
321
322 return 0;
323}
324
325static struct rsnd_mod_ops rsnd_scu_ops = {
326 .name = "scu",
327 .start = rsnd_scu_start,
328 .stop = rsnd_scu_stop,
329};
330
331struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id)
332{
333 if (WARN_ON(id < 0 || id >= rsnd_scu_nr(priv)))
334 id = 0;
335
336 return &((struct rsnd_scu *)(priv->scu) + id)->mod;
337}
338
339int rsnd_scu_probe(struct platform_device *pdev,
340 struct rcar_snd_info *info,
341 struct rsnd_priv *priv)
342{
343 struct device *dev = rsnd_priv_to_dev(priv);
344 struct rsnd_scu *scu;
345 struct clk *clk;
346 char name[RSND_SCU_NAME_SIZE];
347 int i, nr;
348
349 /*
350 * init SCU
351 */
352 nr = info->scu_info_nr;
353 scu = devm_kzalloc(dev, sizeof(*scu) * nr, GFP_KERNEL);
354 if (!scu) {
355 dev_err(dev, "SCU allocate failed\n");
356 return -ENOMEM;
357 }
358
359 priv->scu_nr = nr;
360 priv->scu = scu;
361
362 for_each_rsnd_scu(scu, priv, i) {
363 snprintf(name, RSND_SCU_NAME_SIZE, "scu.%d", i);
364
365 clk = devm_clk_get(dev, name);
366 if (IS_ERR(clk))
367 return PTR_ERR(clk);
368
369 rsnd_mod_init(priv, &scu->mod,
370 &rsnd_scu_ops, i);
371 scu->info = &info->scu_info[i];
372 scu->clk = clk;
373
374 dev_dbg(dev, "SCU%d probed\n", i);
375 }
376 dev_dbg(dev, "scu probed\n");
377
378 return 0;
379}
380
381void rsnd_scu_remove(struct platform_device *pdev,
382 struct rsnd_priv *priv)
383{
384}
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
new file mode 100644
index 000000000000..ea6a214985d0
--- /dev/null
+++ b/sound/soc/sh/rcar/src.c
@@ -0,0 +1,687 @@
1/*
2 * Renesas R-Car SRC support
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include "rsnd.h"
12
13struct rsnd_src {
14 struct rsnd_src_platform_info *info; /* rcar_snd.h */
15 struct rsnd_mod mod;
16 struct clk *clk;
17};
18
19#define RSND_SRC_NAME_SIZE 16
20
21/*
22 * ADINR
23 */
24#define OTBL_24 (0 << 16)
25#define OTBL_22 (2 << 16)
26#define OTBL_20 (4 << 16)
27#define OTBL_18 (6 << 16)
28#define OTBL_16 (8 << 16)
29
30#define rsnd_src_mode_flags(p) ((p)->info->flags)
31#define rsnd_src_convert_rate(p) ((p)->info->convert_rate)
32#define rsnd_mod_to_src(_mod) \
33 container_of((_mod), struct rsnd_src, mod)
34#define rsnd_src_hpbif_is_enable(src) \
35 (rsnd_src_mode_flags(src) & RSND_SCU_USE_HPBIF)
36#define rsnd_src_dma_available(src) \
37 rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod))
38
39#define for_each_rsnd_src(pos, priv, i) \
40 for ((i) = 0; \
41 ((i) < rsnd_src_nr(priv)) && \
42 ((pos) = (struct rsnd_src *)(priv)->src + i); \
43 i++)
44
45
46/*
47 * image of SRC (Sampling Rate Converter)
48 *
49 * 96kHz <-> +-----+ 48kHz +-----+ 48kHz +-------+
50 * 48kHz <-> | SRC | <------> | SSI | <-----> | codec |
51 * 44.1kHz <-> +-----+ +-----+ +-------+
52 * ...
53 *
54 */
55
56/*
57 * src.c is caring...
58 *
59 * Gen1
60 *
61 * [mem] -> [SRU] -> [SSI]
62 * |--------|
63 *
64 * Gen2
65 *
66 * [mem] -> [SRC] -> [SSIU] -> [SSI]
67 * |-----------------|
68 */
69
70/*
71 * How to use SRC bypass mode for debugging
72 *
73 * SRC has bypass mode, and it is useful for debugging.
74 * In Gen2 case,
75 * SRCm_MODE controls whether SRC is used or not
76 * SSI_MODE0 controls whether SSIU which receives SRC data
77 * is used or not.
78 * Both SRCm_MODE/SSI_MODE0 settings are needed if you use SRC,
79 * but SRC bypass mode needs SSI_MODE0 only.
80 *
81 * This driver request
82 * struct rsnd_src_platform_info {
83 * u32 flags;
84 * u32 convert_rate;
85 * }
86 *
87 * rsnd_src_hpbif_is_enable() will be true
88 * if flags had RSND_SRC_USE_HPBIF,
89 * and it controls whether SSIU is used or not.
90 *
91 * rsnd_src_convert_rate() indicates
92 * above convert_rate, and it controls
93 * whether SRC is used or not.
94 *
95 * ex) doesn't use SRC
96 * struct rsnd_src_platform_info info = {
97 * .flags = 0,
98 * .convert_rate = 0,
99 * };
100 *
101 * ex) uses SRC
102 * struct rsnd_src_platform_info info = {
103 * .flags = RSND_SRC_USE_HPBIF,
104 * .convert_rate = 48000,
105 * };
106 *
107 * ex) uses SRC bypass mode
108 * struct rsnd_src_platform_info info = {
109 * .flags = RSND_SRC_USE_HPBIF,
110 * .convert_rate = 0,
111 * };
112 *
113 */
114
115/*
116 * Gen1/Gen2 common functions
117 */
118int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
119 struct rsnd_dai *rdai,
120 struct rsnd_dai_stream *io)
121{
122 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
123 struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
124 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
125 int ssi_id = rsnd_mod_id(ssi_mod);
126 int has_src = 0;
127
128 /*
129 * SSI_MODE0
130 */
131 if (info->dai_info) {
132 has_src = !!src_mod;
133 } else {
134 struct rsnd_src *src = rsnd_mod_to_src(src_mod);
135 has_src = rsnd_src_hpbif_is_enable(src);
136 }
137
138 rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
139 has_src ? 0 : (1 << ssi_id));
140
141 /*
142 * SSI_MODE1
143 */
144 if (rsnd_ssi_is_pin_sharing(ssi_mod)) {
145 int shift = -1;
146 switch (ssi_id) {
147 case 1:
148 shift = 0;
149 break;
150 case 2:
151 shift = 2;
152 break;
153 case 4:
154 shift = 16;
155 break;
156 }
157
158 if (shift >= 0)
159 rsnd_mod_bset(ssi_mod, SSI_MODE1,
160 0x3 << shift,
161 rsnd_dai_is_clk_master(rdai) ?
162 0x2 << shift : 0x1 << shift);
163 }
164
165 return 0;
166}
167
168int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod,
169 struct rsnd_dai *rdai,
170 struct rsnd_dai_stream *io)
171{
172 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
173
174 /* enable PIO interrupt if Gen2 */
175 if (rsnd_is_gen2(priv))
176 rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0f000000);
177
178 return 0;
179}
180
181unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
182 struct rsnd_dai_stream *io,
183 struct snd_pcm_runtime *runtime)
184{
185 struct rsnd_src *src;
186 unsigned int rate;
187
188 src = rsnd_mod_to_src(rsnd_io_to_mod_src(io));
189
190 /*
191 * return convert rate if SRC is used,
192 * otherwise, return runtime->rate as usual
193 */
194 rate = rsnd_src_convert_rate(src);
195 if (!rate)
196 rate = runtime->rate;
197
198 return rate;
199}
200
201static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
202 struct rsnd_dai *rdai,
203 struct rsnd_dai_stream *io)
204{
205 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
206 struct rsnd_src *src = rsnd_mod_to_src(mod);
207 u32 convert_rate = rsnd_src_convert_rate(src);
208 u32 adinr = runtime->channels;
209 u32 fsrate = 0;
210
211 if (convert_rate)
212 fsrate = 0x0400000 / convert_rate * runtime->rate;
213
214 /* set/clear soft reset */
215 rsnd_mod_write(mod, SRC_SWRSR, 0);
216 rsnd_mod_write(mod, SRC_SWRSR, 1);
217
218 /*
219 * Initialize the operation of the SRC internal circuits
220 * see rsnd_src_start()
221 */
222 rsnd_mod_write(mod, SRC_SRCIR, 1);
223
224 /* Set channel number and output bit length */
225 switch (runtime->sample_bits) {
226 case 16:
227 adinr |= OTBL_16;
228 break;
229 case 32:
230 adinr |= OTBL_24;
231 break;
232 default:
233 return -EIO;
234 }
235 rsnd_mod_write(mod, SRC_ADINR, adinr);
236
237 /* Enable the initial value of IFS */
238 if (fsrate) {
239 rsnd_mod_write(mod, SRC_IFSCR, 1);
240
241 /* Set initial value of IFS */
242 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
243 }
244
245 /* use DMA transfer */
246 rsnd_mod_write(mod, SRC_BUSIF_MODE, 1);
247
248 return 0;
249}
250
251static int rsnd_src_init(struct rsnd_mod *mod,
252 struct rsnd_dai *rdai,
253 struct rsnd_dai_stream *io)
254{
255 struct rsnd_src *src = rsnd_mod_to_src(mod);
256
257 clk_enable(src->clk);
258
259 return 0;
260}
261
262static int rsnd_src_quit(struct rsnd_mod *mod,
263 struct rsnd_dai *rdai,
264 struct rsnd_dai_stream *io)
265{
266 struct rsnd_src *src = rsnd_mod_to_src(mod);
267
268 clk_disable(src->clk);
269
270 return 0;
271}
272
273static int rsnd_src_start(struct rsnd_mod *mod,
274 struct rsnd_dai *rdai,
275 struct rsnd_dai_stream *io)
276{
277 struct rsnd_src *src = rsnd_mod_to_src(mod);
278
279 /*
280 * Cancel the initialization and operate the SRC function
281 * see rsnd_src_set_convert_rate()
282 */
283 rsnd_mod_write(mod, SRC_SRCIR, 0);
284
285 if (rsnd_src_convert_rate(src))
286 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
287
288 return 0;
289}
290
291
292static int rsnd_src_stop(struct rsnd_mod *mod,
293 struct rsnd_dai *rdai,
294 struct rsnd_dai_stream *io)
295{
296 struct rsnd_src *src = rsnd_mod_to_src(mod);
297
298 if (rsnd_src_convert_rate(src))
299 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0);
300
301 return 0;
302}
303
304static struct rsnd_mod_ops rsnd_src_non_ops = {
305 .name = "src (non)",
306};
307
308/*
309 * Gen1 functions
310 */
311static int rsnd_src_set_route_gen1(struct rsnd_mod *mod,
312 struct rsnd_dai *rdai,
313 struct rsnd_dai_stream *io)
314{
315 struct src_route_config {
316 u32 mask;
317 int shift;
318 } routes[] = {
319 { 0xF, 0, }, /* 0 */
320 { 0xF, 4, }, /* 1 */
321 { 0xF, 8, }, /* 2 */
322 { 0x7, 12, }, /* 3 */
323 { 0x7, 16, }, /* 4 */
324 { 0x7, 20, }, /* 5 */
325 { 0x7, 24, }, /* 6 */
326 { 0x3, 28, }, /* 7 */
327 { 0x3, 30, }, /* 8 */
328 };
329 u32 mask;
330 u32 val;
331 int id;
332
333 id = rsnd_mod_id(mod);
334 if (id < 0 || id >= ARRAY_SIZE(routes))
335 return -EIO;
336
337 /*
338 * SRC_ROUTE_SELECT
339 */
340 val = rsnd_dai_is_play(rdai, io) ? 0x1 : 0x2;
341 val = val << routes[id].shift;
342 mask = routes[id].mask << routes[id].shift;
343
344 rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val);
345
346 return 0;
347}
348
349static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod,
350 struct rsnd_dai *rdai,
351 struct rsnd_dai_stream *io)
352{
353 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
354 struct rsnd_src *src = rsnd_mod_to_src(mod);
355 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
356 u32 convert_rate = rsnd_src_convert_rate(src);
357 u32 mask;
358 u32 val;
359 int shift;
360 int id = rsnd_mod_id(mod);
361 int ret;
362
363 /*
364 * SRC_TIMING_SELECT
365 */
366 shift = (id % 4) * 8;
367 mask = 0x1F << shift;
368
369 /*
370 * ADG is used as source clock if SRC was used,
371 * then, SSI WS is used as destination clock.
372 * SSI WS is used as source clock if SRC is not used
373 * (when playback, source/destination become reverse when capture)
374 */
375 ret = 0;
376 if (convert_rate) {
377 /* use ADG */
378 val = 0;
379 ret = rsnd_adg_set_convert_clk_gen1(priv, mod,
380 runtime->rate,
381 convert_rate);
382 } else if (8 == id) {
383 /* use SSI WS, but SRU8 is special */
384 val = id << shift;
385 } else {
386 /* use SSI WS */
387 val = (id + 1) << shift;
388 }
389
390 if (ret < 0)
391 return ret;
392
393 switch (id / 4) {
394 case 0:
395 rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val);
396 break;
397 case 1:
398 rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val);
399 break;
400 case 2:
401 rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val);
402 break;
403 }
404
405 return 0;
406}
407
408static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
409 struct rsnd_dai *rdai,
410 struct rsnd_dai_stream *io)
411{
412 int ret;
413
414 ret = rsnd_src_set_convert_rate(mod, rdai, io);
415 if (ret < 0)
416 return ret;
417
418 /* Select SRC mode (fixed value) */
419 rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
420
421 /* Set the restriction value of the FS ratio (98%) */
422 rsnd_mod_write(mod, SRC_MNFSR,
423 rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98);
424
425 /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
426
427 return 0;
428}
429
430static int rsnd_src_init_gen1(struct rsnd_mod *mod,
431 struct rsnd_dai *rdai,
432 struct rsnd_dai_stream *io)
433{
434 int ret;
435
436 ret = rsnd_src_init(mod, rdai, io);
437 if (ret < 0)
438 return ret;
439
440 ret = rsnd_src_set_route_gen1(mod, rdai, io);
441 if (ret < 0)
442 return ret;
443
444 ret = rsnd_src_set_convert_rate_gen1(mod, rdai, io);
445 if (ret < 0)
446 return ret;
447
448 ret = rsnd_src_set_convert_timing_gen1(mod, rdai, io);
449 if (ret < 0)
450 return ret;
451
452 return 0;
453}
454
455static int rsnd_src_start_gen1(struct rsnd_mod *mod,
456 struct rsnd_dai *rdai,
457 struct rsnd_dai_stream *io)
458{
459 int id = rsnd_mod_id(mod);
460
461 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id));
462
463 return rsnd_src_start(mod, rdai, io);
464}
465
466static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
467 struct rsnd_dai *rdai,
468 struct rsnd_dai_stream *io)
469{
470 int id = rsnd_mod_id(mod);
471
472 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0);
473
474 return rsnd_src_stop(mod, rdai, io);
475}
476
477static struct rsnd_mod_ops rsnd_src_gen1_ops = {
478 .name = "sru (gen1)",
479 .init = rsnd_src_init_gen1,
480 .quit = rsnd_src_quit,
481 .start = rsnd_src_start_gen1,
482 .stop = rsnd_src_stop_gen1,
483};
484
485/*
486 * Gen2 functions
487 */
488static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
489 struct rsnd_dai *rdai,
490 struct rsnd_dai_stream *io)
491{
492 int ret;
493
494 ret = rsnd_src_set_convert_rate(mod, rdai, io);
495 if (ret < 0)
496 return ret;
497
498 rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_mod_read(mod, SRC_ADINR));
499 rsnd_mod_write(mod, SSI_BUSIF_MODE, rsnd_mod_read(mod, SRC_BUSIF_MODE));
500
501 rsnd_mod_write(mod, SRC_SRCCR, 0x00011110);
502
503 rsnd_mod_write(mod, SRC_BSDSR, 0x01800000);
504 rsnd_mod_write(mod, SRC_BSISR, 0x00100060);
505
506 return 0;
507}
508
509static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod,
510 struct rsnd_dai *rdai,
511 struct rsnd_dai_stream *io)
512{
513 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
514 struct rsnd_src *src = rsnd_mod_to_src(mod);
515 u32 convert_rate = rsnd_src_convert_rate(src);
516 int ret;
517
518 if (convert_rate)
519 ret = rsnd_adg_set_convert_clk_gen2(mod, rdai, io,
520 runtime->rate,
521 convert_rate);
522 else
523 ret = rsnd_adg_set_convert_timing_gen2(mod, rdai, io);
524
525 return ret;
526}
527
528static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
529 struct rsnd_dai *rdai,
530 struct rsnd_dai_stream *io)
531{
532 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
533 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
534 struct rsnd_src *src = rsnd_mod_to_src(mod);
535 struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, rsnd_mod_id(mod));
536 struct device *dev = rsnd_priv_to_dev(priv);
537 int ret;
538 int is_play;
539
540 if (info->dai_info)
541 is_play = rsnd_info_is_playback(priv, src);
542 else
543 is_play = rsnd_ssi_is_play(ssi);
544
545 ret = rsnd_dma_init(priv,
546 rsnd_mod_to_dma(mod),
547 is_play,
548 src->info->dma_id);
549 if (ret < 0)
550 dev_err(dev, "SRC DMA failed\n");
551
552 return ret;
553}
554
555static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
556 struct rsnd_dai *rdai,
557 struct rsnd_dai_stream *io)
558{
559 rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod));
560
561 return 0;
562}
563
564static int rsnd_src_init_gen2(struct rsnd_mod *mod,
565 struct rsnd_dai *rdai,
566 struct rsnd_dai_stream *io)
567{
568 int ret;
569
570 ret = rsnd_src_init(mod, rdai, io);
571 if (ret < 0)
572 return ret;
573
574 ret = rsnd_src_set_convert_rate_gen2(mod, rdai, io);
575 if (ret < 0)
576 return ret;
577
578 ret = rsnd_src_set_convert_timing_gen2(mod, rdai, io);
579 if (ret < 0)
580 return ret;
581
582 return 0;
583}
584
585static int rsnd_src_start_gen2(struct rsnd_mod *mod,
586 struct rsnd_dai *rdai,
587 struct rsnd_dai_stream *io)
588{
589 struct rsnd_src *src = rsnd_mod_to_src(mod);
590
591 rsnd_dma_start(rsnd_mod_to_dma(&src->mod));
592
593 rsnd_mod_write(mod, SSI_CTRL, 0x1);
594 rsnd_mod_write(mod, SRC_CTRL, 0x11);
595
596 return rsnd_src_start(mod, rdai, io);
597}
598
599static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
600 struct rsnd_dai *rdai,
601 struct rsnd_dai_stream *io)
602{
603 struct rsnd_src *src = rsnd_mod_to_src(mod);
604
605 rsnd_mod_write(mod, SSI_CTRL, 0);
606 rsnd_mod_write(mod, SRC_CTRL, 0);
607
608 rsnd_dma_stop(rsnd_mod_to_dma(&src->mod));
609
610 return rsnd_src_stop(mod, rdai, io);
611}
612
613static struct rsnd_mod_ops rsnd_src_gen2_ops = {
614 .name = "src (gen2)",
615 .probe = rsnd_src_probe_gen2,
616 .remove = rsnd_src_remove_gen2,
617 .init = rsnd_src_init_gen2,
618 .quit = rsnd_src_quit,
619 .start = rsnd_src_start_gen2,
620 .stop = rsnd_src_stop_gen2,
621};
622
623struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
624{
625 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
626 id = 0;
627
628 return &((struct rsnd_src *)(priv->src) + id)->mod;
629}
630
631int rsnd_src_probe(struct platform_device *pdev,
632 struct rsnd_priv *priv)
633{
634 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
635 struct device *dev = rsnd_priv_to_dev(priv);
636 struct rsnd_src *src;
637 struct rsnd_mod_ops *ops;
638 struct clk *clk;
639 char name[RSND_SRC_NAME_SIZE];
640 int i, nr;
641
642 /*
643 * init SRC
644 */
645 nr = info->src_info_nr;
646 if (!nr)
647 return 0;
648
649 src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL);
650 if (!src) {
651 dev_err(dev, "SRC allocate failed\n");
652 return -ENOMEM;
653 }
654
655 priv->src_nr = nr;
656 priv->src = src;
657
658 for_each_rsnd_src(src, priv, i) {
659 snprintf(name, RSND_SRC_NAME_SIZE, "src.%d", i);
660
661 clk = devm_clk_get(dev, name);
662 if (IS_ERR(clk)) {
663 snprintf(name, RSND_SRC_NAME_SIZE, "scu.%d", i);
664 clk = devm_clk_get(dev, name);
665 }
666
667 if (IS_ERR(clk))
668 return PTR_ERR(clk);
669
670 src->info = &info->src_info[i];
671 src->clk = clk;
672
673 ops = &rsnd_src_non_ops;
674 if (rsnd_src_hpbif_is_enable(src)) {
675 if (rsnd_is_gen1(priv))
676 ops = &rsnd_src_gen1_ops;
677 if (rsnd_is_gen2(priv))
678 ops = &rsnd_src_gen2_ops;
679 }
680
681 rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i);
682
683 dev_dbg(dev, "SRC%d probed\n", i);
684 }
685
686 return 0;
687}
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 4b8cf7ca9d19..633b23d209b9 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -64,108 +64,29 @@ struct rsnd_ssi {
64 struct rsnd_mod mod; 64 struct rsnd_mod mod;
65 65
66 struct rsnd_dai *rdai; 66 struct rsnd_dai *rdai;
67 struct rsnd_dai_stream *io;
68 u32 cr_own; 67 u32 cr_own;
69 u32 cr_clk; 68 u32 cr_clk;
70 u32 cr_etc; 69 u32 cr_etc;
71 int err; 70 int err;
72 int dma_offset;
73 unsigned int usrcnt; 71 unsigned int usrcnt;
74 unsigned int rate; 72 unsigned int rate;
75}; 73};
76 74
77struct rsnd_ssiu {
78 u32 ssi_mode0;
79 u32 ssi_mode1;
80
81 int ssi_nr;
82 struct rsnd_ssi *ssi;
83};
84
85#define for_each_rsnd_ssi(pos, priv, i) \ 75#define for_each_rsnd_ssi(pos, priv, i) \
86 for (i = 0; \ 76 for (i = 0; \
87 (i < rsnd_ssi_nr(priv)) && \ 77 (i < rsnd_ssi_nr(priv)) && \
88 ((pos) = ((struct rsnd_ssiu *)((priv)->ssiu))->ssi + i); \ 78 ((pos) = ((struct rsnd_ssi *)(priv)->ssi + i)); \
89 i++) 79 i++)
90 80
91#define rsnd_ssi_nr(priv) (((struct rsnd_ssiu *)((priv)->ssiu))->ssi_nr) 81#define rsnd_ssi_nr(priv) ((priv)->ssi_nr)
92#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) 82#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
93#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma)) 83#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma))
94#define rsnd_ssi_pio_available(ssi) ((ssi)->info->pio_irq > 0) 84#define rsnd_ssi_pio_available(ssi) ((ssi)->info->pio_irq > 0)
95#define rsnd_ssi_dma_available(ssi) \ 85#define rsnd_ssi_dma_available(ssi) \
96 rsnd_dma_available(rsnd_mod_to_dma(&(ssi)->mod)) 86 rsnd_dma_available(rsnd_mod_to_dma(&(ssi)->mod))
97#define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent) 87#define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent)
98#define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master)
99#define rsnd_ssi_mode_flags(p) ((p)->info->flags) 88#define rsnd_ssi_mode_flags(p) ((p)->info->flags)
100#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) 89#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id)
101#define rsnd_ssi_to_ssiu(ssi)\
102 (((struct rsnd_ssiu *)((ssi) - rsnd_mod_id(&(ssi)->mod))) - 1)
103
104static void rsnd_ssi_mode_set(struct rsnd_priv *priv,
105 struct rsnd_dai *rdai,
106 struct rsnd_ssi *ssi)
107{
108 struct device *dev = rsnd_priv_to_dev(priv);
109 struct rsnd_mod *scu;
110 struct rsnd_ssiu *ssiu = rsnd_ssi_to_ssiu(ssi);
111 int id = rsnd_mod_id(&ssi->mod);
112 u32 flags;
113 u32 val;
114
115 scu = rsnd_scu_mod_get(priv, rsnd_mod_id(&ssi->mod));
116
117 /*
118 * SSI_MODE0
119 */
120
121 /* see also BUSIF_MODE */
122 if (rsnd_scu_hpbif_is_enable(scu)) {
123 ssiu->ssi_mode0 &= ~(1 << id);
124 dev_dbg(dev, "SSI%d uses DEPENDENT mode\n", id);
125 } else {
126 ssiu->ssi_mode0 |= (1 << id);
127 dev_dbg(dev, "SSI%d uses INDEPENDENT mode\n", id);
128 }
129
130 /*
131 * SSI_MODE1
132 */
133#define ssi_parent_set(p, sync, adg, ext) \
134 do { \
135 ssi->parent = ssiu->ssi + p; \
136 if (rsnd_rdai_is_clk_master(rdai)) \
137 val = adg; \
138 else \
139 val = ext; \
140 if (flags & RSND_SSI_SYNC) \
141 val |= sync; \
142 } while (0)
143
144 flags = rsnd_ssi_mode_flags(ssi);
145 if (flags & RSND_SSI_CLK_PIN_SHARE) {
146
147 val = 0;
148 switch (id) {
149 case 1:
150 ssi_parent_set(0, (1 << 4), (0x2 << 0), (0x1 << 0));
151 break;
152 case 2:
153 ssi_parent_set(0, (1 << 4), (0x2 << 2), (0x1 << 2));
154 break;
155 case 4:
156 ssi_parent_set(3, (1 << 20), (0x2 << 16), (0x1 << 16));
157 break;
158 case 8:
159 ssi_parent_set(7, 0, 0, 0);
160 break;
161 }
162
163 ssiu->ssi_mode1 |= val;
164 }
165
166 rsnd_mod_write(&ssi->mod, SSI_MODE0, ssiu->ssi_mode0);
167 rsnd_mod_write(&ssi->mod, SSI_MODE1, ssiu->ssi_mode1);
168}
169 90
170static void rsnd_ssi_status_check(struct rsnd_mod *mod, 91static void rsnd_ssi_status_check(struct rsnd_mod *mod,
171 u32 bit) 92 u32 bit)
@@ -200,7 +121,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
200 1, 2, 4, 8, 16, 6, 12, 121 1, 2, 4, 8, 16, 6, 12,
201 }; 122 };
202 unsigned int main_rate; 123 unsigned int main_rate;
203 unsigned int rate = rsnd_scu_get_ssi_rate(priv, &ssi->mod, runtime); 124 unsigned int rate = rsnd_src_get_ssi_rate(priv, io, runtime);
204 125
205 /* 126 /*
206 * Find best clock, and try to start ADG 127 * Find best clock, and try to start ADG
@@ -252,7 +173,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
252 if (0 == ssi->usrcnt) { 173 if (0 == ssi->usrcnt) {
253 clk_enable(ssi->clk); 174 clk_enable(ssi->clk);
254 175
255 if (rsnd_rdai_is_clk_master(rdai)) { 176 if (rsnd_dai_is_clk_master(rdai)) {
256 if (rsnd_ssi_clk_from_parent(ssi)) 177 if (rsnd_ssi_clk_from_parent(ssi))
257 rsnd_ssi_hw_start(ssi->parent, rdai, io); 178 rsnd_ssi_hw_start(ssi->parent, rdai, io);
258 else 179 else
@@ -302,7 +223,7 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
302 rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */ 223 rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */
303 rsnd_ssi_status_check(&ssi->mod, IIRQ); 224 rsnd_ssi_status_check(&ssi->mod, IIRQ);
304 225
305 if (rsnd_rdai_is_clk_master(rdai)) { 226 if (rsnd_dai_is_clk_master(rdai)) {
306 if (rsnd_ssi_clk_from_parent(ssi)) 227 if (rsnd_ssi_clk_from_parent(ssi))
307 rsnd_ssi_hw_stop(ssi->parent, rdai); 228 rsnd_ssi_hw_stop(ssi->parent, rdai);
308 else 229 else
@@ -323,8 +244,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
323 struct rsnd_dai_stream *io) 244 struct rsnd_dai_stream *io)
324{ 245{
325 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 246 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
326 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
327 struct device *dev = rsnd_priv_to_dev(priv);
328 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 247 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
329 u32 cr; 248 u32 cr;
330 249
@@ -365,13 +284,10 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
365 * set ssi parameter 284 * set ssi parameter
366 */ 285 */
367 ssi->rdai = rdai; 286 ssi->rdai = rdai;
368 ssi->io = io;
369 ssi->cr_own = cr; 287 ssi->cr_own = cr;
370 ssi->err = -1; /* ignore 1st error */ 288 ssi->err = -1; /* ignore 1st error */
371 289
372 rsnd_ssi_mode_set(priv, rdai, ssi); 290 rsnd_src_ssi_mode_init(mod, rdai, io);
373
374 dev_dbg(dev, "%s.%d init\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
375 291
376 return 0; 292 return 0;
377} 293}
@@ -384,13 +300,10 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
384 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 300 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
385 struct device *dev = rsnd_priv_to_dev(priv); 301 struct device *dev = rsnd_priv_to_dev(priv);
386 302
387 dev_dbg(dev, "%s.%d quit\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
388
389 if (ssi->err > 0) 303 if (ssi->err > 0)
390 dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err); 304 dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err);
391 305
392 ssi->rdai = NULL; 306 ssi->rdai = NULL;
393 ssi->io = NULL;
394 ssi->cr_own = 0; 307 ssi->cr_own = 0;
395 ssi->err = 0; 308 ssi->err = 0;
396 309
@@ -414,8 +327,9 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
414static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) 327static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
415{ 328{
416 struct rsnd_ssi *ssi = data; 329 struct rsnd_ssi *ssi = data;
417 struct rsnd_dai_stream *io = ssi->io; 330 struct rsnd_mod *mod = &ssi->mod;
418 u32 status = rsnd_mod_read(&ssi->mod, SSISR); 331 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
332 u32 status = rsnd_mod_read(mod, SSISR);
419 irqreturn_t ret = IRQ_NONE; 333 irqreturn_t ret = IRQ_NONE;
420 334
421 if (io && (status & DIRQ)) { 335 if (io && (status & DIRQ)) {
@@ -432,9 +346,9 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
432 * see rsnd_ssi_init() 346 * see rsnd_ssi_init()
433 */ 347 */
434 if (rsnd_dai_is_play(rdai, io)) 348 if (rsnd_dai_is_play(rdai, io))
435 rsnd_mod_write(&ssi->mod, SSITDR, *buf); 349 rsnd_mod_write(mod, SSITDR, *buf);
436 else 350 else
437 *buf = rsnd_mod_read(&ssi->mod, SSIRDR); 351 *buf = rsnd_mod_read(mod, SSIRDR);
438 352
439 rsnd_dai_pointer_update(io, sizeof(*buf)); 353 rsnd_dai_pointer_update(io, sizeof(*buf));
440 354
@@ -444,25 +358,39 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
444 return ret; 358 return ret;
445} 359}
446 360
447static int rsnd_ssi_pio_start(struct rsnd_mod *mod, 361static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
448 struct rsnd_dai *rdai, 362 struct rsnd_dai *rdai,
449 struct rsnd_dai_stream *io) 363 struct rsnd_dai_stream *io)
450{ 364{
451 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 365 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
452 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
453 struct device *dev = rsnd_priv_to_dev(priv); 366 struct device *dev = rsnd_priv_to_dev(priv);
367 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
368 int irq = ssi->info->pio_irq;
369 int ret;
370
371 ret = devm_request_irq(dev, irq,
372 rsnd_ssi_pio_interrupt,
373 IRQF_SHARED,
374 dev_name(dev), ssi);
375 if (ret)
376 dev_err(dev, "SSI request interrupt failed\n");
377
378 return ret;
379}
380
381static int rsnd_ssi_pio_start(struct rsnd_mod *mod,
382 struct rsnd_dai *rdai,
383 struct rsnd_dai_stream *io)
384{
385 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
454 386
455 /* enable PIO IRQ */ 387 /* enable PIO IRQ */
456 ssi->cr_etc = UIEN | OIEN | DIEN; 388 ssi->cr_etc = UIEN | OIEN | DIEN;
457 389
458 /* enable PIO interrupt if gen2 */ 390 rsnd_src_enable_ssi_irq(mod, rdai, io);
459 if (rsnd_is_gen2(priv))
460 rsnd_mod_write(&ssi->mod, INT_ENABLE, 0x0f000000);
461 391
462 rsnd_ssi_hw_start(ssi, rdai, io); 392 rsnd_ssi_hw_start(ssi, rdai, io);
463 393
464 dev_dbg(dev, "%s.%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
465
466 return 0; 394 return 0;
467} 395}
468 396
@@ -470,12 +398,8 @@ static int rsnd_ssi_pio_stop(struct rsnd_mod *mod,
470 struct rsnd_dai *rdai, 398 struct rsnd_dai *rdai,
471 struct rsnd_dai_stream *io) 399 struct rsnd_dai_stream *io)
472{ 400{
473 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
474 struct device *dev = rsnd_priv_to_dev(priv);
475 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 401 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
476 402
477 dev_dbg(dev, "%s.%d stop\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
478
479 ssi->cr_etc = 0; 403 ssi->cr_etc = 0;
480 404
481 rsnd_ssi_hw_stop(ssi, rdai); 405 rsnd_ssi_hw_stop(ssi, rdai);
@@ -485,35 +409,46 @@ static int rsnd_ssi_pio_stop(struct rsnd_mod *mod,
485 409
486static struct rsnd_mod_ops rsnd_ssi_pio_ops = { 410static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
487 .name = "ssi (pio)", 411 .name = "ssi (pio)",
412 .probe = rsnd_ssi_pio_probe,
488 .init = rsnd_ssi_init, 413 .init = rsnd_ssi_init,
489 .quit = rsnd_ssi_quit, 414 .quit = rsnd_ssi_quit,
490 .start = rsnd_ssi_pio_start, 415 .start = rsnd_ssi_pio_start,
491 .stop = rsnd_ssi_pio_stop, 416 .stop = rsnd_ssi_pio_stop,
492}; 417};
493 418
494static int rsnd_ssi_dma_inquiry(struct rsnd_dma *dma, dma_addr_t *buf, int *len) 419static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
420 struct rsnd_dai *rdai,
421 struct rsnd_dai_stream *io)
495{ 422{
496 struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma); 423 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
497 struct rsnd_dai_stream *io = ssi->io; 424 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
498 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 425 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
426 struct device *dev = rsnd_priv_to_dev(priv);
427 int dma_id = ssi->info->dma_id;
428 int is_play;
429 int ret;
499 430
500 *len = io->byte_per_period; 431 if (info->dai_info)
501 *buf = runtime->dma_addr + 432 is_play = rsnd_info_is_playback(priv, ssi);
502 rsnd_dai_pointer_offset(io, ssi->dma_offset + *len); 433 else
503 ssi->dma_offset = *len; /* it cares A/B plane */ 434 is_play = rsnd_ssi_is_play(&ssi->mod);
504 435
505 return 0; 436 ret = rsnd_dma_init(
506} 437 priv, rsnd_mod_to_dma(mod),
438 is_play,
439 dma_id);
507 440
508static int rsnd_ssi_dma_complete(struct rsnd_dma *dma) 441 if (ret < 0)
509{ 442 dev_err(dev, "SSI DMA failed\n");
510 struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma);
511 struct rsnd_dai_stream *io = ssi->io;
512 u32 status = rsnd_mod_read(&ssi->mod, SSISR);
513 443
514 rsnd_ssi_record_error(ssi, status); 444 return ret;
445}
515 446
516 rsnd_dai_pointer_update(ssi->io, io->byte_per_period); 447static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
448 struct rsnd_dai *rdai,
449 struct rsnd_dai_stream *io)
450{
451 rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod));
517 452
518 return 0; 453 return 0;
519} 454}
@@ -527,14 +462,13 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
527 462
528 /* enable DMA transfer */ 463 /* enable DMA transfer */
529 ssi->cr_etc = DMEN; 464 ssi->cr_etc = DMEN;
530 ssi->dma_offset = 0;
531 465
532 rsnd_dma_start(dma); 466 rsnd_dma_start(dma);
533 467
534 rsnd_ssi_hw_start(ssi, ssi->rdai, io); 468 rsnd_ssi_hw_start(ssi, ssi->rdai, io);
535 469
536 /* enable WS continue */ 470 /* enable WS continue */
537 if (rsnd_rdai_is_clk_master(rdai)) 471 if (rsnd_dai_is_clk_master(rdai))
538 rsnd_mod_write(&ssi->mod, SSIWSR, CONT); 472 rsnd_mod_write(&ssi->mod, SSIWSR, CONT);
539 473
540 return 0; 474 return 0;
@@ -549,6 +483,8 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
549 483
550 ssi->cr_etc = 0; 484 ssi->cr_etc = 0;
551 485
486 rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR));
487
552 rsnd_ssi_hw_stop(ssi, rdai); 488 rsnd_ssi_hw_stop(ssi, rdai);
553 489
554 rsnd_dma_stop(dma); 490 rsnd_dma_stop(dma);
@@ -558,6 +494,8 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
558 494
559static struct rsnd_mod_ops rsnd_ssi_dma_ops = { 495static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
560 .name = "ssi (dma)", 496 .name = "ssi (dma)",
497 .probe = rsnd_ssi_dma_probe,
498 .remove = rsnd_ssi_dma_remove,
561 .init = rsnd_ssi_init, 499 .init = rsnd_ssi_init,
562 .quit = rsnd_ssi_quit, 500 .quit = rsnd_ssi_quit,
563 .start = rsnd_ssi_dma_start, 501 .start = rsnd_ssi_dma_start,
@@ -567,24 +505,8 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
567/* 505/*
568 * Non SSI 506 * Non SSI
569 */ 507 */
570static int rsnd_ssi_non(struct rsnd_mod *mod,
571 struct rsnd_dai *rdai,
572 struct rsnd_dai_stream *io)
573{
574 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
575 struct device *dev = rsnd_priv_to_dev(priv);
576
577 dev_dbg(dev, "%s\n", __func__);
578
579 return 0;
580}
581
582static struct rsnd_mod_ops rsnd_ssi_non_ops = { 508static struct rsnd_mod_ops rsnd_ssi_non_ops = {
583 .name = "ssi (non)", 509 .name = "ssi (non)",
584 .init = rsnd_ssi_non,
585 .quit = rsnd_ssi_non,
586 .start = rsnd_ssi_non,
587 .stop = rsnd_ssi_non,
588}; 510};
589 511
590/* 512/*
@@ -593,16 +515,30 @@ static struct rsnd_mod_ops rsnd_ssi_non_ops = {
593struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, 515struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv,
594 int dai_id, int is_play) 516 int dai_id, int is_play)
595{ 517{
518 struct rsnd_dai_platform_info *dai_info = NULL;
519 struct rsnd_dai_path_info *path_info = NULL;
520 struct rsnd_ssi_platform_info *target_info = NULL;
596 struct rsnd_ssi *ssi; 521 struct rsnd_ssi *ssi;
597 int i, has_play; 522 int i, has_play;
598 523
524 if (priv->rdai)
525 dai_info = priv->rdai[dai_id].info;
526 if (dai_info)
527 path_info = (is_play) ? &dai_info->playback : &dai_info->capture;
528 if (path_info)
529 target_info = path_info->ssi;
530
599 is_play = !!is_play; 531 is_play = !!is_play;
600 532
601 for_each_rsnd_ssi(ssi, priv, i) { 533 for_each_rsnd_ssi(ssi, priv, i) {
534 if (target_info == ssi->info)
535 return &ssi->mod;
536
537 /* for compatible */
602 if (rsnd_ssi_dai_id(ssi) != dai_id) 538 if (rsnd_ssi_dai_id(ssi) != dai_id)
603 continue; 539 continue;
604 540
605 has_play = !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY); 541 has_play = rsnd_ssi_is_play(&ssi->mod);
606 542
607 if (is_play == has_play) 543 if (is_play == has_play)
608 return &ssi->mod; 544 return &ssi->mod;
@@ -616,36 +552,66 @@ struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
616 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) 552 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv)))
617 id = 0; 553 id = 0;
618 554
619 return &(((struct rsnd_ssiu *)(priv->ssiu))->ssi + id)->mod; 555 return &((struct rsnd_ssi *)(priv->ssi) + id)->mod;
556}
557
558int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
559{
560 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
561
562 return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE);
563}
564
565int rsnd_ssi_is_play(struct rsnd_mod *mod)
566{
567 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
568
569 return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY);
570}
571
572static void rsnd_ssi_parent_clk_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi)
573{
574 if (!rsnd_ssi_is_pin_sharing(&ssi->mod))
575 return;
576
577 switch (rsnd_mod_id(&ssi->mod)) {
578 case 1:
579 case 2:
580 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 0));
581 break;
582 case 4:
583 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 3));
584 break;
585 case 8:
586 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 7));
587 break;
588 }
620} 589}
621 590
622int rsnd_ssi_probe(struct platform_device *pdev, 591int rsnd_ssi_probe(struct platform_device *pdev,
623 struct rcar_snd_info *info,
624 struct rsnd_priv *priv) 592 struct rsnd_priv *priv)
625{ 593{
594 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
626 struct rsnd_ssi_platform_info *pinfo; 595 struct rsnd_ssi_platform_info *pinfo;
627 struct device *dev = rsnd_priv_to_dev(priv); 596 struct device *dev = rsnd_priv_to_dev(priv);
628 struct rsnd_mod_ops *ops; 597 struct rsnd_mod_ops *ops;
629 struct clk *clk; 598 struct clk *clk;
630 struct rsnd_ssiu *ssiu;
631 struct rsnd_ssi *ssi; 599 struct rsnd_ssi *ssi;
632 char name[RSND_SSI_NAME_SIZE]; 600 char name[RSND_SSI_NAME_SIZE];
633 int i, nr, ret; 601 int i, nr;
634 602
635 /* 603 /*
636 * init SSI 604 * init SSI
637 */ 605 */
638 nr = info->ssi_info_nr; 606 nr = info->ssi_info_nr;
639 ssiu = devm_kzalloc(dev, sizeof(*ssiu) + (sizeof(*ssi) * nr), 607 ssi = devm_kzalloc(dev, sizeof(*ssi) * nr, GFP_KERNEL);
640 GFP_KERNEL); 608 if (!ssi) {
641 if (!ssiu) {
642 dev_err(dev, "SSI allocate failed\n"); 609 dev_err(dev, "SSI allocate failed\n");
643 return -ENOMEM; 610 return -ENOMEM;
644 } 611 }
645 612
646 priv->ssiu = ssiu; 613 priv->ssi = ssi;
647 ssiu->ssi = (struct rsnd_ssi *)(ssiu + 1); 614 priv->ssi_nr = nr;
648 ssiu->ssi_nr = nr;
649 615
650 for_each_rsnd_ssi(ssi, priv, i) { 616 for_each_rsnd_ssi(ssi, priv, i) {
651 pinfo = &info->ssi_info[i]; 617 pinfo = &info->ssi_info[i];
@@ -660,61 +626,15 @@ int rsnd_ssi_probe(struct platform_device *pdev,
660 ssi->clk = clk; 626 ssi->clk = clk;
661 627
662 ops = &rsnd_ssi_non_ops; 628 ops = &rsnd_ssi_non_ops;
629 if (pinfo->dma_id > 0)
630 ops = &rsnd_ssi_dma_ops;
631 else if (rsnd_ssi_pio_available(ssi))
632 ops = &rsnd_ssi_pio_ops;
663 633
664 /* 634 rsnd_mod_init(priv, &ssi->mod, ops, RSND_MOD_SSI, i);
665 * SSI DMA case
666 */
667 if (pinfo->dma_id > 0) {
668 ret = rsnd_dma_init(
669 priv, rsnd_mod_to_dma(&ssi->mod),
670 (rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY),
671 pinfo->dma_id,
672 rsnd_ssi_dma_inquiry,
673 rsnd_ssi_dma_complete);
674 if (ret < 0)
675 dev_info(dev, "SSI DMA failed. try PIO transter\n");
676 else
677 ops = &rsnd_ssi_dma_ops;
678
679 dev_dbg(dev, "SSI%d use DMA transfer\n", i);
680 }
681
682 /*
683 * SSI PIO case
684 */
685 if (!rsnd_ssi_dma_available(ssi) &&
686 rsnd_ssi_pio_available(ssi)) {
687 ret = devm_request_irq(dev, pinfo->pio_irq,
688 &rsnd_ssi_pio_interrupt,
689 IRQF_SHARED,
690 dev_name(dev), ssi);
691 if (ret) {
692 dev_err(dev, "SSI request interrupt failed\n");
693 return ret;
694 }
695
696 ops = &rsnd_ssi_pio_ops;
697 635
698 dev_dbg(dev, "SSI%d use PIO transfer\n", i); 636 rsnd_ssi_parent_clk_setup(priv, ssi);
699 }
700
701 rsnd_mod_init(priv, &ssi->mod, ops, i);
702 } 637 }
703 638
704 dev_dbg(dev, "ssi probed\n");
705
706 return 0; 639 return 0;
707} 640}
708
709void rsnd_ssi_remove(struct platform_device *pdev,
710 struct rsnd_priv *priv)
711{
712 struct rsnd_ssi *ssi;
713 int i;
714
715 for_each_rsnd_ssi(ssi, priv, i) {
716 if (rsnd_ssi_dma_available(ssi))
717 rsnd_dma_quit(priv, rsnd_mod_to_dma(&ssi->mod));
718 }
719
720}
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 375dc6dfba4e..bfed3e4c45ff 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -96,8 +96,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec)
96{ 96{
97 dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n", 97 dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n",
98 codec->name); 98 codec->name);
99 if (!codec->reg_cache) 99
100 return 0;
101 kfree(codec->reg_cache); 100 kfree(codec->reg_cache);
102 codec->reg_cache = NULL; 101 codec->reg_cache = NULL;
103 return 0; 102 return 0;
@@ -117,8 +116,9 @@ int snd_soc_cache_read(struct snd_soc_codec *codec,
117 return -EINVAL; 116 return -EINVAL;
118 117
119 mutex_lock(&codec->cache_rw_mutex); 118 mutex_lock(&codec->cache_rw_mutex);
120 *value = snd_soc_get_cache_val(codec->reg_cache, reg, 119 if (!ZERO_OR_NULL_PTR(codec->reg_cache))
121 codec->driver->reg_word_size); 120 *value = snd_soc_get_cache_val(codec->reg_cache, reg,
121 codec->driver->reg_word_size);
122 mutex_unlock(&codec->cache_rw_mutex); 122 mutex_unlock(&codec->cache_rw_mutex);
123 123
124 return 0; 124 return 0;
@@ -136,8 +136,9 @@ int snd_soc_cache_write(struct snd_soc_codec *codec,
136 unsigned int reg, unsigned int value) 136 unsigned int reg, unsigned int value)
137{ 137{
138 mutex_lock(&codec->cache_rw_mutex); 138 mutex_lock(&codec->cache_rw_mutex);
139 snd_soc_set_cache_val(codec->reg_cache, reg, value, 139 if (!ZERO_OR_NULL_PTR(codec->reg_cache))
140 codec->driver->reg_word_size); 140 snd_soc_set_cache_val(codec->reg_cache, reg, value,
141 codec->driver->reg_word_size);
141 mutex_unlock(&codec->cache_rw_mutex); 142 mutex_unlock(&codec->cache_rw_mutex);
142 143
143 return 0; 144 return 0;
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 5e9690c85d8f..91083e6a6b38 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -30,8 +30,6 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
30{ 30{
31 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 31 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
32 struct snd_soc_platform *platform = rtd->platform; 32 struct snd_soc_platform *platform = rtd->platform;
33 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
34 struct snd_soc_dai *codec_dai = rtd->codec_dai;
35 int ret = 0; 33 int ret = 0;
36 34
37 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 35 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -52,17 +50,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
52 } 50 }
53 } 51 }
54 52
55 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 53 snd_soc_runtime_activate(rtd, cstream->direction);
56 cpu_dai->playback_active++;
57 codec_dai->playback_active++;
58 } else {
59 cpu_dai->capture_active++;
60 codec_dai->capture_active++;
61 }
62
63 cpu_dai->active++;
64 codec_dai->active++;
65 rtd->codec->active++;
66 54
67 mutex_unlock(&rtd->pcm_mutex); 55 mutex_unlock(&rtd->pcm_mutex);
68 56
@@ -81,8 +69,6 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
81 struct snd_soc_pcm_runtime *fe = cstream->private_data; 69 struct snd_soc_pcm_runtime *fe = cstream->private_data;
82 struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream; 70 struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
83 struct snd_soc_platform *platform = fe->platform; 71 struct snd_soc_platform *platform = fe->platform;
84 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
85 struct snd_soc_dai *codec_dai = fe->codec_dai;
86 struct snd_soc_dpcm *dpcm; 72 struct snd_soc_dpcm *dpcm;
87 struct snd_soc_dapm_widget_list *list; 73 struct snd_soc_dapm_widget_list *list;
88 int stream; 74 int stream;
@@ -140,17 +126,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
140 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; 126 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
141 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 127 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
142 128
143 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 129 snd_soc_runtime_activate(fe, stream);
144 cpu_dai->playback_active++;
145 codec_dai->playback_active++;
146 } else {
147 cpu_dai->capture_active++;
148 codec_dai->capture_active++;
149 }
150
151 cpu_dai->active++;
152 codec_dai->active++;
153 fe->codec->active++;
154 130
155 mutex_unlock(&fe->card->mutex); 131 mutex_unlock(&fe->card->mutex);
156 132
@@ -202,23 +178,18 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
202 struct snd_soc_platform *platform = rtd->platform; 178 struct snd_soc_platform *platform = rtd->platform;
203 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 179 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
204 struct snd_soc_dai *codec_dai = rtd->codec_dai; 180 struct snd_soc_dai *codec_dai = rtd->codec_dai;
205 struct snd_soc_codec *codec = rtd->codec; 181 int stream;
206 182
207 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 183 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
208 184
209 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 185 if (cstream->direction == SND_COMPRESS_PLAYBACK)
210 cpu_dai->playback_active--; 186 stream = SNDRV_PCM_STREAM_PLAYBACK;
211 codec_dai->playback_active--; 187 else
212 } else { 188 stream = SNDRV_PCM_STREAM_CAPTURE;
213 cpu_dai->capture_active--;
214 codec_dai->capture_active--;
215 }
216 189
217 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); 190 snd_soc_runtime_deactivate(rtd, stream);
218 191
219 cpu_dai->active--; 192 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
220 codec_dai->active--;
221 codec->active--;
222 193
223 if (!cpu_dai->active) 194 if (!cpu_dai->active)
224 cpu_dai->rate = 0; 195 cpu_dai->rate = 0;
@@ -235,8 +206,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
235 cpu_dai->runtime = NULL; 206 cpu_dai->runtime = NULL;
236 207
237 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 208 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
238 if (!rtd->pmdown_time || codec->ignore_pmdown_time || 209 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
239 rtd->dai_link->ignore_pmdown_time) {
240 snd_soc_dapm_stream_event(rtd, 210 snd_soc_dapm_stream_event(rtd,
241 SNDRV_PCM_STREAM_PLAYBACK, 211 SNDRV_PCM_STREAM_PLAYBACK,
242 SND_SOC_DAPM_STREAM_STOP); 212 SND_SOC_DAPM_STREAM_STOP);
@@ -261,26 +231,17 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
261{ 231{
262 struct snd_soc_pcm_runtime *fe = cstream->private_data; 232 struct snd_soc_pcm_runtime *fe = cstream->private_data;
263 struct snd_soc_platform *platform = fe->platform; 233 struct snd_soc_platform *platform = fe->platform;
264 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
265 struct snd_soc_dai *codec_dai = fe->codec_dai;
266 struct snd_soc_dpcm *dpcm; 234 struct snd_soc_dpcm *dpcm;
267 int stream, ret; 235 int stream, ret;
268 236
269 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 237 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
270 238
271 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 239 if (cstream->direction == SND_COMPRESS_PLAYBACK)
272 stream = SNDRV_PCM_STREAM_PLAYBACK; 240 stream = SNDRV_PCM_STREAM_PLAYBACK;
273 cpu_dai->playback_active--; 241 else
274 codec_dai->playback_active--;
275 } else {
276 stream = SNDRV_PCM_STREAM_CAPTURE; 242 stream = SNDRV_PCM_STREAM_CAPTURE;
277 cpu_dai->capture_active--;
278 codec_dai->capture_active--;
279 }
280 243
281 cpu_dai->active--; 244 snd_soc_runtime_deactivate(fe, stream);
282 codec_dai->active--;
283 fe->codec->active--;
284 245
285 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 246 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
286 247
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index fe1df50805a3..359c2849b364 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -56,7 +56,6 @@ EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
56#endif 56#endif
57 57
58static DEFINE_MUTEX(client_mutex); 58static DEFINE_MUTEX(client_mutex);
59static LIST_HEAD(dai_list);
60static LIST_HEAD(platform_list); 59static LIST_HEAD(platform_list);
61static LIST_HEAD(codec_list); 60static LIST_HEAD(codec_list);
62static LIST_HEAD(component_list); 61static LIST_HEAD(component_list);
@@ -370,18 +369,22 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf,
370{ 369{
371 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 370 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
372 ssize_t len, ret = 0; 371 ssize_t len, ret = 0;
372 struct snd_soc_component *component;
373 struct snd_soc_dai *dai; 373 struct snd_soc_dai *dai;
374 374
375 if (!buf) 375 if (!buf)
376 return -ENOMEM; 376 return -ENOMEM;
377 377
378 list_for_each_entry(dai, &dai_list, list) { 378 list_for_each_entry(component, &component_list, list) {
379 len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", dai->name); 379 list_for_each_entry(dai, &component->dai_list, list) {
380 if (len >= 0) 380 len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
381 ret += len; 381 dai->name);
382 if (ret > PAGE_SIZE) { 382 if (len >= 0)
383 ret = PAGE_SIZE; 383 ret += len;
384 break; 384 if (ret > PAGE_SIZE) {
385 ret = PAGE_SIZE;
386 break;
387 }
385 } 388 }
386 } 389 }
387 390
@@ -855,6 +858,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
855{ 858{
856 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 859 struct snd_soc_dai_link *dai_link = &card->dai_link[num];
857 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 860 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
861 struct snd_soc_component *component;
858 struct snd_soc_codec *codec; 862 struct snd_soc_codec *codec;
859 struct snd_soc_platform *platform; 863 struct snd_soc_platform *platform;
860 struct snd_soc_dai *codec_dai, *cpu_dai; 864 struct snd_soc_dai *codec_dai, *cpu_dai;
@@ -863,18 +867,20 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
863 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); 867 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num);
864 868
865 /* Find CPU DAI from registered DAIs*/ 869 /* Find CPU DAI from registered DAIs*/
866 list_for_each_entry(cpu_dai, &dai_list, list) { 870 list_for_each_entry(component, &component_list, list) {
867 if (dai_link->cpu_of_node && 871 if (dai_link->cpu_of_node &&
868 (cpu_dai->dev->of_node != dai_link->cpu_of_node)) 872 component->dev->of_node != dai_link->cpu_of_node)
869 continue; 873 continue;
870 if (dai_link->cpu_name && 874 if (dai_link->cpu_name &&
871 strcmp(dev_name(cpu_dai->dev), dai_link->cpu_name)) 875 strcmp(dev_name(component->dev), dai_link->cpu_name))
872 continue;
873 if (dai_link->cpu_dai_name &&
874 strcmp(cpu_dai->name, dai_link->cpu_dai_name))
875 continue; 876 continue;
877 list_for_each_entry(cpu_dai, &component->dai_list, list) {
878 if (dai_link->cpu_dai_name &&
879 strcmp(cpu_dai->name, dai_link->cpu_dai_name))
880 continue;
876 881
877 rtd->cpu_dai = cpu_dai; 882 rtd->cpu_dai = cpu_dai;
883 }
878 } 884 }
879 885
880 if (!rtd->cpu_dai) { 886 if (!rtd->cpu_dai) {
@@ -899,12 +905,10 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
899 * CODEC found, so find CODEC DAI from registered DAIs from 905 * CODEC found, so find CODEC DAI from registered DAIs from
900 * this CODEC 906 * this CODEC
901 */ 907 */
902 list_for_each_entry(codec_dai, &dai_list, list) { 908 list_for_each_entry(codec_dai, &codec->component.dai_list, list) {
903 if (codec->dev == codec_dai->dev && 909 if (!strcmp(codec_dai->name, dai_link->codec_dai_name)) {
904 !strcmp(codec_dai->name,
905 dai_link->codec_dai_name)) {
906
907 rtd->codec_dai = codec_dai; 910 rtd->codec_dai = codec_dai;
911 break;
908 } 912 }
909 } 913 }
910 914
@@ -1128,12 +1132,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
1128 driver->num_dapm_widgets); 1132 driver->num_dapm_widgets);
1129 1133
1130 /* Create DAPM widgets for each DAI stream */ 1134 /* Create DAPM widgets for each DAI stream */
1131 list_for_each_entry(dai, &dai_list, list) { 1135 list_for_each_entry(dai, &codec->component.dai_list, list)
1132 if (dai->dev != codec->dev)
1133 continue;
1134
1135 snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); 1136 snd_soc_dapm_new_dai_widgets(&codec->dapm, dai);
1136 }
1137 1137
1138 codec->dapm.idle_bias_off = driver->idle_bias_off; 1138 codec->dapm.idle_bias_off = driver->idle_bias_off;
1139 1139
@@ -1180,6 +1180,7 @@ static int soc_probe_platform(struct snd_soc_card *card,
1180{ 1180{
1181 int ret = 0; 1181 int ret = 0;
1182 const struct snd_soc_platform_driver *driver = platform->driver; 1182 const struct snd_soc_platform_driver *driver = platform->driver;
1183 struct snd_soc_component *component;
1183 struct snd_soc_dai *dai; 1184 struct snd_soc_dai *dai;
1184 1185
1185 platform->card = card; 1186 platform->card = card;
@@ -1195,11 +1196,11 @@ static int soc_probe_platform(struct snd_soc_card *card,
1195 driver->dapm_widgets, driver->num_dapm_widgets); 1196 driver->dapm_widgets, driver->num_dapm_widgets);
1196 1197
1197 /* Create DAPM widgets for each DAI stream */ 1198 /* Create DAPM widgets for each DAI stream */
1198 list_for_each_entry(dai, &dai_list, list) { 1199 list_for_each_entry(component, &component_list, list) {
1199 if (dai->dev != platform->dev) 1200 if (component->dev != platform->dev)
1200 continue; 1201 continue;
1201 1202 list_for_each_entry(dai, &component->dai_list, list)
1202 snd_soc_dapm_new_dai_widgets(&platform->dapm, dai); 1203 snd_soc_dapm_new_dai_widgets(&platform->dapm, dai);
1203 } 1204 }
1204 1205
1205 platform->dapm.idle_bias_off = 1; 1206 platform->dapm.idle_bias_off = 1;
@@ -2571,10 +2572,10 @@ int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
2571 2572
2572 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2573 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2573 uinfo->count = e->shift_l == e->shift_r ? 1 : 2; 2574 uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
2574 uinfo->value.enumerated.items = e->max; 2575 uinfo->value.enumerated.items = e->items;
2575 2576
2576 if (uinfo->value.enumerated.item > e->max - 1) 2577 if (uinfo->value.enumerated.item >= e->items)
2577 uinfo->value.enumerated.item = e->max - 1; 2578 uinfo->value.enumerated.item = e->items - 1;
2578 strlcpy(uinfo->value.enumerated.name, 2579 strlcpy(uinfo->value.enumerated.name,
2579 e->texts[uinfo->value.enumerated.item], 2580 e->texts[uinfo->value.enumerated.item],
2580 sizeof(uinfo->value.enumerated.name)); 2581 sizeof(uinfo->value.enumerated.name));
@@ -2596,14 +2597,18 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
2596{ 2597{
2597 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2598 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2598 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2599 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2599 unsigned int val; 2600 unsigned int val, item;
2601 unsigned int reg_val;
2600 2602
2601 val = snd_soc_read(codec, e->reg); 2603 reg_val = snd_soc_read(codec, e->reg);
2602 ucontrol->value.enumerated.item[0] 2604 val = (reg_val >> e->shift_l) & e->mask;
2603 = (val >> e->shift_l) & e->mask; 2605 item = snd_soc_enum_val_to_item(e, val);
2604 if (e->shift_l != e->shift_r) 2606 ucontrol->value.enumerated.item[0] = item;
2605 ucontrol->value.enumerated.item[1] = 2607 if (e->shift_l != e->shift_r) {
2606 (val >> e->shift_r) & e->mask; 2608 val = (reg_val >> e->shift_l) & e->mask;
2609 item = snd_soc_enum_val_to_item(e, val);
2610 ucontrol->value.enumerated.item[1] = item;
2611 }
2607 2612
2608 return 0; 2613 return 0;
2609} 2614}
@@ -2623,17 +2628,18 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
2623{ 2628{
2624 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2629 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2625 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2630 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2631 unsigned int *item = ucontrol->value.enumerated.item;
2626 unsigned int val; 2632 unsigned int val;
2627 unsigned int mask; 2633 unsigned int mask;
2628 2634
2629 if (ucontrol->value.enumerated.item[0] > e->max - 1) 2635 if (item[0] >= e->items)
2630 return -EINVAL; 2636 return -EINVAL;
2631 val = ucontrol->value.enumerated.item[0] << e->shift_l; 2637 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
2632 mask = e->mask << e->shift_l; 2638 mask = e->mask << e->shift_l;
2633 if (e->shift_l != e->shift_r) { 2639 if (e->shift_l != e->shift_r) {
2634 if (ucontrol->value.enumerated.item[1] > e->max - 1) 2640 if (item[1] >= e->items)
2635 return -EINVAL; 2641 return -EINVAL;
2636 val |= ucontrol->value.enumerated.item[1] << e->shift_r; 2642 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r;
2637 mask |= e->mask << e->shift_r; 2643 mask |= e->mask << e->shift_r;
2638 } 2644 }
2639 2645
@@ -2642,78 +2648,46 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
2642EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); 2648EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
2643 2649
2644/** 2650/**
2645 * snd_soc_get_value_enum_double - semi enumerated double mixer get callback 2651 * snd_soc_read_signed - Read a codec register and interprete as signed value
2646 * @kcontrol: mixer control 2652 * @codec: codec
2647 * @ucontrol: control element information 2653 * @reg: Register to read
2648 * 2654 * @mask: Mask to use after shifting the register value
2649 * Callback to get the value of a double semi enumerated mixer. 2655 * @shift: Right shift of register value
2656 * @sign_bit: Bit that describes if a number is negative or not.
2650 * 2657 *
2651 * Semi enumerated mixer: the enumerated items are referred as values. Can be 2658 * This functions reads a codec register. The register value is shifted right
2652 * used for handling bitfield coded enumeration for example. 2659 * by 'shift' bits and masked with the given 'mask'. Afterwards it translates
2660 * the given registervalue into a signed integer if sign_bit is non-zero.
2653 * 2661 *
2654 * Returns 0 for success. 2662 * Returns the register value as signed int.
2655 */ 2663 */
2656int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol, 2664static int snd_soc_read_signed(struct snd_soc_codec *codec, unsigned int reg,
2657 struct snd_ctl_elem_value *ucontrol) 2665 unsigned int mask, unsigned int shift, unsigned int sign_bit)
2658{ 2666{
2659 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2667 int ret;
2660 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2668 unsigned int val;
2661 unsigned int reg_val, val, mux;
2662 2669
2663 reg_val = snd_soc_read(codec, e->reg); 2670 val = (snd_soc_read(codec, reg) >> shift) & mask;
2664 val = (reg_val >> e->shift_l) & e->mask;
2665 for (mux = 0; mux < e->max; mux++) {
2666 if (val == e->values[mux])
2667 break;
2668 }
2669 ucontrol->value.enumerated.item[0] = mux;
2670 if (e->shift_l != e->shift_r) {
2671 val = (reg_val >> e->shift_r) & e->mask;
2672 for (mux = 0; mux < e->max; mux++) {
2673 if (val == e->values[mux])
2674 break;
2675 }
2676 ucontrol->value.enumerated.item[1] = mux;
2677 }
2678 2671
2679 return 0; 2672 if (!sign_bit)
2680} 2673 return val;
2681EXPORT_SYMBOL_GPL(snd_soc_get_value_enum_double);
2682 2674
2683/** 2675 /* non-negative number */
2684 * snd_soc_put_value_enum_double - semi enumerated double mixer put callback 2676 if (!(val & BIT(sign_bit)))
2685 * @kcontrol: mixer control 2677 return val;
2686 * @ucontrol: control element information
2687 *
2688 * Callback to set the value of a double semi enumerated mixer.
2689 *
2690 * Semi enumerated mixer: the enumerated items are referred as values. Can be
2691 * used for handling bitfield coded enumeration for example.
2692 *
2693 * Returns 0 for success.
2694 */
2695int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
2696 struct snd_ctl_elem_value *ucontrol)
2697{
2698 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2699 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2700 unsigned int val;
2701 unsigned int mask;
2702 2678
2703 if (ucontrol->value.enumerated.item[0] > e->max - 1) 2679 ret = val;
2704 return -EINVAL;
2705 val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l;
2706 mask = e->mask << e->shift_l;
2707 if (e->shift_l != e->shift_r) {
2708 if (ucontrol->value.enumerated.item[1] > e->max - 1)
2709 return -EINVAL;
2710 val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r;
2711 mask |= e->mask << e->shift_r;
2712 }
2713 2680
2714 return snd_soc_update_bits_locked(codec, e->reg, mask, val); 2681 /*
2682 * The register most probably does not contain a full-sized int.
2683 * Instead we have an arbitrary number of bits in a signed
2684 * representation which has to be translated into a full-sized int.
2685 * This is done by filling up all bits above the sign-bit.
2686 */
2687 ret |= ~((int)(BIT(sign_bit) - 1));
2688
2689 return ret;
2715} 2690}
2716EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double);
2717 2691
2718/** 2692/**
2719 * snd_soc_info_volsw - single mixer info callback 2693 * snd_soc_info_volsw - single mixer info callback
@@ -2743,7 +2717,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
2743 2717
2744 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; 2718 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1;
2745 uinfo->value.integer.min = 0; 2719 uinfo->value.integer.min = 0;
2746 uinfo->value.integer.max = platform_max; 2720 uinfo->value.integer.max = platform_max - mc->min;
2747 return 0; 2721 return 0;
2748} 2722}
2749EXPORT_SYMBOL_GPL(snd_soc_info_volsw); 2723EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
@@ -2769,11 +2743,16 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
2769 unsigned int shift = mc->shift; 2743 unsigned int shift = mc->shift;
2770 unsigned int rshift = mc->rshift; 2744 unsigned int rshift = mc->rshift;
2771 int max = mc->max; 2745 int max = mc->max;
2746 int min = mc->min;
2747 int sign_bit = mc->sign_bit;
2772 unsigned int mask = (1 << fls(max)) - 1; 2748 unsigned int mask = (1 << fls(max)) - 1;
2773 unsigned int invert = mc->invert; 2749 unsigned int invert = mc->invert;
2774 2750
2775 ucontrol->value.integer.value[0] = 2751 if (sign_bit)
2776 (snd_soc_read(codec, reg) >> shift) & mask; 2752 mask = BIT(sign_bit + 1) - 1;
2753
2754 ucontrol->value.integer.value[0] = snd_soc_read_signed(codec, reg, mask,
2755 shift, sign_bit) - min;
2777 if (invert) 2756 if (invert)
2778 ucontrol->value.integer.value[0] = 2757 ucontrol->value.integer.value[0] =
2779 max - ucontrol->value.integer.value[0]; 2758 max - ucontrol->value.integer.value[0];
@@ -2781,10 +2760,12 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
2781 if (snd_soc_volsw_is_stereo(mc)) { 2760 if (snd_soc_volsw_is_stereo(mc)) {
2782 if (reg == reg2) 2761 if (reg == reg2)
2783 ucontrol->value.integer.value[1] = 2762 ucontrol->value.integer.value[1] =
2784 (snd_soc_read(codec, reg) >> rshift) & mask; 2763 snd_soc_read_signed(codec, reg, mask, rshift,
2764 sign_bit) - min;
2785 else 2765 else
2786 ucontrol->value.integer.value[1] = 2766 ucontrol->value.integer.value[1] =
2787 (snd_soc_read(codec, reg2) >> shift) & mask; 2767 snd_soc_read_signed(codec, reg2, mask, shift,
2768 sign_bit) - min;
2788 if (invert) 2769 if (invert)
2789 ucontrol->value.integer.value[1] = 2770 ucontrol->value.integer.value[1] =
2790 max - ucontrol->value.integer.value[1]; 2771 max - ucontrol->value.integer.value[1];
@@ -2815,20 +2796,25 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
2815 unsigned int shift = mc->shift; 2796 unsigned int shift = mc->shift;
2816 unsigned int rshift = mc->rshift; 2797 unsigned int rshift = mc->rshift;
2817 int max = mc->max; 2798 int max = mc->max;
2799 int min = mc->min;
2800 unsigned int sign_bit = mc->sign_bit;
2818 unsigned int mask = (1 << fls(max)) - 1; 2801 unsigned int mask = (1 << fls(max)) - 1;
2819 unsigned int invert = mc->invert; 2802 unsigned int invert = mc->invert;
2820 int err; 2803 int err;
2821 bool type_2r = 0; 2804 bool type_2r = false;
2822 unsigned int val2 = 0; 2805 unsigned int val2 = 0;
2823 unsigned int val, val_mask; 2806 unsigned int val, val_mask;
2824 2807
2825 val = (ucontrol->value.integer.value[0] & mask); 2808 if (sign_bit)
2809 mask = BIT(sign_bit + 1) - 1;
2810
2811 val = ((ucontrol->value.integer.value[0] + min) & mask);
2826 if (invert) 2812 if (invert)
2827 val = max - val; 2813 val = max - val;
2828 val_mask = mask << shift; 2814 val_mask = mask << shift;
2829 val = val << shift; 2815 val = val << shift;
2830 if (snd_soc_volsw_is_stereo(mc)) { 2816 if (snd_soc_volsw_is_stereo(mc)) {
2831 val2 = (ucontrol->value.integer.value[1] & mask); 2817 val2 = ((ucontrol->value.integer.value[1] + min) & mask);
2832 if (invert) 2818 if (invert)
2833 val2 = max - val2; 2819 val2 = max - val2;
2834 if (reg == reg2) { 2820 if (reg == reg2) {
@@ -2836,7 +2822,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
2836 val |= val2 << rshift; 2822 val |= val2 << rshift;
2837 } else { 2823 } else {
2838 val2 = val2 << shift; 2824 val2 = val2 << shift;
2839 type_2r = 1; 2825 type_2r = true;
2840 } 2826 }
2841 } 2827 }
2842 err = snd_soc_update_bits_locked(codec, reg, val_mask, val); 2828 err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
@@ -3234,7 +3220,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
3234 struct soc_bytes *params = (void *)kcontrol->private_value; 3220 struct soc_bytes *params = (void *)kcontrol->private_value;
3235 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 3221 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
3236 int ret, len; 3222 int ret, len;
3237 unsigned int val; 3223 unsigned int val, mask;
3238 void *data; 3224 void *data;
3239 3225
3240 if (!codec->using_regmap) 3226 if (!codec->using_regmap)
@@ -3264,12 +3250,36 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
3264 ((u8 *)data)[0] |= val; 3250 ((u8 *)data)[0] |= val;
3265 break; 3251 break;
3266 case 2: 3252 case 2:
3267 ((u16 *)data)[0] &= cpu_to_be16(~params->mask); 3253 mask = ~params->mask;
3268 ((u16 *)data)[0] |= cpu_to_be16(val); 3254 ret = regmap_parse_val(codec->control_data,
3255 &mask, &mask);
3256 if (ret != 0)
3257 goto out;
3258
3259 ((u16 *)data)[0] &= mask;
3260
3261 ret = regmap_parse_val(codec->control_data,
3262 &val, &val);
3263 if (ret != 0)
3264 goto out;
3265
3266 ((u16 *)data)[0] |= val;
3269 break; 3267 break;
3270 case 4: 3268 case 4:
3271 ((u32 *)data)[0] &= cpu_to_be32(~params->mask); 3269 mask = ~params->mask;
3272 ((u32 *)data)[0] |= cpu_to_be32(val); 3270 ret = regmap_parse_val(codec->control_data,
3271 &mask, &mask);
3272 if (ret != 0)
3273 goto out;
3274
3275 ((u32 *)data)[0] &= mask;
3276
3277 ret = regmap_parse_val(codec->control_data,
3278 &val, &val);
3279 if (ret != 0)
3280 goto out;
3281
3282 ((u32 *)data)[0] |= val;
3273 break; 3283 break;
3274 default: 3284 default:
3275 ret = -EINVAL; 3285 ret = -EINVAL;
@@ -3609,6 +3619,30 @@ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3609EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); 3619EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
3610 3620
3611/** 3621/**
3622 * snd_soc_of_xlate_tdm_slot - generate tx/rx slot mask.
3623 * @slots: Number of slots in use.
3624 * @tx_mask: bitmask representing active TX slots.
3625 * @rx_mask: bitmask representing active RX slots.
3626 *
3627 * Generates the TDM tx and rx slot default masks for DAI.
3628 */
3629static int snd_soc_of_xlate_tdm_slot_mask(unsigned int slots,
3630 unsigned int *tx_mask,
3631 unsigned int *rx_mask)
3632{
3633 if (*tx_mask || *rx_mask)
3634 return 0;
3635
3636 if (!slots)
3637 return -EINVAL;
3638
3639 *tx_mask = (1 << slots) - 1;
3640 *rx_mask = (1 << slots) - 1;
3641
3642 return 0;
3643}
3644
3645/**
3612 * snd_soc_dai_set_tdm_slot - configure DAI TDM. 3646 * snd_soc_dai_set_tdm_slot - configure DAI TDM.
3613 * @dai: DAI 3647 * @dai: DAI
3614 * @tx_mask: bitmask representing active TX slots. 3648 * @tx_mask: bitmask representing active TX slots.
@@ -3622,11 +3656,17 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
3622int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, 3656int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
3623 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 3657 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
3624{ 3658{
3659 if (dai->driver && dai->driver->ops->of_xlate_tdm_slot_mask)
3660 dai->driver->ops->of_xlate_tdm_slot_mask(slots,
3661 &tx_mask, &rx_mask);
3662 else
3663 snd_soc_of_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask);
3664
3625 if (dai->driver && dai->driver->ops->set_tdm_slot) 3665 if (dai->driver && dai->driver->ops->set_tdm_slot)
3626 return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask, 3666 return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
3627 slots, slot_width); 3667 slots, slot_width);
3628 else 3668 else
3629 return -EINVAL; 3669 return -ENOTSUPP;
3630} 3670}
3631EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); 3671EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
3632 3672
@@ -3882,95 +3922,42 @@ static inline char *fmt_multiple_name(struct device *dev,
3882} 3922}
3883 3923
3884/** 3924/**
3885 * snd_soc_register_dai - Register a DAI with the ASoC core 3925 * snd_soc_unregister_dai - Unregister DAIs from the ASoC core
3886 * 3926 *
3887 * @dai: DAI to register 3927 * @component: The component for which the DAIs should be unregistered
3888 */ 3928 */
3889static int snd_soc_register_dai(struct device *dev, 3929static void snd_soc_unregister_dais(struct snd_soc_component *component)
3890 struct snd_soc_dai_driver *dai_drv)
3891{ 3930{
3892 struct snd_soc_codec *codec; 3931 struct snd_soc_dai *dai, *_dai;
3893 struct snd_soc_dai *dai;
3894
3895 dev_dbg(dev, "ASoC: dai register %s\n", dev_name(dev));
3896 3932
3897 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); 3933 list_for_each_entry_safe(dai, _dai, &component->dai_list, list) {
3898 if (dai == NULL) 3934 dev_dbg(component->dev, "ASoC: Unregistered DAI '%s'\n",
3899 return -ENOMEM; 3935 dai->name);
3900 3936 list_del(&dai->list);
3901 /* create DAI component name */ 3937 kfree(dai->name);
3902 dai->name = fmt_single_name(dev, &dai->id);
3903 if (dai->name == NULL) {
3904 kfree(dai); 3938 kfree(dai);
3905 return -ENOMEM;
3906 }
3907
3908 dai->dev = dev;
3909 dai->driver = dai_drv;
3910 dai->dapm.dev = dev;
3911 if (!dai->driver->ops)
3912 dai->driver->ops = &null_dai_ops;
3913
3914 mutex_lock(&client_mutex);
3915
3916 list_for_each_entry(codec, &codec_list, list) {
3917 if (codec->dev == dev) {
3918 dev_dbg(dev, "ASoC: Mapped DAI %s to CODEC %s\n",
3919 dai->name, codec->name);
3920 dai->codec = codec;
3921 break;
3922 }
3923 } 3939 }
3924
3925 if (!dai->codec)
3926 dai->dapm.idle_bias_off = 1;
3927
3928 list_add(&dai->list, &dai_list);
3929
3930 mutex_unlock(&client_mutex);
3931
3932 dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);
3933
3934 return 0;
3935} 3940}
3936 3941
3937/** 3942/**
3938 * snd_soc_unregister_dai - Unregister a DAI from the ASoC core 3943 * snd_soc_register_dais - Register a DAI with the ASoC core
3939 * 3944 *
3940 * @dai: DAI to unregister 3945 * @component: The component the DAIs are registered for
3941 */ 3946 * @codec: The CODEC that the DAIs are registered for, NULL if the component is
3942static void snd_soc_unregister_dai(struct device *dev) 3947 * not a CODEC.
3943{ 3948 * @dai_drv: DAI driver to use for the DAIs
3944 struct snd_soc_dai *dai;
3945
3946 list_for_each_entry(dai, &dai_list, list) {
3947 if (dev == dai->dev)
3948 goto found;
3949 }
3950 return;
3951
3952found:
3953 mutex_lock(&client_mutex);
3954 list_del(&dai->list);
3955 mutex_unlock(&client_mutex);
3956
3957 dev_dbg(dev, "ASoC: Unregistered DAI '%s'\n", dai->name);
3958 kfree(dai->name);
3959 kfree(dai);
3960}
3961
3962/**
3963 * snd_soc_register_dais - Register multiple DAIs with the ASoC core
3964 *
3965 * @dai: Array of DAIs to register
3966 * @count: Number of DAIs 3949 * @count: Number of DAIs
3950 * @legacy_dai_naming: Use the legacy naming scheme and let the DAI inherit the
3951 * parent's name.
3967 */ 3952 */
3968static int snd_soc_register_dais(struct device *dev, 3953static int snd_soc_register_dais(struct snd_soc_component *component,
3969 struct snd_soc_dai_driver *dai_drv, size_t count) 3954 struct snd_soc_codec *codec, struct snd_soc_dai_driver *dai_drv,
3955 size_t count, bool legacy_dai_naming)
3970{ 3956{
3971 struct snd_soc_codec *codec; 3957 struct device *dev = component->dev;
3972 struct snd_soc_dai *dai; 3958 struct snd_soc_dai *dai;
3973 int i, ret = 0; 3959 unsigned int i;
3960 int ret;
3974 3961
3975 dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count); 3962 dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count);
3976 3963
@@ -3982,70 +3969,54 @@ static int snd_soc_register_dais(struct device *dev,
3982 goto err; 3969 goto err;
3983 } 3970 }
3984 3971
3985 /* create DAI component name */ 3972 /*
3986 dai->name = fmt_multiple_name(dev, &dai_drv[i]); 3973 * Back in the old days when we still had component-less DAIs,
3974 * instead of having a static name, component-less DAIs would
3975 * inherit the name of the parent device so it is possible to
3976 * register multiple instances of the DAI. We still need to keep
3977 * the same naming style even though those DAIs are not
3978 * component-less anymore.
3979 */
3980 if (count == 1 && legacy_dai_naming) {
3981 dai->name = fmt_single_name(dev, &dai->id);
3982 } else {
3983 dai->name = fmt_multiple_name(dev, &dai_drv[i]);
3984 if (dai_drv[i].id)
3985 dai->id = dai_drv[i].id;
3986 else
3987 dai->id = i;
3988 }
3987 if (dai->name == NULL) { 3989 if (dai->name == NULL) {
3988 kfree(dai); 3990 kfree(dai);
3989 ret = -EINVAL; 3991 ret = -ENOMEM;
3990 goto err; 3992 goto err;
3991 } 3993 }
3992 3994
3995 dai->component = component;
3996 dai->codec = codec;
3993 dai->dev = dev; 3997 dai->dev = dev;
3994 dai->driver = &dai_drv[i]; 3998 dai->driver = &dai_drv[i];
3995 if (dai->driver->id)
3996 dai->id = dai->driver->id;
3997 else
3998 dai->id = i;
3999 dai->dapm.dev = dev; 3999 dai->dapm.dev = dev;
4000 if (!dai->driver->ops) 4000 if (!dai->driver->ops)
4001 dai->driver->ops = &null_dai_ops; 4001 dai->driver->ops = &null_dai_ops;
4002 4002
4003 mutex_lock(&client_mutex);
4004
4005 list_for_each_entry(codec, &codec_list, list) {
4006 if (codec->dev == dev) {
4007 dev_dbg(dev,
4008 "ASoC: Mapped DAI %s to CODEC %s\n",
4009 dai->name, codec->name);
4010 dai->codec = codec;
4011 break;
4012 }
4013 }
4014
4015 if (!dai->codec) 4003 if (!dai->codec)
4016 dai->dapm.idle_bias_off = 1; 4004 dai->dapm.idle_bias_off = 1;
4017 4005
4018 list_add(&dai->list, &dai_list); 4006 list_add(&dai->list, &component->dai_list);
4019 4007
4020 mutex_unlock(&client_mutex); 4008 dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);
4021
4022 dev_dbg(dai->dev, "ASoC: Registered DAI '%s'\n", dai->name);
4023 } 4009 }
4024 4010
4025 return 0; 4011 return 0;
4026 4012
4027err: 4013err:
4028 for (i--; i >= 0; i--) 4014 snd_soc_unregister_dais(component);
4029 snd_soc_unregister_dai(dev);
4030 4015
4031 return ret; 4016 return ret;
4032} 4017}
4033 4018
4034/** 4019/**
4035 * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core
4036 *
4037 * @dai: Array of DAIs to unregister
4038 * @count: Number of DAIs
4039 */
4040static void snd_soc_unregister_dais(struct device *dev, size_t count)
4041{
4042 int i;
4043
4044 for (i = 0; i < count; i++)
4045 snd_soc_unregister_dai(dev);
4046}
4047
4048/**
4049 * snd_soc_register_component - Register a component with the ASoC core 4020 * snd_soc_register_component - Register a component with the ASoC core
4050 * 4021 *
4051 */ 4022 */
@@ -4053,6 +4024,7 @@ static int
4053__snd_soc_register_component(struct device *dev, 4024__snd_soc_register_component(struct device *dev,
4054 struct snd_soc_component *cmpnt, 4025 struct snd_soc_component *cmpnt,
4055 const struct snd_soc_component_driver *cmpnt_drv, 4026 const struct snd_soc_component_driver *cmpnt_drv,
4027 struct snd_soc_codec *codec,
4056 struct snd_soc_dai_driver *dai_drv, 4028 struct snd_soc_dai_driver *dai_drv,
4057 int num_dai, bool allow_single_dai) 4029 int num_dai, bool allow_single_dai)
4058{ 4030{
@@ -4075,20 +4047,10 @@ __snd_soc_register_component(struct device *dev,
4075 cmpnt->driver = cmpnt_drv; 4047 cmpnt->driver = cmpnt_drv;
4076 cmpnt->dai_drv = dai_drv; 4048 cmpnt->dai_drv = dai_drv;
4077 cmpnt->num_dai = num_dai; 4049 cmpnt->num_dai = num_dai;
4050 INIT_LIST_HEAD(&cmpnt->dai_list);
4078 4051
4079 /* 4052 ret = snd_soc_register_dais(cmpnt, codec, dai_drv, num_dai,
4080 * snd_soc_register_dai() uses fmt_single_name(), and 4053 allow_single_dai);
4081 * snd_soc_register_dais() uses fmt_multiple_name()
4082 * for dai->name which is used for name based matching
4083 *
4084 * this function is used from cpu/codec.
4085 * allow_single_dai flag can ignore "codec" driver reworking
4086 * since it had been used snd_soc_register_dais(),
4087 */
4088 if ((1 == num_dai) && allow_single_dai)
4089 ret = snd_soc_register_dai(dev, dai_drv);
4090 else
4091 ret = snd_soc_register_dais(dev, dai_drv, num_dai);
4092 if (ret < 0) { 4054 if (ret < 0) {
4093 dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); 4055 dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
4094 goto error_component_name; 4056 goto error_component_name;
@@ -4121,7 +4083,9 @@ int snd_soc_register_component(struct device *dev,
4121 return -ENOMEM; 4083 return -ENOMEM;
4122 } 4084 }
4123 4085
4124 return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, 4086 cmpnt->ignore_pmdown_time = true;
4087
4088 return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, NULL,
4125 dai_drv, num_dai, true); 4089 dai_drv, num_dai, true);
4126} 4090}
4127EXPORT_SYMBOL_GPL(snd_soc_register_component); 4091EXPORT_SYMBOL_GPL(snd_soc_register_component);
@@ -4141,7 +4105,7 @@ void snd_soc_unregister_component(struct device *dev)
4141 return; 4105 return;
4142 4106
4143found: 4107found:
4144 snd_soc_unregister_dais(dev, cmpnt->num_dai); 4108 snd_soc_unregister_dais(cmpnt);
4145 4109
4146 mutex_lock(&client_mutex); 4110 mutex_lock(&client_mutex);
4147 list_del(&cmpnt->list); 4111 list_del(&cmpnt->list);
@@ -4319,7 +4283,7 @@ int snd_soc_register_codec(struct device *dev,
4319 codec->volatile_register = codec_drv->volatile_register; 4283 codec->volatile_register = codec_drv->volatile_register;
4320 codec->readable_register = codec_drv->readable_register; 4284 codec->readable_register = codec_drv->readable_register;
4321 codec->writable_register = codec_drv->writable_register; 4285 codec->writable_register = codec_drv->writable_register;
4322 codec->ignore_pmdown_time = codec_drv->ignore_pmdown_time; 4286 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
4323 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 4287 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
4324 codec->dapm.dev = dev; 4288 codec->dapm.dev = dev;
4325 codec->dapm.codec = codec; 4289 codec->dapm.codec = codec;
@@ -4342,7 +4306,7 @@ int snd_soc_register_codec(struct device *dev,
4342 /* register component */ 4306 /* register component */
4343 ret = __snd_soc_register_component(dev, &codec->component, 4307 ret = __snd_soc_register_component(dev, &codec->component,
4344 &codec_drv->component_driver, 4308 &codec_drv->component_driver,
4345 dai_drv, num_dai, false); 4309 codec, dai_drv, num_dai, false);
4346 if (ret < 0) { 4310 if (ret < 0) {
4347 dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret); 4311 dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret);
4348 goto fail_codec_name; 4312 goto fail_codec_name;
@@ -4417,6 +4381,122 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
4417} 4381}
4418EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name); 4382EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name);
4419 4383
4384static const struct snd_soc_dapm_widget simple_widgets[] = {
4385 SND_SOC_DAPM_MIC("Microphone", NULL),
4386 SND_SOC_DAPM_LINE("Line", NULL),
4387 SND_SOC_DAPM_HP("Headphone", NULL),
4388 SND_SOC_DAPM_SPK("Speaker", NULL),
4389};
4390
4391int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
4392 const char *propname)
4393{
4394 struct device_node *np = card->dev->of_node;
4395 struct snd_soc_dapm_widget *widgets;
4396 const char *template, *wname;
4397 int i, j, num_widgets, ret;
4398
4399 num_widgets = of_property_count_strings(np, propname);
4400 if (num_widgets < 0) {
4401 dev_err(card->dev,
4402 "ASoC: Property '%s' does not exist\n", propname);
4403 return -EINVAL;
4404 }
4405 if (num_widgets & 1) {
4406 dev_err(card->dev,
4407 "ASoC: Property '%s' length is not even\n", propname);
4408 return -EINVAL;
4409 }
4410
4411 num_widgets /= 2;
4412 if (!num_widgets) {
4413 dev_err(card->dev, "ASoC: Property '%s's length is zero\n",
4414 propname);
4415 return -EINVAL;
4416 }
4417
4418 widgets = devm_kcalloc(card->dev, num_widgets, sizeof(*widgets),
4419 GFP_KERNEL);
4420 if (!widgets) {
4421 dev_err(card->dev,
4422 "ASoC: Could not allocate memory for widgets\n");
4423 return -ENOMEM;
4424 }
4425
4426 for (i = 0; i < num_widgets; i++) {
4427 ret = of_property_read_string_index(np, propname,
4428 2 * i, &template);
4429 if (ret) {
4430 dev_err(card->dev,
4431 "ASoC: Property '%s' index %d read error:%d\n",
4432 propname, 2 * i, ret);
4433 return -EINVAL;
4434 }
4435
4436 for (j = 0; j < ARRAY_SIZE(simple_widgets); j++) {
4437 if (!strncmp(template, simple_widgets[j].name,
4438 strlen(simple_widgets[j].name))) {
4439 widgets[i] = simple_widgets[j];
4440 break;
4441 }
4442 }
4443
4444 if (j >= ARRAY_SIZE(simple_widgets)) {
4445 dev_err(card->dev,
4446 "ASoC: DAPM widget '%s' is not supported\n",
4447 template);
4448 return -EINVAL;
4449 }
4450
4451 ret = of_property_read_string_index(np, propname,
4452 (2 * i) + 1,
4453 &wname);
4454 if (ret) {
4455 dev_err(card->dev,
4456 "ASoC: Property '%s' index %d read error:%d\n",
4457 propname, (2 * i) + 1, ret);
4458 return -EINVAL;
4459 }
4460
4461 widgets[i].name = wname;
4462 }
4463
4464 card->dapm_widgets = widgets;
4465 card->num_dapm_widgets = num_widgets;
4466
4467 return 0;
4468}
4469EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
4470
4471int snd_soc_of_parse_tdm_slot(struct device_node *np,
4472 unsigned int *slots,
4473 unsigned int *slot_width)
4474{
4475 u32 val;
4476 int ret;
4477
4478 if (of_property_read_bool(np, "dai-tdm-slot-num")) {
4479 ret = of_property_read_u32(np, "dai-tdm-slot-num", &val);
4480 if (ret)
4481 return ret;
4482
4483 if (slots)
4484 *slots = val;
4485 }
4486
4487 if (of_property_read_bool(np, "dai-tdm-slot-width")) {
4488 ret = of_property_read_u32(np, "dai-tdm-slot-width", &val);
4489 if (ret)
4490 return ret;
4491
4492 if (slot_width)
4493 *slot_width = val;
4494 }
4495
4496 return 0;
4497}
4498EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot);
4499
4420int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, 4500int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
4421 const char *propname) 4501 const char *propname)
4422{ 4502{
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index dc8ff13187f7..c8a780d0d057 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -70,8 +70,6 @@ static int dapm_up_seq[] = {
70 [snd_soc_dapm_aif_out] = 4, 70 [snd_soc_dapm_aif_out] = 4,
71 [snd_soc_dapm_mic] = 5, 71 [snd_soc_dapm_mic] = 5,
72 [snd_soc_dapm_mux] = 6, 72 [snd_soc_dapm_mux] = 6,
73 [snd_soc_dapm_virt_mux] = 6,
74 [snd_soc_dapm_value_mux] = 6,
75 [snd_soc_dapm_dac] = 7, 73 [snd_soc_dapm_dac] = 7,
76 [snd_soc_dapm_switch] = 8, 74 [snd_soc_dapm_switch] = 8,
77 [snd_soc_dapm_mixer] = 8, 75 [snd_soc_dapm_mixer] = 8,
@@ -102,8 +100,6 @@ static int dapm_down_seq[] = {
102 [snd_soc_dapm_mic] = 7, 100 [snd_soc_dapm_mic] = 7,
103 [snd_soc_dapm_micbias] = 8, 101 [snd_soc_dapm_micbias] = 8,
104 [snd_soc_dapm_mux] = 9, 102 [snd_soc_dapm_mux] = 9,
105 [snd_soc_dapm_virt_mux] = 9,
106 [snd_soc_dapm_value_mux] = 9,
107 [snd_soc_dapm_aif_in] = 10, 103 [snd_soc_dapm_aif_in] = 10,
108 [snd_soc_dapm_aif_out] = 10, 104 [snd_soc_dapm_aif_out] = 10,
109 [snd_soc_dapm_dai_in] = 10, 105 [snd_soc_dapm_dai_in] = 10,
@@ -115,6 +111,12 @@ static int dapm_down_seq[] = {
115 [snd_soc_dapm_post] = 14, 111 [snd_soc_dapm_post] = 14,
116}; 112};
117 113
114static void dapm_assert_locked(struct snd_soc_dapm_context *dapm)
115{
116 if (dapm->card && dapm->card->instantiated)
117 lockdep_assert_held(&dapm->card->dapm_mutex);
118}
119
118static void pop_wait(u32 pop_time) 120static void pop_wait(u32 pop_time)
119{ 121{
120 if (pop_time) 122 if (pop_time)
@@ -146,15 +148,16 @@ static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w)
146 return !list_empty(&w->dirty); 148 return !list_empty(&w->dirty);
147} 149}
148 150
149void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) 151static void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason)
150{ 152{
153 dapm_assert_locked(w->dapm);
154
151 if (!dapm_dirty_widget(w)) { 155 if (!dapm_dirty_widget(w)) {
152 dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n", 156 dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n",
153 w->name, reason); 157 w->name, reason);
154 list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty); 158 list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty);
155 } 159 }
156} 160}
157EXPORT_SYMBOL_GPL(dapm_mark_dirty);
158 161
159void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm) 162void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm)
160{ 163{
@@ -361,6 +364,8 @@ static void dapm_reset(struct snd_soc_card *card)
361{ 364{
362 struct snd_soc_dapm_widget *w; 365 struct snd_soc_dapm_widget *w;
363 366
367 lockdep_assert_held(&card->dapm_mutex);
368
364 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); 369 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
365 370
366 list_for_each_entry(w, &card->widgets, list) { 371 list_for_each_entry(w, &card->widgets, list) {
@@ -386,7 +391,8 @@ static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg,
386 return -1; 391 return -1;
387} 392}
388 393
389static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val) 394static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg,
395 unsigned int val)
390{ 396{
391 if (w->codec) 397 if (w->codec)
392 return snd_soc_write(w->codec, reg, val); 398 return snd_soc_write(w->codec, reg, val);
@@ -498,131 +504,40 @@ out:
498 return ret; 504 return ret;
499} 505}
500 506
501/* set up initial codec paths */ 507/* connect mux widget to its interconnecting audio paths */
502static void dapm_set_path_status(struct snd_soc_dapm_widget *w, 508static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
503 struct snd_soc_dapm_path *p, int i) 509 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
510 struct snd_soc_dapm_path *path, const char *control_name,
511 const struct snd_kcontrol_new *kcontrol)
504{ 512{
505 switch (w->id) { 513 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
506 case snd_soc_dapm_switch: 514 unsigned int val, item;
507 case snd_soc_dapm_mixer: 515 int i;
508 case snd_soc_dapm_mixer_named_ctl: {
509 int val;
510 struct soc_mixer_control *mc = (struct soc_mixer_control *)
511 w->kcontrol_news[i].private_value;
512 int reg = mc->reg;
513 unsigned int shift = mc->shift;
514 int max = mc->max;
515 unsigned int mask = (1 << fls(max)) - 1;
516 unsigned int invert = mc->invert;
517
518 if (reg != SND_SOC_NOPM) {
519 soc_widget_read(w, reg, &val);
520 val = (val >> shift) & mask;
521 if (invert)
522 val = max - val;
523 p->connect = !!val;
524 } else {
525 p->connect = 0;
526 }
527
528 }
529 break;
530 case snd_soc_dapm_mux: {
531 struct soc_enum *e = (struct soc_enum *)
532 w->kcontrol_news[i].private_value;
533 int val, item;
534
535 soc_widget_read(w, e->reg, &val);
536 item = (val >> e->shift_l) & e->mask;
537
538 if (item < e->max && !strcmp(p->name, e->texts[item]))
539 p->connect = 1;
540 else
541 p->connect = 0;
542 }
543 break;
544 case snd_soc_dapm_virt_mux: {
545 struct soc_enum *e = (struct soc_enum *)
546 w->kcontrol_news[i].private_value;
547 516
548 p->connect = 0; 517 if (e->reg != SND_SOC_NOPM) {
518 soc_widget_read(dest, e->reg, &val);
519 val = (val >> e->shift_l) & e->mask;
520 item = snd_soc_enum_val_to_item(e, val);
521 } else {
549 /* since a virtual mux has no backing registers to 522 /* since a virtual mux has no backing registers to
550 * decide which path to connect, it will try to match 523 * decide which path to connect, it will try to match
551 * with the first enumeration. This is to ensure 524 * with the first enumeration. This is to ensure
552 * that the default mux choice (the first) will be 525 * that the default mux choice (the first) will be
553 * correctly powered up during initialization. 526 * correctly powered up during initialization.
554 */ 527 */
555 if (!strcmp(p->name, e->texts[0])) 528 item = 0;
556 p->connect = 1;
557 }
558 break;
559 case snd_soc_dapm_value_mux: {
560 struct soc_enum *e = (struct soc_enum *)
561 w->kcontrol_news[i].private_value;
562 int val, item;
563
564 soc_widget_read(w, e->reg, &val);
565 val = (val >> e->shift_l) & e->mask;
566 for (item = 0; item < e->max; item++) {
567 if (val == e->values[item])
568 break;
569 }
570
571 if (item < e->max && !strcmp(p->name, e->texts[item]))
572 p->connect = 1;
573 else
574 p->connect = 0;
575 }
576 break;
577 /* does not affect routing - always connected */
578 case snd_soc_dapm_pga:
579 case snd_soc_dapm_out_drv:
580 case snd_soc_dapm_output:
581 case snd_soc_dapm_adc:
582 case snd_soc_dapm_input:
583 case snd_soc_dapm_siggen:
584 case snd_soc_dapm_dac:
585 case snd_soc_dapm_micbias:
586 case snd_soc_dapm_vmid:
587 case snd_soc_dapm_supply:
588 case snd_soc_dapm_regulator_supply:
589 case snd_soc_dapm_clock_supply:
590 case snd_soc_dapm_aif_in:
591 case snd_soc_dapm_aif_out:
592 case snd_soc_dapm_dai_in:
593 case snd_soc_dapm_dai_out:
594 case snd_soc_dapm_hp:
595 case snd_soc_dapm_mic:
596 case snd_soc_dapm_spk:
597 case snd_soc_dapm_line:
598 case snd_soc_dapm_dai_link:
599 case snd_soc_dapm_kcontrol:
600 p->connect = 1;
601 break;
602 /* does affect routing - dynamically connected */
603 case snd_soc_dapm_pre:
604 case snd_soc_dapm_post:
605 p->connect = 0;
606 break;
607 } 529 }
608}
609
610/* connect mux widget to its interconnecting audio paths */
611static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
612 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
613 struct snd_soc_dapm_path *path, const char *control_name,
614 const struct snd_kcontrol_new *kcontrol)
615{
616 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
617 int i;
618 530
619 for (i = 0; i < e->max; i++) { 531 for (i = 0; i < e->items; i++) {
620 if (!(strcmp(control_name, e->texts[i]))) { 532 if (!(strcmp(control_name, e->texts[i]))) {
621 list_add(&path->list, &dapm->card->paths); 533 list_add(&path->list, &dapm->card->paths);
622 list_add(&path->list_sink, &dest->sources); 534 list_add(&path->list_sink, &dest->sources);
623 list_add(&path->list_source, &src->sinks); 535 list_add(&path->list_source, &src->sinks);
624 path->name = (char*)e->texts[i]; 536 path->name = (char*)e->texts[i];
625 dapm_set_path_status(dest, path, 0); 537 if (i == item)
538 path->connect = 1;
539 else
540 path->connect = 0;
626 return 0; 541 return 0;
627 } 542 }
628 } 543 }
@@ -630,6 +545,30 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
630 return -ENODEV; 545 return -ENODEV;
631} 546}
632 547
548/* set up initial codec paths */
549static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w,
550 struct snd_soc_dapm_path *p, int i)
551{
552 struct soc_mixer_control *mc = (struct soc_mixer_control *)
553 w->kcontrol_news[i].private_value;
554 unsigned int reg = mc->reg;
555 unsigned int shift = mc->shift;
556 unsigned int max = mc->max;
557 unsigned int mask = (1 << fls(max)) - 1;
558 unsigned int invert = mc->invert;
559 unsigned int val;
560
561 if (reg != SND_SOC_NOPM) {
562 soc_widget_read(w, reg, &val);
563 val = (val >> shift) & mask;
564 if (invert)
565 val = max - val;
566 p->connect = !!val;
567 } else {
568 p->connect = 0;
569 }
570}
571
633/* connect mixer widget to its interconnecting audio paths */ 572/* connect mixer widget to its interconnecting audio paths */
634static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, 573static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
635 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 574 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
@@ -644,7 +583,7 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
644 list_add(&path->list_sink, &dest->sources); 583 list_add(&path->list_sink, &dest->sources);
645 list_add(&path->list_source, &src->sinks); 584 list_add(&path->list_source, &src->sinks);
646 path->name = dest->kcontrol_news[i].name; 585 path->name = dest->kcontrol_news[i].name;
647 dapm_set_path_status(dest, path, i); 586 dapm_set_mixer_path_status(dest, path, i);
648 return 0; 587 return 0;
649 } 588 }
650 } 589 }
@@ -723,8 +662,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
723 kcname_in_long_name = true; 662 kcname_in_long_name = true;
724 break; 663 break;
725 case snd_soc_dapm_mux: 664 case snd_soc_dapm_mux:
726 case snd_soc_dapm_virt_mux:
727 case snd_soc_dapm_value_mux:
728 wname_in_long_name = true; 665 wname_in_long_name = true;
729 kcname_in_long_name = false; 666 kcname_in_long_name = false;
730 break; 667 break;
@@ -1218,7 +1155,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
1218 ret = regulator_allow_bypass(w->regulator, false); 1155 ret = regulator_allow_bypass(w->regulator, false);
1219 if (ret != 0) 1156 if (ret != 0)
1220 dev_warn(w->dapm->dev, 1157 dev_warn(w->dapm->dev,
1221 "ASoC: Failed to bypass %s: %d\n", 1158 "ASoC: Failed to unbypass %s: %d\n",
1222 w->name, ret); 1159 w->name, ret);
1223 } 1160 }
1224 1161
@@ -1228,7 +1165,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
1228 ret = regulator_allow_bypass(w->regulator, true); 1165 ret = regulator_allow_bypass(w->regulator, true);
1229 if (ret != 0) 1166 if (ret != 0)
1230 dev_warn(w->dapm->dev, 1167 dev_warn(w->dapm->dev,
1231 "ASoC: Failed to unbypass %s: %d\n", 1168 "ASoC: Failed to bypass %s: %d\n",
1232 w->name, ret); 1169 w->name, ret);
1233 } 1170 }
1234 1171
@@ -1823,6 +1760,8 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
1823 ASYNC_DOMAIN_EXCLUSIVE(async_domain); 1760 ASYNC_DOMAIN_EXCLUSIVE(async_domain);
1824 enum snd_soc_bias_level bias; 1761 enum snd_soc_bias_level bias;
1825 1762
1763 lockdep_assert_held(&card->dapm_mutex);
1764
1826 trace_snd_soc_dapm_start(card); 1765 trace_snd_soc_dapm_start(card);
1827 1766
1828 list_for_each_entry(d, &card->dapm_list, list) { 1767 list_for_each_entry(d, &card->dapm_list, list) {
@@ -1897,10 +1836,14 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
1897 1836
1898 trace_snd_soc_dapm_walk_done(card); 1837 trace_snd_soc_dapm_walk_done(card);
1899 1838
1900 /* Run all the bias changes in parallel */ 1839 /* Run card bias changes at first */
1901 list_for_each_entry(d, &card->dapm_list, list) 1840 dapm_pre_sequence_async(&card->dapm, 0);
1902 async_schedule_domain(dapm_pre_sequence_async, d, 1841 /* Run other bias changes in parallel */
1903 &async_domain); 1842 list_for_each_entry(d, &card->dapm_list, list) {
1843 if (d != &card->dapm)
1844 async_schedule_domain(dapm_pre_sequence_async, d,
1845 &async_domain);
1846 }
1904 async_synchronize_full_domain(&async_domain); 1847 async_synchronize_full_domain(&async_domain);
1905 1848
1906 list_for_each_entry(w, &down_list, power_list) { 1849 list_for_each_entry(w, &down_list, power_list) {
@@ -1920,10 +1863,14 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
1920 dapm_seq_run(card, &up_list, event, true); 1863 dapm_seq_run(card, &up_list, event, true);
1921 1864
1922 /* Run all the bias changes in parallel */ 1865 /* Run all the bias changes in parallel */
1923 list_for_each_entry(d, &card->dapm_list, list) 1866 list_for_each_entry(d, &card->dapm_list, list) {
1924 async_schedule_domain(dapm_post_sequence_async, d, 1867 if (d != &card->dapm)
1925 &async_domain); 1868 async_schedule_domain(dapm_post_sequence_async, d,
1869 &async_domain);
1870 }
1926 async_synchronize_full_domain(&async_domain); 1871 async_synchronize_full_domain(&async_domain);
1872 /* Run card bias changes at last */
1873 dapm_post_sequence_async(&card->dapm, 0);
1927 1874
1928 /* do we need to notify any clients that DAPM event is complete */ 1875 /* do we need to notify any clients that DAPM event is complete */
1929 list_for_each_entry(d, &card->dapm_list, list) { 1876 list_for_each_entry(d, &card->dapm_list, list) {
@@ -2110,6 +2057,8 @@ static int soc_dapm_mux_update_power(struct snd_soc_card *card,
2110 struct snd_soc_dapm_path *path; 2057 struct snd_soc_dapm_path *path;
2111 int found = 0; 2058 int found = 0;
2112 2059
2060 lockdep_assert_held(&card->dapm_mutex);
2061
2113 /* find dapm widget path assoc with kcontrol */ 2062 /* find dapm widget path assoc with kcontrol */
2114 dapm_kcontrol_for_each_path(path, kcontrol) { 2063 dapm_kcontrol_for_each_path(path, kcontrol) {
2115 if (!path->name || !e->texts[mux]) 2064 if (!path->name || !e->texts[mux])
@@ -2160,6 +2109,8 @@ static int soc_dapm_mixer_update_power(struct snd_soc_card *card,
2160 struct snd_soc_dapm_path *path; 2109 struct snd_soc_dapm_path *path;
2161 int found = 0; 2110 int found = 0;
2162 2111
2112 lockdep_assert_held(&card->dapm_mutex);
2113
2163 /* find dapm widget path assoc with kcontrol */ 2114 /* find dapm widget path assoc with kcontrol */
2164 dapm_kcontrol_for_each_path(path, kcontrol) { 2115 dapm_kcontrol_for_each_path(path, kcontrol) {
2165 found = 1; 2116 found = 1;
@@ -2325,6 +2276,8 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
2325{ 2276{
2326 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); 2277 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
2327 2278
2279 dapm_assert_locked(dapm);
2280
2328 if (!w) { 2281 if (!w) {
2329 dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin); 2282 dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin);
2330 return -EINVAL; 2283 return -EINVAL;
@@ -2341,18 +2294,18 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
2341} 2294}
2342 2295
2343/** 2296/**
2344 * snd_soc_dapm_sync - scan and power dapm paths 2297 * snd_soc_dapm_sync_unlocked - scan and power dapm paths
2345 * @dapm: DAPM context 2298 * @dapm: DAPM context
2346 * 2299 *
2347 * Walks all dapm audio paths and powers widgets according to their 2300 * Walks all dapm audio paths and powers widgets according to their
2348 * stream or path usage. 2301 * stream or path usage.
2349 * 2302 *
2303 * Requires external locking.
2304 *
2350 * Returns 0 for success. 2305 * Returns 0 for success.
2351 */ 2306 */
2352int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) 2307int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm)
2353{ 2308{
2354 int ret;
2355
2356 /* 2309 /*
2357 * Suppress early reports (eg, jacks syncing their state) to avoid 2310 * Suppress early reports (eg, jacks syncing their state) to avoid
2358 * silly DAPM runs during card startup. 2311 * silly DAPM runs during card startup.
@@ -2360,8 +2313,25 @@ int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
2360 if (!dapm->card || !dapm->card->instantiated) 2313 if (!dapm->card || !dapm->card->instantiated)
2361 return 0; 2314 return 0;
2362 2315
2316 return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP);
2317}
2318EXPORT_SYMBOL_GPL(snd_soc_dapm_sync_unlocked);
2319
2320/**
2321 * snd_soc_dapm_sync - scan and power dapm paths
2322 * @dapm: DAPM context
2323 *
2324 * Walks all dapm audio paths and powers widgets according to their
2325 * stream or path usage.
2326 *
2327 * Returns 0 for success.
2328 */
2329int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
2330{
2331 int ret;
2332
2363 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2333 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2364 ret = dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP); 2334 ret = snd_soc_dapm_sync_unlocked(dapm);
2365 mutex_unlock(&dapm->card->dapm_mutex); 2335 mutex_unlock(&dapm->card->dapm_mutex);
2366 return ret; 2336 return ret;
2367} 2337}
@@ -2444,8 +2414,6 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
2444 path->connect = 1; 2414 path->connect = 1;
2445 return 0; 2415 return 0;
2446 case snd_soc_dapm_mux: 2416 case snd_soc_dapm_mux:
2447 case snd_soc_dapm_virt_mux:
2448 case snd_soc_dapm_value_mux:
2449 ret = dapm_connect_mux(dapm, wsource, wsink, path, control, 2417 ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
2450 &wsink->kcontrol_news[0]); 2418 &wsink->kcontrol_news[0]);
2451 if (ret != 0) 2419 if (ret != 0)
@@ -2772,8 +2740,6 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card)
2772 dapm_new_mixer(w); 2740 dapm_new_mixer(w);
2773 break; 2741 break;
2774 case snd_soc_dapm_mux: 2742 case snd_soc_dapm_mux:
2775 case snd_soc_dapm_virt_mux:
2776 case snd_soc_dapm_value_mux:
2777 dapm_new_mux(w); 2743 dapm_new_mux(w);
2778 break; 2744 break;
2779 case snd_soc_dapm_pga: 2745 case snd_soc_dapm_pga:
@@ -2935,213 +2901,75 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
2935{ 2901{
2936 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); 2902 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2937 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2903 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2938 unsigned int val; 2904 unsigned int reg_val, val;
2939
2940 val = snd_soc_read(codec, e->reg);
2941 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask;
2942 if (e->shift_l != e->shift_r)
2943 ucontrol->value.enumerated.item[1] =
2944 (val >> e->shift_r) & e->mask;
2945
2946 return 0;
2947}
2948EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
2949
2950/**
2951 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
2952 * @kcontrol: mixer control
2953 * @ucontrol: control element information
2954 *
2955 * Callback to set the value of a dapm enumerated double mixer control.
2956 *
2957 * Returns 0 for success.
2958 */
2959int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2960 struct snd_ctl_elem_value *ucontrol)
2961{
2962 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2963 struct snd_soc_card *card = codec->card;
2964 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2965 unsigned int val, mux, change;
2966 unsigned int mask;
2967 struct snd_soc_dapm_update update;
2968 int ret = 0;
2969
2970 if (ucontrol->value.enumerated.item[0] > e->max - 1)
2971 return -EINVAL;
2972 mux = ucontrol->value.enumerated.item[0];
2973 val = mux << e->shift_l;
2974 mask = e->mask << e->shift_l;
2975 if (e->shift_l != e->shift_r) {
2976 if (ucontrol->value.enumerated.item[1] > e->max - 1)
2977 return -EINVAL;
2978 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
2979 mask |= e->mask << e->shift_r;
2980 }
2981
2982 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2983
2984 change = snd_soc_test_bits(codec, e->reg, mask, val);
2985 if (change) {
2986 update.kcontrol = kcontrol;
2987 update.reg = e->reg;
2988 update.mask = mask;
2989 update.val = val;
2990 card->update = &update;
2991
2992 ret = soc_dapm_mux_update_power(card, kcontrol, mux, e);
2993
2994 card->update = NULL;
2995 }
2996
2997 mutex_unlock(&card->dapm_mutex);
2998 2905
2999 if (ret > 0) 2906 if (e->reg != SND_SOC_NOPM)
3000 soc_dpcm_runtime_update(card); 2907 reg_val = snd_soc_read(codec, e->reg);
3001 2908 else
3002 return change; 2909 reg_val = dapm_kcontrol_get_value(kcontrol);
3003}
3004EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
3005
3006/**
3007 * snd_soc_dapm_get_enum_virt - Get virtual DAPM mux
3008 * @kcontrol: mixer control
3009 * @ucontrol: control element information
3010 *
3011 * Returns 0 for success.
3012 */
3013int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
3014 struct snd_ctl_elem_value *ucontrol)
3015{
3016 ucontrol->value.enumerated.item[0] = dapm_kcontrol_get_value(kcontrol);
3017 return 0;
3018}
3019EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
3020
3021/**
3022 * snd_soc_dapm_put_enum_virt - Set virtual DAPM mux
3023 * @kcontrol: mixer control
3024 * @ucontrol: control element information
3025 *
3026 * Returns 0 for success.
3027 */
3028int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
3029 struct snd_ctl_elem_value *ucontrol)
3030{
3031 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
3032 struct snd_soc_card *card = codec->card;
3033 unsigned int value;
3034 struct soc_enum *e =
3035 (struct soc_enum *)kcontrol->private_value;
3036 int change;
3037 int ret = 0;
3038
3039 if (ucontrol->value.enumerated.item[0] >= e->max)
3040 return -EINVAL;
3041
3042 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3043
3044 value = ucontrol->value.enumerated.item[0];
3045 change = dapm_kcontrol_set_value(kcontrol, value);
3046 if (change)
3047 ret = soc_dapm_mux_update_power(card, kcontrol, value, e);
3048
3049 mutex_unlock(&card->dapm_mutex);
3050
3051 if (ret > 0)
3052 soc_dpcm_runtime_update(card);
3053
3054 return change;
3055}
3056EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
3057
3058/**
3059 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
3060 * callback
3061 * @kcontrol: mixer control
3062 * @ucontrol: control element information
3063 *
3064 * Callback to get the value of a dapm semi enumerated double mixer control.
3065 *
3066 * Semi enumerated mixer: the enumerated items are referred as values. Can be
3067 * used for handling bitfield coded enumeration for example.
3068 *
3069 * Returns 0 for success.
3070 */
3071int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
3072 struct snd_ctl_elem_value *ucontrol)
3073{
3074 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
3075 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
3076 unsigned int reg_val, val, mux;
3077 2910
3078 reg_val = snd_soc_read(codec, e->reg);
3079 val = (reg_val >> e->shift_l) & e->mask; 2911 val = (reg_val >> e->shift_l) & e->mask;
3080 for (mux = 0; mux < e->max; mux++) { 2912 ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val);
3081 if (val == e->values[mux])
3082 break;
3083 }
3084 ucontrol->value.enumerated.item[0] = mux;
3085 if (e->shift_l != e->shift_r) { 2913 if (e->shift_l != e->shift_r) {
3086 val = (reg_val >> e->shift_r) & e->mask; 2914 val = (reg_val >> e->shift_r) & e->mask;
3087 for (mux = 0; mux < e->max; mux++) { 2915 val = snd_soc_enum_val_to_item(e, val);
3088 if (val == e->values[mux]) 2916 ucontrol->value.enumerated.item[1] = val;
3089 break;
3090 }
3091 ucontrol->value.enumerated.item[1] = mux;
3092 } 2917 }
3093 2918
3094 return 0; 2919 return 0;
3095} 2920}
3096EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double); 2921EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
3097 2922
3098/** 2923/**
3099 * snd_soc_dapm_put_value_enum_double - dapm semi enumerated double mixer set 2924 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
3100 * callback
3101 * @kcontrol: mixer control 2925 * @kcontrol: mixer control
3102 * @ucontrol: control element information 2926 * @ucontrol: control element information
3103 * 2927 *
3104 * Callback to set the value of a dapm semi enumerated double mixer control. 2928 * Callback to set the value of a dapm enumerated double mixer control.
3105 *
3106 * Semi enumerated mixer: the enumerated items are referred as values. Can be
3107 * used for handling bitfield coded enumeration for example.
3108 * 2929 *
3109 * Returns 0 for success. 2930 * Returns 0 for success.
3110 */ 2931 */
3111int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, 2932int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
3112 struct snd_ctl_elem_value *ucontrol) 2933 struct snd_ctl_elem_value *ucontrol)
3113{ 2934{
3114 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); 2935 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
3115 struct snd_soc_card *card = codec->card; 2936 struct snd_soc_card *card = codec->card;
3116 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2937 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
3117 unsigned int val, mux, change; 2938 unsigned int *item = ucontrol->value.enumerated.item;
2939 unsigned int val, change;
3118 unsigned int mask; 2940 unsigned int mask;
3119 struct snd_soc_dapm_update update; 2941 struct snd_soc_dapm_update update;
3120 int ret = 0; 2942 int ret = 0;
3121 2943
3122 if (ucontrol->value.enumerated.item[0] > e->max - 1) 2944 if (item[0] >= e->items)
3123 return -EINVAL; 2945 return -EINVAL;
3124 mux = ucontrol->value.enumerated.item[0]; 2946
3125 val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l; 2947 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
3126 mask = e->mask << e->shift_l; 2948 mask = e->mask << e->shift_l;
3127 if (e->shift_l != e->shift_r) { 2949 if (e->shift_l != e->shift_r) {
3128 if (ucontrol->value.enumerated.item[1] > e->max - 1) 2950 if (item[1] > e->items)
3129 return -EINVAL; 2951 return -EINVAL;
3130 val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r; 2952 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l;
3131 mask |= e->mask << e->shift_r; 2953 mask |= e->mask << e->shift_r;
3132 } 2954 }
3133 2955
3134 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2956 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3135 2957
3136 change = snd_soc_test_bits(codec, e->reg, mask, val); 2958 if (e->reg != SND_SOC_NOPM)
2959 change = snd_soc_test_bits(codec, e->reg, mask, val);
2960 else
2961 change = dapm_kcontrol_set_value(kcontrol, val);
2962
3137 if (change) { 2963 if (change) {
3138 update.kcontrol = kcontrol; 2964 if (e->reg != SND_SOC_NOPM) {
3139 update.reg = e->reg; 2965 update.kcontrol = kcontrol;
3140 update.mask = mask; 2966 update.reg = e->reg;
3141 update.val = val; 2967 update.mask = mask;
3142 card->update = &update; 2968 update.val = val;
2969 card->update = &update;
2970 }
3143 2971
3144 ret = soc_dapm_mux_update_power(card, kcontrol, mux, e); 2972 ret = soc_dapm_mux_update_power(card, kcontrol, item[0], e);
3145 2973
3146 card->update = NULL; 2974 card->update = NULL;
3147 } 2975 }
@@ -3153,7 +2981,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
3153 2981
3154 return change; 2982 return change;
3155} 2983}
3156EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); 2984EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
3157 2985
3158/** 2986/**
3159 * snd_soc_dapm_info_pin_switch - Info for a pin switch 2987 * snd_soc_dapm_info_pin_switch - Info for a pin switch
@@ -3210,15 +3038,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
3210 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 3038 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
3211 const char *pin = (const char *)kcontrol->private_value; 3039 const char *pin = (const char *)kcontrol->private_value;
3212 3040
3213 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3214
3215 if (ucontrol->value.integer.value[0]) 3041 if (ucontrol->value.integer.value[0])
3216 snd_soc_dapm_enable_pin(&card->dapm, pin); 3042 snd_soc_dapm_enable_pin(&card->dapm, pin);
3217 else 3043 else
3218 snd_soc_dapm_disable_pin(&card->dapm, pin); 3044 snd_soc_dapm_disable_pin(&card->dapm, pin);
3219 3045
3220 mutex_unlock(&card->dapm_mutex);
3221
3222 snd_soc_dapm_sync(&card->dapm); 3046 snd_soc_dapm_sync(&card->dapm);
3223 return 0; 3047 return 0;
3224} 3048}
@@ -3248,7 +3072,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3248 ret = regulator_allow_bypass(w->regulator, true); 3072 ret = regulator_allow_bypass(w->regulator, true);
3249 if (ret != 0) 3073 if (ret != 0)
3250 dev_warn(w->dapm->dev, 3074 dev_warn(w->dapm->dev,
3251 "ASoC: Failed to unbypass %s: %d\n", 3075 "ASoC: Failed to bypass %s: %d\n",
3252 w->name, ret); 3076 w->name, ret);
3253 } 3077 }
3254 break; 3078 break;
@@ -3287,8 +3111,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3287 w->power_check = dapm_generic_check_power; 3111 w->power_check = dapm_generic_check_power;
3288 break; 3112 break;
3289 case snd_soc_dapm_mux: 3113 case snd_soc_dapm_mux:
3290 case snd_soc_dapm_virt_mux:
3291 case snd_soc_dapm_value_mux:
3292 w->power_check = dapm_generic_check_power; 3114 w->power_check = dapm_generic_check_power;
3293 break; 3115 break;
3294 case snd_soc_dapm_dai_out: 3116 case snd_soc_dapm_dai_out:
@@ -3767,23 +3589,52 @@ void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
3767} 3589}
3768 3590
3769/** 3591/**
3592 * snd_soc_dapm_enable_pin_unlocked - enable pin.
3593 * @dapm: DAPM context
3594 * @pin: pin name
3595 *
3596 * Enables input/output pin and its parents or children widgets iff there is
3597 * a valid audio route and active audio stream.
3598 *
3599 * Requires external locking.
3600 *
3601 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3602 * do any widget power switching.
3603 */
3604int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
3605 const char *pin)
3606{
3607 return snd_soc_dapm_set_pin(dapm, pin, 1);
3608}
3609EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin_unlocked);
3610
3611/**
3770 * snd_soc_dapm_enable_pin - enable pin. 3612 * snd_soc_dapm_enable_pin - enable pin.
3771 * @dapm: DAPM context 3613 * @dapm: DAPM context
3772 * @pin: pin name 3614 * @pin: pin name
3773 * 3615 *
3774 * Enables input/output pin and its parents or children widgets iff there is 3616 * Enables input/output pin and its parents or children widgets iff there is
3775 * a valid audio route and active audio stream. 3617 * a valid audio route and active audio stream.
3618 *
3776 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 3619 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3777 * do any widget power switching. 3620 * do any widget power switching.
3778 */ 3621 */
3779int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) 3622int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin)
3780{ 3623{
3781 return snd_soc_dapm_set_pin(dapm, pin, 1); 3624 int ret;
3625
3626 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3627
3628 ret = snd_soc_dapm_set_pin(dapm, pin, 1);
3629
3630 mutex_unlock(&dapm->card->dapm_mutex);
3631
3632 return ret;
3782} 3633}
3783EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); 3634EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
3784 3635
3785/** 3636/**
3786 * snd_soc_dapm_force_enable_pin - force a pin to be enabled 3637 * snd_soc_dapm_force_enable_pin_unlocked - force a pin to be enabled
3787 * @dapm: DAPM context 3638 * @dapm: DAPM context
3788 * @pin: pin name 3639 * @pin: pin name
3789 * 3640 *
@@ -3791,11 +3642,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
3791 * intended for use with microphone bias supplies used in microphone 3642 * intended for use with microphone bias supplies used in microphone
3792 * jack detection. 3643 * jack detection.
3793 * 3644 *
3645 * Requires external locking.
3646 *
3794 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 3647 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3795 * do any widget power switching. 3648 * do any widget power switching.
3796 */ 3649 */
3797int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, 3650int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
3798 const char *pin) 3651 const char *pin)
3799{ 3652{
3800 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); 3653 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
3801 3654
@@ -3811,25 +3664,103 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
3811 3664
3812 return 0; 3665 return 0;
3813} 3666}
3667EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin_unlocked);
3668
3669/**
3670 * snd_soc_dapm_force_enable_pin - force a pin to be enabled
3671 * @dapm: DAPM context
3672 * @pin: pin name
3673 *
3674 * Enables input/output pin regardless of any other state. This is
3675 * intended for use with microphone bias supplies used in microphone
3676 * jack detection.
3677 *
3678 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3679 * do any widget power switching.
3680 */
3681int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
3682 const char *pin)
3683{
3684 int ret;
3685
3686 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3687
3688 ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
3689
3690 mutex_unlock(&dapm->card->dapm_mutex);
3691
3692 return ret;
3693}
3814EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); 3694EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
3815 3695
3816/** 3696/**
3697 * snd_soc_dapm_disable_pin_unlocked - disable pin.
3698 * @dapm: DAPM context
3699 * @pin: pin name
3700 *
3701 * Disables input/output pin and its parents or children widgets.
3702 *
3703 * Requires external locking.
3704 *
3705 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3706 * do any widget power switching.
3707 */
3708int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm,
3709 const char *pin)
3710{
3711 return snd_soc_dapm_set_pin(dapm, pin, 0);
3712}
3713EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin_unlocked);
3714
3715/**
3817 * snd_soc_dapm_disable_pin - disable pin. 3716 * snd_soc_dapm_disable_pin - disable pin.
3818 * @dapm: DAPM context 3717 * @dapm: DAPM context
3819 * @pin: pin name 3718 * @pin: pin name
3820 * 3719 *
3821 * Disables input/output pin and its parents or children widgets. 3720 * Disables input/output pin and its parents or children widgets.
3721 *
3822 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 3722 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3823 * do any widget power switching. 3723 * do any widget power switching.
3824 */ 3724 */
3825int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, 3725int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
3826 const char *pin) 3726 const char *pin)
3827{ 3727{
3828 return snd_soc_dapm_set_pin(dapm, pin, 0); 3728 int ret;
3729
3730 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3731
3732 ret = snd_soc_dapm_set_pin(dapm, pin, 0);
3733
3734 mutex_unlock(&dapm->card->dapm_mutex);
3735
3736 return ret;
3829} 3737}
3830EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); 3738EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
3831 3739
3832/** 3740/**
3741 * snd_soc_dapm_nc_pin_unlocked - permanently disable pin.
3742 * @dapm: DAPM context
3743 * @pin: pin name
3744 *
3745 * Marks the specified pin as being not connected, disabling it along
3746 * any parent or child widgets. At present this is identical to
3747 * snd_soc_dapm_disable_pin() but in future it will be extended to do
3748 * additional things such as disabling controls which only affect
3749 * paths through the pin.
3750 *
3751 * Requires external locking.
3752 *
3753 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3754 * do any widget power switching.
3755 */
3756int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm,
3757 const char *pin)
3758{
3759 return snd_soc_dapm_set_pin(dapm, pin, 0);
3760}
3761EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin_unlocked);
3762
3763/**
3833 * snd_soc_dapm_nc_pin - permanently disable pin. 3764 * snd_soc_dapm_nc_pin - permanently disable pin.
3834 * @dapm: DAPM context 3765 * @dapm: DAPM context
3835 * @pin: pin name 3766 * @pin: pin name
@@ -3845,7 +3776,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
3845 */ 3776 */
3846int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) 3777int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin)
3847{ 3778{
3848 return snd_soc_dapm_set_pin(dapm, pin, 0); 3779 int ret;
3780
3781 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3782
3783 ret = snd_soc_dapm_set_pin(dapm, pin, 0);
3784
3785 mutex_unlock(&dapm->card->dapm_mutex);
3786
3787 return ret;
3849} 3788}
3850EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); 3789EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
3851 3790
@@ -3985,7 +3924,7 @@ void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
3985} 3924}
3986EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 3925EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
3987 3926
3988static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) 3927static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm)
3989{ 3928{
3990 struct snd_soc_card *card = dapm->card; 3929 struct snd_soc_card *card = dapm->card;
3991 struct snd_soc_dapm_widget *w; 3930 struct snd_soc_dapm_widget *w;
@@ -4025,14 +3964,21 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
4025 */ 3964 */
4026void snd_soc_dapm_shutdown(struct snd_soc_card *card) 3965void snd_soc_dapm_shutdown(struct snd_soc_card *card)
4027{ 3966{
4028 struct snd_soc_codec *codec; 3967 struct snd_soc_dapm_context *dapm;
4029 3968
4030 list_for_each_entry(codec, &card->codec_dev_list, card_list) { 3969 list_for_each_entry(dapm, &card->dapm_list, list) {
4031 soc_dapm_shutdown_codec(&codec->dapm); 3970 if (dapm != &card->dapm) {
4032 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) 3971 soc_dapm_shutdown_dapm(dapm);
4033 snd_soc_dapm_set_bias_level(&codec->dapm, 3972 if (dapm->bias_level == SND_SOC_BIAS_STANDBY)
4034 SND_SOC_BIAS_OFF); 3973 snd_soc_dapm_set_bias_level(dapm,
3974 SND_SOC_BIAS_OFF);
3975 }
4035 } 3976 }
3977
3978 soc_dapm_shutdown_dapm(&card->dapm);
3979 if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY)
3980 snd_soc_dapm_set_bias_level(&card->dapm,
3981 SND_SOC_BIAS_OFF);
4036} 3982}
4037 3983
4038/* Module information */ 3984/* Module information */
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 47e1ce771e65..330eaf007d89 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -35,6 +35,86 @@
35#define DPCM_MAX_BE_USERS 8 35#define DPCM_MAX_BE_USERS 8
36 36
37/** 37/**
38 * snd_soc_runtime_activate() - Increment active count for PCM runtime components
39 * @rtd: ASoC PCM runtime that is activated
40 * @stream: Direction of the PCM stream
41 *
42 * Increments the active count for all the DAIs and components attached to a PCM
43 * runtime. Should typically be called when a stream is opened.
44 *
45 * Must be called with the rtd->pcm_mutex being held
46 */
47void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
48{
49 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
50 struct snd_soc_dai *codec_dai = rtd->codec_dai;
51
52 lockdep_assert_held(&rtd->pcm_mutex);
53
54 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
55 cpu_dai->playback_active++;
56 codec_dai->playback_active++;
57 } else {
58 cpu_dai->capture_active++;
59 codec_dai->capture_active++;
60 }
61
62 cpu_dai->active++;
63 codec_dai->active++;
64 cpu_dai->component->active++;
65 codec_dai->component->active++;
66}
67
68/**
69 * snd_soc_runtime_deactivate() - Decrement active count for PCM runtime components
70 * @rtd: ASoC PCM runtime that is deactivated
71 * @stream: Direction of the PCM stream
72 *
73 * Decrements the active count for all the DAIs and components attached to a PCM
74 * runtime. Should typically be called when a stream is closed.
75 *
76 * Must be called with the rtd->pcm_mutex being held
77 */
78void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
79{
80 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
81 struct snd_soc_dai *codec_dai = rtd->codec_dai;
82
83 lockdep_assert_held(&rtd->pcm_mutex);
84
85 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
86 cpu_dai->playback_active--;
87 codec_dai->playback_active--;
88 } else {
89 cpu_dai->capture_active--;
90 codec_dai->capture_active--;
91 }
92
93 cpu_dai->active--;
94 codec_dai->active--;
95 cpu_dai->component->active--;
96 codec_dai->component->active--;
97}
98
99/**
100 * snd_soc_runtime_ignore_pmdown_time() - Check whether to ignore the power down delay
101 * @rtd: The ASoC PCM runtime that should be checked.
102 *
103 * This function checks whether the power down delay should be ignored for a
104 * specific PCM runtime. Returns true if the delay is 0, if it the DAI link has
105 * been configured to ignore the delay, or if none of the components benefits
106 * from having the delay.
107 */
108bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd)
109{
110 if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time)
111 return true;
112
113 return rtd->cpu_dai->component->ignore_pmdown_time &&
114 rtd->codec_dai->component->ignore_pmdown_time;
115}
116
117/**
38 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters 118 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
39 * @substream: the pcm substream 119 * @substream: the pcm substream
40 * @hw: the hardware parameters 120 * @hw: the hardware parameters
@@ -378,16 +458,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
378 runtime->hw.rate_max); 458 runtime->hw.rate_max);
379 459
380dynamic: 460dynamic:
381 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 461
382 cpu_dai->playback_active++; 462 snd_soc_runtime_activate(rtd, substream->stream);
383 codec_dai->playback_active++; 463
384 } else {
385 cpu_dai->capture_active++;
386 codec_dai->capture_active++;
387 }
388 cpu_dai->active++;
389 codec_dai->active++;
390 rtd->codec->active++;
391 mutex_unlock(&rtd->pcm_mutex); 464 mutex_unlock(&rtd->pcm_mutex);
392 return 0; 465 return 0;
393 466
@@ -459,21 +532,10 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
459 struct snd_soc_platform *platform = rtd->platform; 532 struct snd_soc_platform *platform = rtd->platform;
460 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 533 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
461 struct snd_soc_dai *codec_dai = rtd->codec_dai; 534 struct snd_soc_dai *codec_dai = rtd->codec_dai;
462 struct snd_soc_codec *codec = rtd->codec;
463 535
464 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 536 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
465 537
466 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 538 snd_soc_runtime_deactivate(rtd, substream->stream);
467 cpu_dai->playback_active--;
468 codec_dai->playback_active--;
469 } else {
470 cpu_dai->capture_active--;
471 codec_dai->capture_active--;
472 }
473
474 cpu_dai->active--;
475 codec_dai->active--;
476 codec->active--;
477 539
478 /* clear the corresponding DAIs rate when inactive */ 540 /* clear the corresponding DAIs rate when inactive */
479 if (!cpu_dai->active) 541 if (!cpu_dai->active)
@@ -496,8 +558,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
496 cpu_dai->runtime = NULL; 558 cpu_dai->runtime = NULL;
497 559
498 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 560 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
499 if (!rtd->pmdown_time || codec->ignore_pmdown_time || 561 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
500 rtd->dai_link->ignore_pmdown_time) {
501 /* powered down playback stream now */ 562 /* powered down playback stream now */
502 snd_soc_dapm_stream_event(rtd, 563 snd_soc_dapm_stream_event(rtd,
503 SNDRV_PCM_STREAM_PLAYBACK, 564 SNDRV_PCM_STREAM_PLAYBACK,
@@ -1989,6 +2050,7 @@ int soc_dpcm_runtime_update(struct snd_soc_card *card)
1989 2050
1990 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); 2051 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list);
1991 if (paths < 0) { 2052 if (paths < 0) {
2053 dpcm_path_put(&list);
1992 dev_warn(fe->dev, "ASoC: %s no valid %s path\n", 2054 dev_warn(fe->dev, "ASoC: %s no valid %s path\n",
1993 fe->dai_link->name, "playback"); 2055 fe->dai_link->name, "playback");
1994 mutex_unlock(&card->mutex); 2056 mutex_unlock(&card->mutex);
@@ -2018,6 +2080,7 @@ capture:
2018 2080
2019 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); 2081 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list);
2020 if (paths < 0) { 2082 if (paths < 0) {
2083 dpcm_path_put(&list);
2021 dev_warn(fe->dev, "ASoC: %s no valid %s path\n", 2084 dev_warn(fe->dev, "ASoC: %s no valid %s path\n",
2022 fe->dai_link->name, "capture"); 2085 fe->dai_link->name, "capture");
2023 mutex_unlock(&card->mutex); 2086 mutex_unlock(&card->mutex);
@@ -2082,6 +2145,7 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream)
2082 fe->dpcm[stream].runtime = fe_substream->runtime; 2145 fe->dpcm[stream].runtime = fe_substream->runtime;
2083 2146
2084 if (dpcm_path_get(fe, stream, &list) <= 0) { 2147 if (dpcm_path_get(fe, stream, &list) <= 0) {
2148 dpcm_path_put(&list);
2085 dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", 2149 dev_dbg(fe->dev, "ASoC: %s no valid %s route\n",
2086 fe->dai_link->name, stream ? "capture" : "playback"); 2150 fe->dai_link->name, stream ? "capture" : "playback");
2087 } 2151 }
diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c
index fe99f461aff0..19cca043e6e4 100644
--- a/sound/soc/spear/spdif_out.c
+++ b/sound/soc/spear/spdif_out.c
@@ -213,10 +213,7 @@ static int spdif_digital_mute(struct snd_soc_dai *dai, int mute)
213static int spdif_mute_get(struct snd_kcontrol *kcontrol, 213static int spdif_mute_get(struct snd_kcontrol *kcontrol,
214 struct snd_ctl_elem_value *ucontrol) 214 struct snd_ctl_elem_value *ucontrol)
215{ 215{
216 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 216 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
217 struct snd_soc_card *card = codec->card;
218 struct snd_soc_pcm_runtime *rtd = card->rtd;
219 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
220 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai); 217 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
221 218
222 ucontrol->value.integer.value[0] = host->saved_params.mute; 219 ucontrol->value.integer.value[0] = host->saved_params.mute;
@@ -226,10 +223,7 @@ static int spdif_mute_get(struct snd_kcontrol *kcontrol,
226static int spdif_mute_put(struct snd_kcontrol *kcontrol, 223static int spdif_mute_put(struct snd_kcontrol *kcontrol,
227 struct snd_ctl_elem_value *ucontrol) 224 struct snd_ctl_elem_value *ucontrol)
228{ 225{
229 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 226 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
230 struct snd_soc_card *card = codec->card;
231 struct snd_soc_pcm_runtime *rtd = card->rtd;
232 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
233 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai); 227 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
234 228
235 if (host->saved_params.mute == ucontrol->value.integer.value[0]) 229 if (host->saved_params.mute == ucontrol->value.integer.value[0])
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 9f9c1856f822..31198cf7f88d 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -105,7 +105,7 @@ config SND_SOC_TEGRA_TRIMSLICE
105 tristate "SoC Audio support for TrimSlice board" 105 tristate "SoC Audio support for TrimSlice board"
106 depends on SND_SOC_TEGRA && I2C 106 depends on SND_SOC_TEGRA && I2C
107 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC 107 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
108 select SND_SOC_TLV320AIC23 108 select SND_SOC_TLV320AIC23_I2C
109 help 109 help
110 Say Y or M here if you want to add support for SoC audio on the 110 Say Y or M here if you want to add support for SoC audio on the
111 TrimSlice platform. 111 TrimSlice platform.
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index e0305a148568..9edd68db9f48 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -183,14 +183,16 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
183 irq = platform_get_irq(pdev, 0); 183 irq = platform_get_irq(pdev, 0);
184 if (irq < 0) 184 if (irq < 0)
185 return irq; 185 return irq;
186
187 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
188 if (!drvdata)
189 return -ENOMEM;
190
186 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 191 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
187 drvdata->base = devm_ioremap_resource(&pdev->dev, r); 192 drvdata->base = devm_ioremap_resource(&pdev->dev, r);
188 if (IS_ERR(drvdata->base)) 193 if (IS_ERR(drvdata->base))
189 return PTR_ERR(drvdata->base); 194 return PTR_ERR(drvdata->base);
190 195
191 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
192 if (!drvdata)
193 return -ENOMEM;
194 platform_set_drvdata(pdev, drvdata); 196 platform_set_drvdata(pdev, drvdata);
195 drvdata->physbase = r->start; 197 drvdata->physbase = r->start;
196 if (sizeof(drvdata->physbase) > sizeof(r->start) && 198 if (sizeof(drvdata->physbase) > sizeof(r->start) &&
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index de9408b83f75..e05a86b7c0da 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -14,6 +14,7 @@ config SND_USB_AUDIO
14 select SND_HWDEP 14 select SND_HWDEP
15 select SND_RAWMIDI 15 select SND_RAWMIDI
16 select SND_PCM 16 select SND_PCM
17 select BITREVERSE
17 help 18 help
18 Say Y here to include support for USB audio and USB MIDI 19 Say Y here to include support for USB audio and USB MIDI
19 devices. 20 devices.
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 44b0ba4feab3..1bed780e21d9 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -883,6 +883,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
883 } 883 }
884 break; 884 break;
885 885
886 case USB_ID(0x046d, 0x0807): /* Logitech Webcam C500 */
886 case USB_ID(0x046d, 0x0808): 887 case USB_ID(0x046d, 0x0808):
887 case USB_ID(0x046d, 0x0809): 888 case USB_ID(0x046d, 0x0809):
888 case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ 889 case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c
index 32af6b741ef5..d1d72ff50347 100644
--- a/sound/usb/mixer_maps.c
+++ b/sound/usb/mixer_maps.c
@@ -328,6 +328,11 @@ static struct usbmix_name_map gamecom780_map[] = {
328 {} 328 {}
329}; 329};
330 330
331static const struct usbmix_name_map kef_x300a_map[] = {
332 { 10, NULL }, /* firmware locks up (?) when we try to access this FU */
333 { 0 }
334};
335
331/* 336/*
332 * Control map entries 337 * Control map entries
333 */ 338 */
@@ -419,6 +424,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
419 .id = USB_ID(0x200c, 0x1018), 424 .id = USB_ID(0x200c, 0x1018),
420 .map = ebox44_map, 425 .map = ebox44_map,
421 }, 426 },
427 {
428 .id = USB_ID(0x27ac, 0x1000),
429 .map = kef_x300a_map,
430 },
422 { 0 } /* terminator */ 431 { 0 } /* terminator */
423}; 432};
424 433