aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_codec.c4
-rw-r--r--sound/pci/hda/hda_eld.c2
-rw-r--r--sound/pci/hda/hda_generic.c48
-rw-r--r--sound/pci/hda/hda_intel.c138
-rw-r--r--sound/pci/hda/patch_cirrus.c4
-rw-r--r--sound/pci/hda/patch_conexant.c16
-rw-r--r--sound/pci/hda/patch_hdmi.c2
-rw-r--r--sound/pci/hda/patch_realtek.c4
-rw-r--r--sound/soc/atmel/atmel-pcm-dma.c25
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c54
-rw-r--r--sound/soc/au1x/ac97c.c9
-rw-r--r--sound/soc/au1x/i2sc.c9
-rw-r--r--sound/soc/au1x/psc-ac97.c9
-rw-r--r--sound/soc/au1x/psc-i2s.c9
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c9
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c9
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c9
-rw-r--r--sound/soc/blackfin/bf6xx-i2s.c9
-rw-r--r--sound/soc/cirrus/edb93xx.c1
-rw-r--r--sound/soc/cirrus/ep93xx-ac97.c18
-rw-r--r--sound/soc/cirrus/ep93xx-i2s.c25
-rw-r--r--sound/soc/cirrus/ep93xx-pcm.c37
-rw-r--r--sound/soc/cirrus/ep93xx-pcm.h20
-rw-r--r--sound/soc/cirrus/simone.c2
-rw-r--r--sound/soc/cirrus/snappercl15.c1
-rw-r--r--sound/soc/codecs/Kconfig6
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/adau1373.c5
-rw-r--r--sound/soc/codecs/ak4104.c55
-rw-r--r--sound/soc/codecs/ak5386.c152
-rw-r--r--sound/soc/codecs/arizona.c530
-rw-r--r--sound/soc/codecs/arizona.h34
-rw-r--r--sound/soc/codecs/cs4271.c166
-rw-r--r--sound/soc/codecs/cs42l73.c6
-rw-r--r--sound/soc/codecs/max98088.c30
-rw-r--r--[-rwxr-xr-x]sound/soc/codecs/max98090.c45
-rw-r--r--[-rwxr-xr-x]sound/soc/codecs/max98090.h0
-rw-r--r--sound/soc/codecs/si476x.c48
-rw-r--r--sound/soc/codecs/wm2200.c2
-rw-r--r--sound/soc/codecs/wm5102.c131
-rw-r--r--sound/soc/codecs/wm5102.h6
-rw-r--r--sound/soc/codecs/wm5110.c54
-rw-r--r--sound/soc/codecs/wm5110.h6
-rw-r--r--sound/soc/codecs/wm8903.c2
-rw-r--r--sound/soc/codecs/wm_adsp.c129
-rw-r--r--sound/soc/codecs/wm_adsp.h5
-rw-r--r--sound/soc/davinci/davinci-i2s.c15
-rw-r--r--sound/soc/davinci/davinci-mcasp.c97
-rw-r--r--sound/soc/davinci/davinci-pcm.c16
-rw-r--r--sound/soc/davinci/davinci-pcm.h1
-rw-r--r--sound/soc/davinci/davinci-vcif.c11
-rw-r--r--sound/soc/dwc/designware_i2s.c9
-rw-r--r--sound/soc/fsl/fsl_ssi.c45
-rw-r--r--sound/soc/fsl/imx-audmux.c3
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c58
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c6
-rw-r--r--sound/soc/fsl/imx-pcm.h19
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c2
-rw-r--r--sound/soc/fsl/imx-ssi.c47
-rw-r--r--sound/soc/fsl/imx-ssi.h7
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c8
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c9
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c2
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c9
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c11
-rw-r--r--sound/soc/mid-x86/sst_platform.c20
-rw-r--r--sound/soc/mid-x86/sst_platform.h2
-rw-r--r--sound/soc/mxs/mxs-pcm.c43
-rw-r--r--sound/soc/mxs/mxs-pcm.h4
-rw-r--r--sound/soc/mxs/mxs-saif.c17
-rw-r--r--sound/soc/nuc900/nuc900-ac97.c9
-rw-r--r--sound/soc/omap/am3517evm.c1
-rw-r--r--sound/soc/omap/ams-delta.c1
-rw-r--r--sound/soc/omap/mcbsp.c14
-rw-r--r--sound/soc/omap/mcbsp.h7
-rw-r--r--sound/soc/omap/n810.c1
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c1
-rw-r--r--sound/soc/omap/omap-dmic.c47
-rw-r--r--sound/soc/omap/omap-hdmi.c33
-rw-r--r--sound/soc/omap/omap-mcbsp.c27
-rw-r--r--sound/soc/omap/omap-mcpdm.c118
-rw-r--r--sound/soc/omap/omap-pcm.c83
-rw-r--r--sound/soc/omap/omap-pcm.h40
-rw-r--r--sound/soc/omap/omap-twl4030.c1
-rw-r--r--sound/soc/omap/omap3pandora.c9
-rw-r--r--sound/soc/omap/osk5912.c1
-rw-r--r--sound/soc/omap/rx51.c1
-rw-r--r--sound/soc/pxa/mmp-pcm.c33
-rw-r--r--sound/soc/pxa/mmp-sspa.c9
-rw-r--r--sound/soc/pxa/pxa-ssp.c9
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c11
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c9
-rw-r--r--sound/soc/s6000/s6000-i2s.c9
-rw-r--r--sound/soc/samsung/Kconfig5
-rw-r--r--sound/soc/samsung/ac97.c14
-rw-r--r--sound/soc/samsung/goni_wm8994.c11
-rw-r--r--sound/soc/samsung/h1940_uda1380.c2
-rw-r--r--sound/soc/samsung/i2s.c33
-rw-r--r--sound/soc/samsung/idma.c11
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c3
-rw-r--r--sound/soc/samsung/pcm.c11
-rw-r--r--sound/soc/samsung/regs-ac97.h67
-rw-r--r--sound/soc/samsung/regs-iis.h70
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c2
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c9
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.h7
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c12
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c13
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c2
-rw-r--r--sound/soc/samsung/spdif.c11
-rw-r--r--sound/soc/sh/dma-sh7760.c4
-rw-r--r--sound/soc/sh/fsi.c14
-rw-r--r--sound/soc/sh/hac.c10
-rw-r--r--sound/soc/sh/migor.c2
-rw-r--r--sound/soc/sh/siu_dai.c11
-rw-r--r--sound/soc/sh/ssi.c10
-rw-r--r--sound/soc/soc-compress.c41
-rw-r--r--sound/soc/soc-core.c138
-rw-r--r--sound/soc/soc-dapm.c334
-rw-r--r--sound/soc/soc-dmaengine-pcm.c68
-rw-r--r--sound/soc/soc-io.c5
-rw-r--r--sound/soc/spear/spdif_in.c9
-rw-r--r--sound/soc/spear/spdif_out.c9
-rw-r--r--sound/soc/spear/spear_pcm.c30
-rw-r--r--sound/soc/tegra/tegra20_ac97.c28
-rw-r--r--sound/soc/tegra/tegra20_ac97.h4
-rw-r--r--sound/soc/tegra/tegra20_i2s.c28
-rw-r--r--sound/soc/tegra/tegra20_i2s.h4
-rw-r--r--sound/soc/tegra/tegra20_spdif.c22
-rw-r--r--sound/soc/tegra/tegra20_spdif.h4
-rw-r--r--sound/soc/tegra/tegra30_ahub.c8
-rw-r--r--sound/soc/tegra/tegra30_ahub.h8
-rw-r--r--sound/soc/tegra/tegra30_i2s.c28
-rw-r--r--sound/soc/tegra/tegra30_i2s.h4
-rw-r--r--sound/soc/tegra/tegra_pcm.c48
-rw-r--r--sound/soc/tegra/tegra_pcm.h7
-rw-r--r--sound/soc/tegra/tegra_wm9712.c2
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c9
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c13
-rw-r--r--sound/soc/ux500/ux500_pcm.c76
-rw-r--r--sound/soc/ux500/ux500_pcm.h14
-rw-r--r--sound/usb/clock.c45
-rw-r--r--sound/usb/mixer.c21
143 files changed, 2713 insertions, 1450 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index a9ebcf9e3710..4aba7646dd9c 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -173,7 +173,7 @@ const char *snd_hda_get_jack_type(u32 cfg)
173 "Line Out", "Speaker", "HP Out", "CD", 173 "Line Out", "Speaker", "HP Out", "CD",
174 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand", 174 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
175 "Line In", "Aux", "Mic", "Telephony", 175 "Line In", "Aux", "Mic", "Telephony",
176 "SPDIF In", "Digitial In", "Reserved", "Other" 176 "SPDIF In", "Digital In", "Reserved", "Other"
177 }; 177 };
178 178
179 return jack_types[(cfg & AC_DEFCFG_DEVICE) 179 return jack_types[(cfg & AC_DEFCFG_DEVICE)
@@ -3144,7 +3144,7 @@ static unsigned int convert_to_spdif_status(unsigned short val)
3144 if (val & AC_DIG1_PROFESSIONAL) 3144 if (val & AC_DIG1_PROFESSIONAL)
3145 sbits |= IEC958_AES0_PROFESSIONAL; 3145 sbits |= IEC958_AES0_PROFESSIONAL;
3146 if (sbits & IEC958_AES0_PROFESSIONAL) { 3146 if (sbits & IEC958_AES0_PROFESSIONAL) {
3147 if (sbits & AC_DIG1_EMPHASIS) 3147 if (val & AC_DIG1_EMPHASIS)
3148 sbits |= IEC958_AES0_PRO_EMPHASIS_5015; 3148 sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
3149 } else { 3149 } else {
3150 if (val & AC_DIG1_EMPHASIS) 3150 if (val & AC_DIG1_EMPHASIS)
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 7dd846380a50..d0d7ac1e99d2 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -320,7 +320,7 @@ int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid,
320 unsigned char *buf, int *eld_size) 320 unsigned char *buf, int *eld_size)
321{ 321{
322 int i; 322 int i;
323 int ret; 323 int ret = 0;
324 int size; 324 int size;
325 325
326 /* 326 /*
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 78897d05d80f..2dbe767be16b 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -740,7 +740,7 @@ EXPORT_SYMBOL_HDA(snd_hda_activate_path);
740static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path) 740static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path)
741{ 741{
742 struct hda_gen_spec *spec = codec->spec; 742 struct hda_gen_spec *spec = codec->spec;
743 bool changed; 743 bool changed = false;
744 int i; 744 int i;
745 745
746 if (!spec->power_down_unused || path->active) 746 if (!spec->power_down_unused || path->active)
@@ -995,6 +995,8 @@ enum {
995 BAD_NO_EXTRA_SURR_DAC = 0x101, 995 BAD_NO_EXTRA_SURR_DAC = 0x101,
996 /* Primary DAC shared with main surrounds */ 996 /* Primary DAC shared with main surrounds */
997 BAD_SHARED_SURROUND = 0x100, 997 BAD_SHARED_SURROUND = 0x100,
998 /* No independent HP possible */
999 BAD_NO_INDEP_HP = 0x40,
998 /* Primary DAC shared with main CLFE */ 1000 /* Primary DAC shared with main CLFE */
999 BAD_SHARED_CLFE = 0x10, 1001 BAD_SHARED_CLFE = 0x10,
1000 /* Primary DAC shared with extra surrounds */ 1002 /* Primary DAC shared with extra surrounds */
@@ -1392,6 +1394,43 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx)
1392 return snd_hda_get_path_idx(codec, path); 1394 return snd_hda_get_path_idx(codec, path);
1393} 1395}
1394 1396
1397/* check whether the independent HP is available with the current config */
1398static bool indep_hp_possible(struct hda_codec *codec)
1399{
1400 struct hda_gen_spec *spec = codec->spec;
1401 struct auto_pin_cfg *cfg = &spec->autocfg;
1402 struct nid_path *path;
1403 int i, idx;
1404
1405 if (cfg->line_out_type == AUTO_PIN_HP_OUT)
1406 idx = spec->out_paths[0];
1407 else
1408 idx = spec->hp_paths[0];
1409 path = snd_hda_get_path_from_idx(codec, idx);
1410 if (!path)
1411 return false;
1412
1413 /* assume no path conflicts unless aamix is involved */
1414 if (!spec->mixer_nid || !is_nid_contained(path, spec->mixer_nid))
1415 return true;
1416
1417 /* check whether output paths contain aamix */
1418 for (i = 0; i < cfg->line_outs; i++) {
1419 if (spec->out_paths[i] == idx)
1420 break;
1421 path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]);
1422 if (path && is_nid_contained(path, spec->mixer_nid))
1423 return false;
1424 }
1425 for (i = 0; i < cfg->speaker_outs; i++) {
1426 path = snd_hda_get_path_from_idx(codec, spec->speaker_paths[i]);
1427 if (path && is_nid_contained(path, spec->mixer_nid))
1428 return false;
1429 }
1430
1431 return true;
1432}
1433
1395/* fill the empty entries in the dac array for speaker/hp with the 1434/* fill the empty entries in the dac array for speaker/hp with the
1396 * shared dac pointed by the paths 1435 * shared dac pointed by the paths
1397 */ 1436 */
@@ -1545,6 +1584,9 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1545 badness += BAD_MULTI_IO; 1584 badness += BAD_MULTI_IO;
1546 } 1585 }
1547 1586
1587 if (spec->indep_hp && !indep_hp_possible(codec))
1588 badness += BAD_NO_INDEP_HP;
1589
1548 /* re-fill the shared DAC for speaker / headphone */ 1590 /* re-fill the shared DAC for speaker / headphone */
1549 if (cfg->line_out_type != AUTO_PIN_HP_OUT) 1591 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1550 refill_shared_dacs(codec, cfg->hp_outs, 1592 refill_shared_dacs(codec, cfg->hp_outs,
@@ -1758,6 +1800,10 @@ static int parse_output_paths(struct hda_codec *codec)
1758 cfg->speaker_pins, val); 1800 cfg->speaker_pins, val);
1759 } 1801 }
1760 1802
1803 /* clear indep_hp flag if not available */
1804 if (spec->indep_hp && !indep_hp_possible(codec))
1805 spec->indep_hp = 0;
1806
1761 kfree(best_cfg); 1807 kfree(best_cfg);
1762 return 0; 1808 return 0;
1763} 1809}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 4cea6bb6fade..bcd40ee488e3 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -134,8 +134,8 @@ MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
134 * this may give more power-saving, but will take longer time to 134 * this may give more power-saving, but will take longer time to
135 * wake up. 135 * wake up.
136 */ 136 */
137static int power_save_controller = -1; 137static bool power_save_controller = 1;
138module_param(power_save_controller, bint, 0644); 138module_param(power_save_controller, bool, 0644);
139MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); 139MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
140#endif /* CONFIG_PM */ 140#endif /* CONFIG_PM */
141 141
@@ -415,6 +415,8 @@ struct azx_dev {
415 unsigned int opened :1; 415 unsigned int opened :1;
416 unsigned int running :1; 416 unsigned int running :1;
417 unsigned int irq_pending :1; 417 unsigned int irq_pending :1;
418 unsigned int prepared:1;
419 unsigned int locked:1;
418 /* 420 /*
419 * For VIA: 421 * For VIA:
420 * A flag to ensure DMA position is 0 422 * A flag to ensure DMA position is 0
@@ -426,8 +428,25 @@ struct azx_dev {
426 428
427 struct timecounter azx_tc; 429 struct timecounter azx_tc;
428 struct cyclecounter azx_cc; 430 struct cyclecounter azx_cc;
431
432#ifdef CONFIG_SND_HDA_DSP_LOADER
433 struct mutex dsp_mutex;
434#endif
429}; 435};
430 436
437/* DSP lock helpers */
438#ifdef CONFIG_SND_HDA_DSP_LOADER
439#define dsp_lock_init(dev) mutex_init(&(dev)->dsp_mutex)
440#define dsp_lock(dev) mutex_lock(&(dev)->dsp_mutex)
441#define dsp_unlock(dev) mutex_unlock(&(dev)->dsp_mutex)
442#define dsp_is_locked(dev) ((dev)->locked)
443#else
444#define dsp_lock_init(dev) do {} while (0)
445#define dsp_lock(dev) do {} while (0)
446#define dsp_unlock(dev) do {} while (0)
447#define dsp_is_locked(dev) 0
448#endif
449
431/* CORB/RIRB */ 450/* CORB/RIRB */
432struct azx_rb { 451struct azx_rb {
433 u32 *buf; /* CORB/RIRB buffer 452 u32 *buf; /* CORB/RIRB buffer
@@ -527,6 +546,10 @@ struct azx {
527 546
528 /* card list (for power_save trigger) */ 547 /* card list (for power_save trigger) */
529 struct list_head list; 548 struct list_head list;
549
550#ifdef CONFIG_SND_HDA_DSP_LOADER
551 struct azx_dev saved_azx_dev;
552#endif
530}; 553};
531 554
532#define CREATE_TRACE_POINTS 555#define CREATE_TRACE_POINTS
@@ -1793,15 +1816,25 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
1793 dev = chip->capture_index_offset; 1816 dev = chip->capture_index_offset;
1794 nums = chip->capture_streams; 1817 nums = chip->capture_streams;
1795 } 1818 }
1796 for (i = 0; i < nums; i++, dev++) 1819 for (i = 0; i < nums; i++, dev++) {
1797 if (!chip->azx_dev[dev].opened) { 1820 struct azx_dev *azx_dev = &chip->azx_dev[dev];
1798 res = &chip->azx_dev[dev]; 1821 dsp_lock(azx_dev);
1799 if (res->assigned_key == key) 1822 if (!azx_dev->opened && !dsp_is_locked(azx_dev)) {
1800 break; 1823 res = azx_dev;
1824 if (res->assigned_key == key) {
1825 res->opened = 1;
1826 res->assigned_key = key;
1827 dsp_unlock(azx_dev);
1828 return azx_dev;
1829 }
1801 } 1830 }
1831 dsp_unlock(azx_dev);
1832 }
1802 if (res) { 1833 if (res) {
1834 dsp_lock(res);
1803 res->opened = 1; 1835 res->opened = 1;
1804 res->assigned_key = key; 1836 res->assigned_key = key;
1837 dsp_unlock(res);
1805 } 1838 }
1806 return res; 1839 return res;
1807} 1840}
@@ -2009,6 +2042,12 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
2009 struct azx_dev *azx_dev = get_azx_dev(substream); 2042 struct azx_dev *azx_dev = get_azx_dev(substream);
2010 int ret; 2043 int ret;
2011 2044
2045 dsp_lock(azx_dev);
2046 if (dsp_is_locked(azx_dev)) {
2047 ret = -EBUSY;
2048 goto unlock;
2049 }
2050
2012 mark_runtime_wc(chip, azx_dev, substream, false); 2051 mark_runtime_wc(chip, azx_dev, substream, false);
2013 azx_dev->bufsize = 0; 2052 azx_dev->bufsize = 0;
2014 azx_dev->period_bytes = 0; 2053 azx_dev->period_bytes = 0;
@@ -2016,8 +2055,10 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
2016 ret = snd_pcm_lib_malloc_pages(substream, 2055 ret = snd_pcm_lib_malloc_pages(substream,
2017 params_buffer_bytes(hw_params)); 2056 params_buffer_bytes(hw_params));
2018 if (ret < 0) 2057 if (ret < 0)
2019 return ret; 2058 goto unlock;
2020 mark_runtime_wc(chip, azx_dev, substream, true); 2059 mark_runtime_wc(chip, azx_dev, substream, true);
2060 unlock:
2061 dsp_unlock(azx_dev);
2021 return ret; 2062 return ret;
2022} 2063}
2023 2064
@@ -2029,16 +2070,21 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
2029 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; 2070 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
2030 2071
2031 /* reset BDL address */ 2072 /* reset BDL address */
2032 azx_sd_writel(azx_dev, SD_BDLPL, 0); 2073 dsp_lock(azx_dev);
2033 azx_sd_writel(azx_dev, SD_BDLPU, 0); 2074 if (!dsp_is_locked(azx_dev)) {
2034 azx_sd_writel(azx_dev, SD_CTL, 0); 2075 azx_sd_writel(azx_dev, SD_BDLPL, 0);
2035 azx_dev->bufsize = 0; 2076 azx_sd_writel(azx_dev, SD_BDLPU, 0);
2036 azx_dev->period_bytes = 0; 2077 azx_sd_writel(azx_dev, SD_CTL, 0);
2037 azx_dev->format_val = 0; 2078 azx_dev->bufsize = 0;
2079 azx_dev->period_bytes = 0;
2080 azx_dev->format_val = 0;
2081 }
2038 2082
2039 snd_hda_codec_cleanup(apcm->codec, hinfo, substream); 2083 snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
2040 2084
2041 mark_runtime_wc(chip, azx_dev, substream, false); 2085 mark_runtime_wc(chip, azx_dev, substream, false);
2086 azx_dev->prepared = 0;
2087 dsp_unlock(azx_dev);
2042 return snd_pcm_lib_free_pages(substream); 2088 return snd_pcm_lib_free_pages(substream);
2043} 2089}
2044 2090
@@ -2055,6 +2101,12 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
2055 snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid); 2101 snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
2056 unsigned short ctls = spdif ? spdif->ctls : 0; 2102 unsigned short ctls = spdif ? spdif->ctls : 0;
2057 2103
2104 dsp_lock(azx_dev);
2105 if (dsp_is_locked(azx_dev)) {
2106 err = -EBUSY;
2107 goto unlock;
2108 }
2109
2058 azx_stream_reset(chip, azx_dev); 2110 azx_stream_reset(chip, azx_dev);
2059 format_val = snd_hda_calc_stream_format(runtime->rate, 2111 format_val = snd_hda_calc_stream_format(runtime->rate,
2060 runtime->channels, 2112 runtime->channels,
@@ -2065,7 +2117,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
2065 snd_printk(KERN_ERR SFX 2117 snd_printk(KERN_ERR SFX
2066 "%s: invalid format_val, rate=%d, ch=%d, format=%d\n", 2118 "%s: invalid format_val, rate=%d, ch=%d, format=%d\n",
2067 pci_name(chip->pci), runtime->rate, runtime->channels, runtime->format); 2119 pci_name(chip->pci), runtime->rate, runtime->channels, runtime->format);
2068 return -EINVAL; 2120 err = -EINVAL;
2121 goto unlock;
2069 } 2122 }
2070 2123
2071 bufsize = snd_pcm_lib_buffer_bytes(substream); 2124 bufsize = snd_pcm_lib_buffer_bytes(substream);
@@ -2084,7 +2137,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
2084 azx_dev->no_period_wakeup = runtime->no_period_wakeup; 2137 azx_dev->no_period_wakeup = runtime->no_period_wakeup;
2085 err = azx_setup_periods(chip, substream, azx_dev); 2138 err = azx_setup_periods(chip, substream, azx_dev);
2086 if (err < 0) 2139 if (err < 0)
2087 return err; 2140 goto unlock;
2088 } 2141 }
2089 2142
2090 /* wallclk has 24Mhz clock source */ 2143 /* wallclk has 24Mhz clock source */
@@ -2101,8 +2154,14 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
2101 if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) && 2154 if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) &&
2102 stream_tag > chip->capture_streams) 2155 stream_tag > chip->capture_streams)
2103 stream_tag -= chip->capture_streams; 2156 stream_tag -= chip->capture_streams;
2104 return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag, 2157 err = snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
2105 azx_dev->format_val, substream); 2158 azx_dev->format_val, substream);
2159
2160 unlock:
2161 if (!err)
2162 azx_dev->prepared = 1;
2163 dsp_unlock(azx_dev);
2164 return err;
2106} 2165}
2107 2166
2108static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 2167static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -2117,6 +2176,9 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
2117 azx_dev = get_azx_dev(substream); 2176 azx_dev = get_azx_dev(substream);
2118 trace_azx_pcm_trigger(chip, azx_dev, cmd); 2177 trace_azx_pcm_trigger(chip, azx_dev, cmd);
2119 2178
2179 if (dsp_is_locked(azx_dev) || !azx_dev->prepared)
2180 return -EPIPE;
2181
2120 switch (cmd) { 2182 switch (cmd) {
2121 case SNDRV_PCM_TRIGGER_START: 2183 case SNDRV_PCM_TRIGGER_START:
2122 rstart = 1; 2184 rstart = 1;
@@ -2621,17 +2683,27 @@ static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
2621 struct azx_dev *azx_dev; 2683 struct azx_dev *azx_dev;
2622 int err; 2684 int err;
2623 2685
2624 if (snd_hda_lock_devices(bus)) 2686 azx_dev = azx_get_dsp_loader_dev(chip);
2625 return -EBUSY; 2687
2688 dsp_lock(azx_dev);
2689 spin_lock_irq(&chip->reg_lock);
2690 if (azx_dev->running || azx_dev->locked) {
2691 spin_unlock_irq(&chip->reg_lock);
2692 err = -EBUSY;
2693 goto unlock;
2694 }
2695 azx_dev->prepared = 0;
2696 chip->saved_azx_dev = *azx_dev;
2697 azx_dev->locked = 1;
2698 spin_unlock_irq(&chip->reg_lock);
2626 2699
2627 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, 2700 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG,
2628 snd_dma_pci_data(chip->pci), 2701 snd_dma_pci_data(chip->pci),
2629 byte_size, bufp); 2702 byte_size, bufp);
2630 if (err < 0) 2703 if (err < 0)
2631 goto unlock; 2704 goto err_alloc;
2632 2705
2633 mark_pages_wc(chip, bufp, true); 2706 mark_pages_wc(chip, bufp, true);
2634 azx_dev = azx_get_dsp_loader_dev(chip);
2635 azx_dev->bufsize = byte_size; 2707 azx_dev->bufsize = byte_size;
2636 azx_dev->period_bytes = byte_size; 2708 azx_dev->period_bytes = byte_size;
2637 azx_dev->format_val = format; 2709 azx_dev->format_val = format;
@@ -2649,13 +2721,20 @@ static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
2649 goto error; 2721 goto error;
2650 2722
2651 azx_setup_controller(chip, azx_dev); 2723 azx_setup_controller(chip, azx_dev);
2724 dsp_unlock(azx_dev);
2652 return azx_dev->stream_tag; 2725 return azx_dev->stream_tag;
2653 2726
2654 error: 2727 error:
2655 mark_pages_wc(chip, bufp, false); 2728 mark_pages_wc(chip, bufp, false);
2656 snd_dma_free_pages(bufp); 2729 snd_dma_free_pages(bufp);
2657unlock: 2730 err_alloc:
2658 snd_hda_unlock_devices(bus); 2731 spin_lock_irq(&chip->reg_lock);
2732 if (azx_dev->opened)
2733 *azx_dev = chip->saved_azx_dev;
2734 azx_dev->locked = 0;
2735 spin_unlock_irq(&chip->reg_lock);
2736 unlock:
2737 dsp_unlock(azx_dev);
2659 return err; 2738 return err;
2660} 2739}
2661 2740
@@ -2677,9 +2756,10 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus,
2677 struct azx *chip = bus->private_data; 2756 struct azx *chip = bus->private_data;
2678 struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip); 2757 struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
2679 2758
2680 if (!dmab->area) 2759 if (!dmab->area || !azx_dev->locked)
2681 return; 2760 return;
2682 2761
2762 dsp_lock(azx_dev);
2683 /* reset BDL address */ 2763 /* reset BDL address */
2684 azx_sd_writel(azx_dev, SD_BDLPL, 0); 2764 azx_sd_writel(azx_dev, SD_BDLPL, 0);
2685 azx_sd_writel(azx_dev, SD_BDLPU, 0); 2765 azx_sd_writel(azx_dev, SD_BDLPU, 0);
@@ -2692,7 +2772,12 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus,
2692 snd_dma_free_pages(dmab); 2772 snd_dma_free_pages(dmab);
2693 dmab->area = NULL; 2773 dmab->area = NULL;
2694 2774
2695 snd_hda_unlock_devices(bus); 2775 spin_lock_irq(&chip->reg_lock);
2776 if (azx_dev->opened)
2777 *azx_dev = chip->saved_azx_dev;
2778 azx_dev->locked = 0;
2779 spin_unlock_irq(&chip->reg_lock);
2780 dsp_unlock(azx_dev);
2696} 2781}
2697#endif /* CONFIG_SND_HDA_DSP_LOADER */ 2782#endif /* CONFIG_SND_HDA_DSP_LOADER */
2698 2783
@@ -2846,8 +2931,6 @@ static int azx_runtime_idle(struct device *dev)
2846 struct snd_card *card = dev_get_drvdata(dev); 2931 struct snd_card *card = dev_get_drvdata(dev);
2847 struct azx *chip = card->private_data; 2932 struct azx *chip = card->private_data;
2848 2933
2849 if (power_save_controller > 0)
2850 return 0;
2851 if (!power_save_controller || 2934 if (!power_save_controller ||
2852 !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) 2935 !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
2853 return -EBUSY; 2936 return -EBUSY;
@@ -3481,6 +3564,7 @@ static int azx_first_init(struct azx *chip)
3481 } 3564 }
3482 3565
3483 for (i = 0; i < chip->num_streams; i++) { 3566 for (i = 0; i < chip->num_streams; i++) {
3567 dsp_lock_init(&chip->azx_dev[i]);
3484 /* allocate memory for the BDL for each stream */ 3568 /* allocate memory for the BDL for each stream */
3485 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, 3569 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
3486 snd_dma_pci_data(chip->pci), 3570 snd_dma_pci_data(chip->pci),
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 60d08f669f0c..0d9c58f13560 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -168,10 +168,10 @@ static void cs_automute(struct hda_codec *codec)
168 snd_hda_gen_update_outputs(codec); 168 snd_hda_gen_update_outputs(codec);
169 169
170 if (spec->gpio_eapd_hp) { 170 if (spec->gpio_eapd_hp) {
171 unsigned int gpio = spec->gen.hp_jack_present ? 171 spec->gpio_data = spec->gen.hp_jack_present ?
172 spec->gpio_eapd_hp : spec->gpio_eapd_speaker; 172 spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
173 snd_hda_codec_write(codec, 0x01, 0, 173 snd_hda_codec_write(codec, 0x01, 0,
174 AC_VERB_SET_GPIO_DATA, gpio); 174 AC_VERB_SET_GPIO_DATA, spec->gpio_data);
175 } 175 }
176} 176}
177 177
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 941bf6c766ec..2a89d1eefeb6 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -1142,7 +1142,7 @@ static int patch_cxt5045(struct hda_codec *codec)
1142 } 1142 }
1143 1143
1144 if (spec->beep_amp) 1144 if (spec->beep_amp)
1145 snd_hda_attach_beep_device(codec, spec->beep_amp); 1145 snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
1146 1146
1147 return 0; 1147 return 0;
1148} 1148}
@@ -1921,7 +1921,7 @@ static int patch_cxt5051(struct hda_codec *codec)
1921 } 1921 }
1922 1922
1923 if (spec->beep_amp) 1923 if (spec->beep_amp)
1924 snd_hda_attach_beep_device(codec, spec->beep_amp); 1924 snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
1925 1925
1926 return 0; 1926 return 0;
1927} 1927}
@@ -3099,7 +3099,7 @@ static int patch_cxt5066(struct hda_codec *codec)
3099 } 3099 }
3100 3100
3101 if (spec->beep_amp) 3101 if (spec->beep_amp)
3102 snd_hda_attach_beep_device(codec, spec->beep_amp); 3102 snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
3103 3103
3104 return 0; 3104 return 0;
3105} 3105}
@@ -3191,11 +3191,17 @@ static int cx_auto_build_controls(struct hda_codec *codec)
3191 return 0; 3191 return 0;
3192} 3192}
3193 3193
3194static void cx_auto_free(struct hda_codec *codec)
3195{
3196 snd_hda_detach_beep_device(codec);
3197 snd_hda_gen_free(codec);
3198}
3199
3194static const struct hda_codec_ops cx_auto_patch_ops = { 3200static const struct hda_codec_ops cx_auto_patch_ops = {
3195 .build_controls = cx_auto_build_controls, 3201 .build_controls = cx_auto_build_controls,
3196 .build_pcms = snd_hda_gen_build_pcms, 3202 .build_pcms = snd_hda_gen_build_pcms,
3197 .init = snd_hda_gen_init, 3203 .init = snd_hda_gen_init,
3198 .free = snd_hda_gen_free, 3204 .free = cx_auto_free,
3199 .unsol_event = snd_hda_jack_unsol_event, 3205 .unsol_event = snd_hda_jack_unsol_event,
3200#ifdef CONFIG_PM 3206#ifdef CONFIG_PM
3201 .check_power_status = snd_hda_gen_check_power_status, 3207 .check_power_status = snd_hda_gen_check_power_status,
@@ -3391,7 +3397,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
3391 3397
3392 codec->patch_ops = cx_auto_patch_ops; 3398 codec->patch_ops = cx_auto_patch_ops;
3393 if (spec->beep_amp) 3399 if (spec->beep_amp)
3394 snd_hda_attach_beep_device(codec, spec->beep_amp); 3400 snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
3395 3401
3396 /* Some laptops with Conexant chips show stalls in S3 resume, 3402 /* Some laptops with Conexant chips show stalls in S3 resume,
3397 * which falls into the single-cmd mode. 3403 * which falls into the single-cmd mode.
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 78e1827d0a95..de8ac5c07fd0 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1196,7 +1196,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1196 1196
1197 _snd_printd(SND_PR_VERBOSE, 1197 _snd_printd(SND_PR_VERBOSE,
1198 "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 1198 "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
1199 codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); 1199 codec->addr, pin_nid, pin_eld->monitor_present, eld->eld_valid);
1200 1200
1201 if (eld->eld_valid) { 1201 if (eld->eld_valid) {
1202 if (snd_hdmi_get_eld(codec, pin_nid, eld->eld_buffer, 1202 if (snd_hdmi_get_eld(codec, pin_nid, eld->eld_buffer,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 563c24df4d6f..f15c36bde540 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -3440,7 +3440,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
3440 const hda_nid_t *ssids; 3440 const hda_nid_t *ssids;
3441 3441
3442 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 3442 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
3443 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 3443 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 ||
3444 codec->vendor_id == 0x10ec0671)
3444 ssids = alc663_ssids; 3445 ssids = alc663_ssids;
3445 else 3446 else
3446 ssids = alc662_ssids; 3447 ssids = alc662_ssids;
@@ -3894,6 +3895,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
3894 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 3895 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
3895 { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, 3896 { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
3896 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 3897 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
3898 { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
3897 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, 3899 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
3898 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 3900 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
3899 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 3901 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c
index 30184a4a147a..bb07989762d5 100644
--- a/sound/soc/atmel/atmel-pcm-dma.c
+++ b/sound/soc/atmel/atmel-pcm-dma.c
@@ -67,9 +67,10 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = {
67static void atmel_pcm_dma_irq(u32 ssc_sr, 67static void atmel_pcm_dma_irq(u32 ssc_sr,
68 struct snd_pcm_substream *substream) 68 struct snd_pcm_substream *substream)
69{ 69{
70 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct atmel_pcm_dma_params *prtd; 71 struct atmel_pcm_dma_params *prtd;
71 72
72 prtd = snd_dmaengine_pcm_get_data(substream); 73 prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
73 74
74 if (ssc_sr & prtd->mask->ssc_error) { 75 if (ssc_sr & prtd->mask->ssc_error) {
75 if (snd_pcm_running(substream)) 76 if (snd_pcm_running(substream))
@@ -104,15 +105,13 @@ static bool filter(struct dma_chan *chan, void *slave)
104} 105}
105 106
106static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, 107static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
107 struct snd_pcm_hw_params *params) 108 struct snd_pcm_hw_params *params, struct atmel_pcm_dma_params *prtd)
108{ 109{
109 struct atmel_pcm_dma_params *prtd;
110 struct ssc_device *ssc; 110 struct ssc_device *ssc;
111 struct dma_chan *dma_chan; 111 struct dma_chan *dma_chan;
112 struct dma_slave_config slave_config; 112 struct dma_slave_config slave_config;
113 int ret; 113 int ret;
114 114
115 prtd = snd_dmaengine_pcm_get_data(substream);
116 ssc = prtd->ssc; 115 ssc = prtd->ssc;
117 116
118 ret = snd_hwparams_to_dma_slave_config(substream, params, 117 ret = snd_hwparams_to_dma_slave_config(substream, params,
@@ -130,8 +129,6 @@ static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
130 slave_config.src_maxburst = 1; 129 slave_config.src_maxburst = 1;
131 } 130 }
132 131
133 slave_config.device_fc = false;
134
135 dma_chan = snd_dmaengine_pcm_get_chan(substream); 132 dma_chan = snd_dmaengine_pcm_get_chan(substream);
136 if (dmaengine_slave_config(dma_chan, &slave_config)) { 133 if (dmaengine_slave_config(dma_chan, &slave_config)) {
137 pr_err("atmel-pcm: failed to configure dma channel\n"); 134 pr_err("atmel-pcm: failed to configure dma channel\n");
@@ -164,9 +161,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
164 return -EINVAL; 161 return -EINVAL;
165 } 162 }
166 163
167 snd_dmaengine_pcm_set_data(substream, prtd); 164 ret = atmel_pcm_configure_dma(substream, params, prtd);
168
169 ret = atmel_pcm_configure_dma(substream, params);
170 if (ret) { 165 if (ret) {
171 pr_err("atmel-pcm: failed to configure dmai\n"); 166 pr_err("atmel-pcm: failed to configure dmai\n");
172 goto err; 167 goto err;
@@ -182,9 +177,10 @@ err:
182 177
183static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream) 178static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream)
184{ 179{
180 struct snd_soc_pcm_runtime *rtd = substream->private_data;
185 struct atmel_pcm_dma_params *prtd; 181 struct atmel_pcm_dma_params *prtd;
186 182
187 prtd = snd_dmaengine_pcm_get_data(substream); 183 prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
188 184
189 ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error); 185 ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error);
190 ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable); 186 ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable);
@@ -199,16 +195,9 @@ static int atmel_pcm_open(struct snd_pcm_substream *substream)
199 return 0; 195 return 0;
200} 196}
201 197
202static int atmel_pcm_close(struct snd_pcm_substream *substream)
203{
204 snd_dmaengine_pcm_close(substream);
205
206 return 0;
207}
208
209static struct snd_pcm_ops atmel_pcm_ops = { 198static struct snd_pcm_ops atmel_pcm_ops = {
210 .open = atmel_pcm_open, 199 .open = atmel_pcm_open,
211 .close = atmel_pcm_close, 200 .close = snd_dmaengine_pcm_close,
212 .ioctl = snd_pcm_lib_ioctl, 201 .ioctl = snd_pcm_lib_ioctl,
213 .hw_params = atmel_pcm_hw_params, 202 .hw_params = atmel_pcm_hw_params,
214 .prepare = atmel_pcm_dma_prepare, 203 .prepare = atmel_pcm_dma_prepare,
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index e13580d6c476..f3fdfa07fcb9 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -533,6 +533,49 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
533 break; 533 break;
534 534
535 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: 535 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
536 /*
537 * DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks.
538 *
539 * The SSC transmit clock is obtained from the BCLK signal on
540 * on the TK line, and the SSC receive clock is
541 * generated from the transmit clock.
542 *
543 * Data is transferred on first BCLK after LRC pulse rising
544 * edge.If stereo, the right channel data is contiguous with
545 * the left channel data.
546 */
547 rcmr = SSC_BF(RCMR_PERIOD, 0)
548 | SSC_BF(RCMR_STTDLY, START_DELAY)
549 | SSC_BF(RCMR_START, SSC_START_RISING_RF)
550 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
551 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
552 | SSC_BF(RCMR_CKS, SSC_CKS_PIN);
553
554 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
555 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
556 | SSC_BF(RFMR_FSLEN, 0)
557 | SSC_BF(RFMR_DATNB, (channels - 1))
558 | SSC_BIT(RFMR_MSBF)
559 | SSC_BF(RFMR_LOOP, 0)
560 | SSC_BF(RFMR_DATLEN, (bits - 1));
561
562 tcmr = SSC_BF(TCMR_PERIOD, 0)
563 | SSC_BF(TCMR_STTDLY, START_DELAY)
564 | SSC_BF(TCMR_START, SSC_START_RISING_RF)
565 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
566 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
567 | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
568
569 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
570 | SSC_BF(TFMR_FSDEN, 0)
571 | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
572 | SSC_BF(TFMR_FSLEN, 0)
573 | SSC_BF(TFMR_DATNB, (channels - 1))
574 | SSC_BIT(TFMR_MSBF)
575 | SSC_BF(TFMR_DATDEF, 0)
576 | SSC_BF(TFMR_DATLEN, (bits - 1));
577 break;
578
536 default: 579 default:
537 printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n", 580 printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n",
538 ssc_p->daifmt); 581 ssc_p->daifmt);
@@ -707,13 +750,18 @@ static struct snd_soc_dai_driver atmel_ssc_dai = {
707 .ops = &atmel_ssc_dai_ops, 750 .ops = &atmel_ssc_dai_ops,
708}; 751};
709 752
753static const struct snd_soc_component_driver atmel_ssc_component = {
754 .name = "atmel-ssc",
755};
756
710static int asoc_ssc_init(struct device *dev) 757static int asoc_ssc_init(struct device *dev)
711{ 758{
712 struct platform_device *pdev = to_platform_device(dev); 759 struct platform_device *pdev = to_platform_device(dev);
713 struct ssc_device *ssc = platform_get_drvdata(pdev); 760 struct ssc_device *ssc = platform_get_drvdata(pdev);
714 int ret; 761 int ret;
715 762
716 ret = snd_soc_register_dai(dev, &atmel_ssc_dai); 763 ret = snd_soc_register_component(dev, &atmel_ssc_component,
764 &atmel_ssc_dai, 1);
717 if (ret) { 765 if (ret) {
718 dev_err(dev, "Could not register DAI: %d\n", ret); 766 dev_err(dev, "Could not register DAI: %d\n", ret);
719 goto err; 767 goto err;
@@ -732,7 +780,7 @@ static int asoc_ssc_init(struct device *dev)
732 return 0; 780 return 0;
733 781
734err_unregister_dai: 782err_unregister_dai:
735 snd_soc_unregister_dai(dev); 783 snd_soc_unregister_component(dev);
736err: 784err:
737 return ret; 785 return ret;
738} 786}
@@ -747,7 +795,7 @@ static void asoc_ssc_exit(struct device *dev)
747 else 795 else
748 atmel_pcm_pdc_platform_unregister(dev); 796 atmel_pcm_pdc_platform_unregister(dev);
749 797
750 snd_soc_unregister_dai(dev); 798 snd_soc_unregister_component(dev);
751} 799}
752 800
753/** 801/**
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
index ea7d9d157022..44b8dcecf571 100644
--- a/sound/soc/au1x/ac97c.c
+++ b/sound/soc/au1x/ac97c.c
@@ -223,6 +223,10 @@ static struct snd_soc_dai_driver au1xac97c_dai_driver = {
223 .ops = &alchemy_ac97c_ops, 223 .ops = &alchemy_ac97c_ops,
224}; 224};
225 225
226static const struct snd_soc_component_driver au1xac97c_component = {
227 .name = "au1xac97c",
228};
229
226static int au1xac97c_drvprobe(struct platform_device *pdev) 230static int au1xac97c_drvprobe(struct platform_device *pdev)
227{ 231{
228 int ret; 232 int ret;
@@ -268,7 +272,8 @@ static int au1xac97c_drvprobe(struct platform_device *pdev)
268 272
269 platform_set_drvdata(pdev, ctx); 273 platform_set_drvdata(pdev, ctx);
270 274
271 ret = snd_soc_register_dai(&pdev->dev, &au1xac97c_dai_driver); 275 ret = snd_soc_register_component(&pdev->dev, &au1xac97c_component,
276 &au1xac97c_dai_driver, 1);
272 if (ret) 277 if (ret)
273 return ret; 278 return ret;
274 279
@@ -280,7 +285,7 @@ static int au1xac97c_drvremove(struct platform_device *pdev)
280{ 285{
281 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); 286 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
282 287
283 snd_soc_unregister_dai(&pdev->dev); 288 snd_soc_unregister_component(&pdev->dev);
284 289
285 WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */ 290 WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
286 291
diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c
index 072448afc219..b3f37f6edbcb 100644
--- a/sound/soc/au1x/i2sc.c
+++ b/sound/soc/au1x/i2sc.c
@@ -225,6 +225,10 @@ static struct snd_soc_dai_driver au1xi2s_dai_driver = {
225 .ops = &au1xi2s_dai_ops, 225 .ops = &au1xi2s_dai_ops,
226}; 226};
227 227
228static const struct snd_soc_component_driver au1xi2s_component = {
229 .name = "au1xi2s",
230};
231
228static int au1xi2s_drvprobe(struct platform_device *pdev) 232static int au1xi2s_drvprobe(struct platform_device *pdev)
229{ 233{
230 struct resource *iores, *dmares; 234 struct resource *iores, *dmares;
@@ -260,14 +264,15 @@ static int au1xi2s_drvprobe(struct platform_device *pdev)
260 264
261 platform_set_drvdata(pdev, ctx); 265 platform_set_drvdata(pdev, ctx);
262 266
263 return snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver); 267 return snd_soc_register_component(&pdev->dev, &au1xi2s_component,
268 &au1xi2s_dai_driver, 1);
264} 269}
265 270
266static int au1xi2s_drvremove(struct platform_device *pdev) 271static int au1xi2s_drvremove(struct platform_device *pdev)
267{ 272{
268 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); 273 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
269 274
270 snd_soc_unregister_dai(&pdev->dev); 275 snd_soc_unregister_component(&pdev->dev);
271 276
272 WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */ 277 WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
273 278
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 6ba07e365967..8f1862aa7333 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -361,6 +361,10 @@ static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = {
361 .ops = &au1xpsc_ac97_dai_ops, 361 .ops = &au1xpsc_ac97_dai_ops,
362}; 362};
363 363
364static const struct snd_soc_component_driver au1xpsc_ac97_component = {
365 .name = "au1xpsc-ac97",
366};
367
364static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) 368static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
365{ 369{
366 int ret; 370 int ret;
@@ -419,7 +423,8 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
419 423
420 platform_set_drvdata(pdev, wd); 424 platform_set_drvdata(pdev, wd);
421 425
422 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); 426 ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component,
427 &wd->dai_drv, 1);
423 if (ret) 428 if (ret)
424 return ret; 429 return ret;
425 430
@@ -431,7 +436,7 @@ static int au1xpsc_ac97_drvremove(struct platform_device *pdev)
431{ 436{
432 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); 437 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
433 438
434 snd_soc_unregister_dai(&pdev->dev); 439 snd_soc_unregister_component(&pdev->dev);
435 440
436 /* disable PSC completely */ 441 /* disable PSC completely */
437 au_writel(0, AC97_CFG(wd)); 442 au_writel(0, AC97_CFG(wd));
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 360b4e50d7c8..fe923a7bdc39 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -288,6 +288,10 @@ static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = {
288 .ops = &au1xpsc_i2s_dai_ops, 288 .ops = &au1xpsc_i2s_dai_ops,
289}; 289};
290 290
291static const struct snd_soc_component_driver au1xpsc_i2s_component = {
292 .name = "au1xpsc-i2s",
293};
294
291static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) 295static int au1xpsc_i2s_drvprobe(struct platform_device *pdev)
292{ 296{
293 struct resource *iores, *dmares; 297 struct resource *iores, *dmares;
@@ -350,14 +354,15 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev)
350 354
351 platform_set_drvdata(pdev, wd); 355 platform_set_drvdata(pdev, wd);
352 356
353 return snd_soc_register_dai(&pdev->dev, &wd->dai_drv); 357 return snd_soc_register_component(&pdev->dev, &au1xpsc_i2s_component,
358 &wd->dai_drv, 1);
354} 359}
355 360
356static int au1xpsc_i2s_drvremove(struct platform_device *pdev) 361static int au1xpsc_i2s_drvremove(struct platform_device *pdev)
357{ 362{
358 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); 363 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
359 364
360 snd_soc_unregister_dai(&pdev->dev); 365 snd_soc_unregister_component(&pdev->dev);
361 366
362 au_writel(0, I2S_CFG(wd)); 367 au_writel(0, I2S_CFG(wd));
363 au_sync(); 368 au_sync();
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index 8e41bcb020eb..490217325975 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -282,6 +282,10 @@ static struct snd_soc_dai_driver bfin_ac97_dai = {
282 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 282 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
283}; 283};
284 284
285static const struct snd_soc_component_driver bfin_ac97_component = {
286 .name = "bfin-ac97",
287};
288
285static int asoc_bfin_ac97_probe(struct platform_device *pdev) 289static int asoc_bfin_ac97_probe(struct platform_device *pdev)
286{ 290{
287 struct sport_device *sport_handle; 291 struct sport_device *sport_handle;
@@ -331,7 +335,8 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
331 goto sport_config_err; 335 goto sport_config_err;
332 } 336 }
333 337
334 ret = snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai); 338 ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component,
339 &bfin_ac97_dai, 1);
335 if (ret) { 340 if (ret) {
336 pr_err("Failed to register DAI: %d\n", ret); 341 pr_err("Failed to register DAI: %d\n", ret);
337 goto sport_config_err; 342 goto sport_config_err;
@@ -356,7 +361,7 @@ static int asoc_bfin_ac97_remove(struct platform_device *pdev)
356{ 361{
357 struct sport_device *sport_handle = platform_get_drvdata(pdev); 362 struct sport_device *sport_handle = platform_get_drvdata(pdev);
358 363
359 snd_soc_unregister_dai(&pdev->dev); 364 snd_soc_unregister_component(&pdev->dev);
360 sport_done(sport_handle); 365 sport_done(sport_handle);
361#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 366#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
362 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 367 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 168d88bccb41..dd0c2a4f83a3 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -245,6 +245,10 @@ static struct snd_soc_dai_driver bf5xx_i2s_dai = {
245 .ops = &bf5xx_i2s_dai_ops, 245 .ops = &bf5xx_i2s_dai_ops,
246}; 246};
247 247
248static const struct snd_soc_component_driver bf5xx_i2s_component = {
249 .name = "bf5xx-i2s",
250};
251
248static int bf5xx_i2s_probe(struct platform_device *pdev) 252static int bf5xx_i2s_probe(struct platform_device *pdev)
249{ 253{
250 struct sport_device *sport_handle; 254 struct sport_device *sport_handle;
@@ -257,7 +261,8 @@ static int bf5xx_i2s_probe(struct platform_device *pdev)
257 return -ENODEV; 261 return -ENODEV;
258 262
259 /* register with the ASoC layers */ 263 /* register with the ASoC layers */
260 ret = snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai); 264 ret = snd_soc_register_component(&pdev->dev, &bf5xx_i2s_component,
265 &bf5xx_i2s_dai, 1);
261 if (ret) { 266 if (ret) {
262 pr_err("Failed to register DAI: %d\n", ret); 267 pr_err("Failed to register DAI: %d\n", ret);
263 sport_done(sport_handle); 268 sport_done(sport_handle);
@@ -273,7 +278,7 @@ static int bf5xx_i2s_remove(struct platform_device *pdev)
273 278
274 pr_debug("%s enter\n", __func__); 279 pr_debug("%s enter\n", __func__);
275 280
276 snd_soc_unregister_dai(&pdev->dev); 281 snd_soc_unregister_component(&pdev->dev);
277 sport_done(sport_handle); 282 sport_done(sport_handle);
278 283
279 return 0; 284 return 0;
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index c1e516ec53ad..69e9a3e935bd 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -249,6 +249,10 @@ static struct snd_soc_dai_driver bf5xx_tdm_dai = {
249 .ops = &bf5xx_tdm_dai_ops, 249 .ops = &bf5xx_tdm_dai_ops,
250}; 250};
251 251
252static const struct snd_soc_component_driver bf5xx_tdm_component = {
253 .name = "bf5xx-tdm",
254};
255
252static int bfin_tdm_probe(struct platform_device *pdev) 256static int bfin_tdm_probe(struct platform_device *pdev)
253{ 257{
254 struct sport_device *sport_handle; 258 struct sport_device *sport_handle;
@@ -282,7 +286,8 @@ static int bfin_tdm_probe(struct platform_device *pdev)
282 goto sport_config_err; 286 goto sport_config_err;
283 } 287 }
284 288
285 ret = snd_soc_register_dai(&pdev->dev, &bf5xx_tdm_dai); 289 ret = snd_soc_register_component(&pdev->dev, &bf5xx_tdm_component,
290 &bf5xx_tdm_dai, 1);
286 if (ret) { 291 if (ret) {
287 pr_err("Failed to register DAI: %d\n", ret); 292 pr_err("Failed to register DAI: %d\n", ret);
288 goto sport_config_err; 293 goto sport_config_err;
@@ -299,7 +304,7 @@ static int bfin_tdm_remove(struct platform_device *pdev)
299{ 304{
300 struct sport_device *sport_handle = platform_get_drvdata(pdev); 305 struct sport_device *sport_handle = platform_get_drvdata(pdev);
301 306
302 snd_soc_unregister_dai(&pdev->dev); 307 snd_soc_unregister_component(&pdev->dev);
303 sport_done(sport_handle); 308 sport_done(sport_handle);
304 309
305 return 0; 310 return 0;
diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c
index 8f337972f438..c02405cc007d 100644
--- a/sound/soc/blackfin/bf6xx-i2s.c
+++ b/sound/soc/blackfin/bf6xx-i2s.c
@@ -186,6 +186,10 @@ static struct snd_soc_dai_driver bfin_i2s_dai = {
186 .ops = &bfin_i2s_dai_ops, 186 .ops = &bfin_i2s_dai_ops,
187}; 187};
188 188
189static const struct snd_soc_component_driver bfin_i2s_component = {
190 .name = "bfin-i2s",
191};
192
189static int bfin_i2s_probe(struct platform_device *pdev) 193static int bfin_i2s_probe(struct platform_device *pdev)
190{ 194{
191 struct sport_device *sport; 195 struct sport_device *sport;
@@ -197,7 +201,8 @@ static int bfin_i2s_probe(struct platform_device *pdev)
197 return -ENODEV; 201 return -ENODEV;
198 202
199 /* register with the ASoC layers */ 203 /* register with the ASoC layers */
200 ret = snd_soc_register_dai(dev, &bfin_i2s_dai); 204 ret = snd_soc_register_component(dev, &bfin_i2s_component,
205 &bfin_i2s_dai, 1);
201 if (ret) { 206 if (ret) {
202 dev_err(dev, "Failed to register DAI: %d\n", ret); 207 dev_err(dev, "Failed to register DAI: %d\n", ret);
203 sport_delete(sport); 208 sport_delete(sport);
@@ -212,7 +217,7 @@ static int bfin_i2s_remove(struct platform_device *pdev)
212{ 217{
213 struct sport_device *sport = platform_get_drvdata(pdev); 218 struct sport_device *sport = platform_get_drvdata(pdev);
214 219
215 snd_soc_unregister_dai(&pdev->dev); 220 snd_soc_unregister_component(&pdev->dev);
216 sport_delete(sport); 221 sport_delete(sport);
217 222
218 return 0; 223 return 0;
diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c
index 5db68cf7b281..c43fb214558a 100644
--- a/sound/soc/cirrus/edb93xx.c
+++ b/sound/soc/cirrus/edb93xx.c
@@ -27,7 +27,6 @@
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <asm/mach-types.h> 28#include <asm/mach-types.h>
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include "ep93xx-pcm.h"
31 30
32static int edb93xx_hw_params(struct snd_pcm_substream *substream, 31static int edb93xx_hw_params(struct snd_pcm_substream *substream,
33 struct snd_pcm_hw_params *params) 32 struct snd_pcm_hw_params *params)
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
index 1738d28fb04f..7798fbd5e81d 100644
--- a/sound/soc/cirrus/ep93xx-ac97.c
+++ b/sound/soc/cirrus/ep93xx-ac97.c
@@ -23,7 +23,6 @@
23#include <sound/soc.h> 23#include <sound/soc.h>
24 24
25#include <linux/platform_data/dma-ep93xx.h> 25#include <linux/platform_data/dma-ep93xx.h>
26#include "ep93xx-pcm.h"
27 26
28/* 27/*
29 * Per channel (1-4) registers. 28 * Per channel (1-4) registers.
@@ -101,14 +100,16 @@ struct ep93xx_ac97_info {
101/* currently ALSA only supports a single AC97 device */ 100/* currently ALSA only supports a single AC97 device */
102static struct ep93xx_ac97_info *ep93xx_ac97_info; 101static struct ep93xx_ac97_info *ep93xx_ac97_info;
103 102
104static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_out = { 103static struct ep93xx_dma_data ep93xx_ac97_pcm_out = {
105 .name = "ac97-pcm-out", 104 .name = "ac97-pcm-out",
106 .dma_port = EP93XX_DMA_AAC1, 105 .dma_port = EP93XX_DMA_AAC1,
106 .direction = DMA_MEM_TO_DEV,
107}; 107};
108 108
109static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_in = { 109static struct ep93xx_dma_data ep93xx_ac97_pcm_in = {
110 .name = "ac97-pcm-in", 110 .name = "ac97-pcm-in",
111 .dma_port = EP93XX_DMA_AAC1, 111 .dma_port = EP93XX_DMA_AAC1,
112 .direction = DMA_DEV_TO_MEM,
112}; 113};
113 114
114static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info, 115static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info,
@@ -316,7 +317,7 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
316static int ep93xx_ac97_startup(struct snd_pcm_substream *substream, 317static int ep93xx_ac97_startup(struct snd_pcm_substream *substream,
317 struct snd_soc_dai *dai) 318 struct snd_soc_dai *dai)
318{ 319{
319 struct ep93xx_pcm_dma_params *dma_data; 320 struct ep93xx_dma_data *dma_data;
320 321
321 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 322 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
322 dma_data = &ep93xx_ac97_pcm_out; 323 dma_data = &ep93xx_ac97_pcm_out;
@@ -353,6 +354,10 @@ static struct snd_soc_dai_driver ep93xx_ac97_dai = {
353 .ops = &ep93xx_ac97_dai_ops, 354 .ops = &ep93xx_ac97_dai_ops,
354}; 355};
355 356
357static const struct snd_soc_component_driver ep93xx_ac97_component = {
358 .name = "ep93xx-ac97",
359};
360
356static int ep93xx_ac97_probe(struct platform_device *pdev) 361static int ep93xx_ac97_probe(struct platform_device *pdev)
357{ 362{
358 struct ep93xx_ac97_info *info; 363 struct ep93xx_ac97_info *info;
@@ -390,7 +395,8 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
390 ep93xx_ac97_info = info; 395 ep93xx_ac97_info = info;
391 platform_set_drvdata(pdev, info); 396 platform_set_drvdata(pdev, info);
392 397
393 ret = snd_soc_register_dai(&pdev->dev, &ep93xx_ac97_dai); 398 ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component,
399 &ep93xx_ac97_dai, 1);
394 if (ret) 400 if (ret)
395 goto fail; 401 goto fail;
396 402
@@ -407,7 +413,7 @@ static int ep93xx_ac97_remove(struct platform_device *pdev)
407{ 413{
408 struct ep93xx_ac97_info *info = platform_get_drvdata(pdev); 414 struct ep93xx_ac97_info *info = platform_get_drvdata(pdev);
409 415
410 snd_soc_unregister_dai(&pdev->dev); 416 snd_soc_unregister_component(&pdev->dev);
411 417
412 /* disable the AC97 controller */ 418 /* disable the AC97 controller */
413 ep93xx_ac97_write_reg(info, AC97GCR, 0); 419 ep93xx_ac97_write_reg(info, AC97GCR, 0);
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 323ed69b7975..5c1102e9e159 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -30,8 +30,6 @@
30#include <mach/ep93xx-regs.h> 30#include <mach/ep93xx-regs.h>
31#include <linux/platform_data/dma-ep93xx.h> 31#include <linux/platform_data/dma-ep93xx.h>
32 32
33#include "ep93xx-pcm.h"
34
35#define EP93XX_I2S_TXCLKCFG 0x00 33#define EP93XX_I2S_TXCLKCFG 0x00
36#define EP93XX_I2S_RXCLKCFG 0x04 34#define EP93XX_I2S_RXCLKCFG 0x04
37#define EP93XX_I2S_GLCTRL 0x0C 35#define EP93XX_I2S_GLCTRL 0x0C
@@ -62,18 +60,20 @@ struct ep93xx_i2s_info {
62 struct clk *mclk; 60 struct clk *mclk;
63 struct clk *sclk; 61 struct clk *sclk;
64 struct clk *lrclk; 62 struct clk *lrclk;
65 struct ep93xx_pcm_dma_params *dma_params; 63 struct ep93xx_dma_data *dma_data;
66 void __iomem *regs; 64 void __iomem *regs;
67}; 65};
68 66
69struct ep93xx_pcm_dma_params ep93xx_i2s_dma_params[] = { 67struct ep93xx_dma_data ep93xx_i2s_dma_data[] = {
70 [SNDRV_PCM_STREAM_PLAYBACK] = { 68 [SNDRV_PCM_STREAM_PLAYBACK] = {
71 .name = "i2s-pcm-out", 69 .name = "i2s-pcm-out",
72 .dma_port = EP93XX_DMA_I2S1, 70 .port = EP93XX_DMA_I2S1,
71 .direction = DMA_MEM_TO_DEV,
73 }, 72 },
74 [SNDRV_PCM_STREAM_CAPTURE] = { 73 [SNDRV_PCM_STREAM_CAPTURE] = {
75 .name = "i2s-pcm-in", 74 .name = "i2s-pcm-in",
76 .dma_port = EP93XX_DMA_I2S1, 75 .port = EP93XX_DMA_I2S1,
76 .direction = DMA_DEV_TO_MEM,
77 }, 77 },
78}; 78};
79 79
@@ -147,7 +147,7 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream,
147 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 147 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
148 148
149 snd_soc_dai_set_dma_data(cpu_dai, substream, 149 snd_soc_dai_set_dma_data(cpu_dai, substream,
150 &info->dma_params[substream->stream]); 150 &info->dma_data[substream->stream]);
151 return 0; 151 return 0;
152} 152}
153 153
@@ -366,6 +366,10 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = {
366 .ops = &ep93xx_i2s_dai_ops, 366 .ops = &ep93xx_i2s_dai_ops,
367}; 367};
368 368
369static const struct snd_soc_component_driver ep93xx_i2s_component = {
370 .name = "ep93xx-i2s",
371};
372
369static int ep93xx_i2s_probe(struct platform_device *pdev) 373static int ep93xx_i2s_probe(struct platform_device *pdev)
370{ 374{
371 struct ep93xx_i2s_info *info; 375 struct ep93xx_i2s_info *info;
@@ -403,9 +407,10 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
403 } 407 }
404 408
405 dev_set_drvdata(&pdev->dev, info); 409 dev_set_drvdata(&pdev->dev, info);
406 info->dma_params = ep93xx_i2s_dma_params; 410 info->dma_data = ep93xx_i2s_dma_data;
407 411
408 err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai); 412 err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component,
413 &ep93xx_i2s_dai, 1);
409 if (err) 414 if (err)
410 goto fail_put_lrclk; 415 goto fail_put_lrclk;
411 416
@@ -426,7 +431,7 @@ static int ep93xx_i2s_remove(struct platform_device *pdev)
426{ 431{
427 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); 432 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
428 433
429 snd_soc_unregister_dai(&pdev->dev); 434 snd_soc_unregister_component(&pdev->dev);
430 dev_set_drvdata(&pdev->dev, NULL); 435 dev_set_drvdata(&pdev->dev, NULL);
431 clk_put(info->lrclk); 436 clk_put(info->lrclk);
432 clk_put(info->sclk); 437 clk_put(info->sclk);
diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c
index 72eb7a49e16a..298946f790eb 100644
--- a/sound/soc/cirrus/ep93xx-pcm.c
+++ b/sound/soc/cirrus/ep93xx-pcm.c
@@ -29,8 +29,6 @@
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include <mach/ep93xx-regs.h> 30#include <mach/ep93xx-regs.h>
31 31
32#include "ep93xx-pcm.h"
33
34static const struct snd_pcm_hardware ep93xx_pcm_hardware = { 32static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
35 .info = (SNDRV_PCM_INFO_MMAP | 33 .info = (SNDRV_PCM_INFO_MMAP |
36 SNDRV_PCM_INFO_MMAP_VALID | 34 SNDRV_PCM_INFO_MMAP_VALID |
@@ -68,40 +66,11 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
68static int ep93xx_pcm_open(struct snd_pcm_substream *substream) 66static int ep93xx_pcm_open(struct snd_pcm_substream *substream)
69{ 67{
70 struct snd_soc_pcm_runtime *rtd = substream->private_data; 68 struct snd_soc_pcm_runtime *rtd = substream->private_data;
71 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
72 struct ep93xx_pcm_dma_params *dma_params;
73 struct ep93xx_dma_data *dma_data;
74 int ret;
75 69
76 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); 70 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware);
77 71
78 dma_data = kmalloc(sizeof(*dma_data), GFP_KERNEL); 72 return snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter,
79 if (!dma_data) 73 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
80 return -ENOMEM;
81
82 dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream);
83 dma_data->port = dma_params->dma_port;
84 dma_data->name = dma_params->name;
85 dma_data->direction = snd_pcm_substream_to_dma_direction(substream);
86
87 ret = snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, dma_data);
88 if (ret) {
89 kfree(dma_data);
90 return ret;
91 }
92
93 snd_dmaengine_pcm_set_data(substream, dma_data);
94
95 return 0;
96}
97
98static int ep93xx_pcm_close(struct snd_pcm_substream *substream)
99{
100 struct dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
101
102 snd_dmaengine_pcm_close(substream);
103 kfree(dma_data);
104 return 0;
105} 74}
106 75
107static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, 76static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream,
@@ -131,7 +100,7 @@ static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream,
131 100
132static struct snd_pcm_ops ep93xx_pcm_ops = { 101static struct snd_pcm_ops ep93xx_pcm_ops = {
133 .open = ep93xx_pcm_open, 102 .open = ep93xx_pcm_open,
134 .close = ep93xx_pcm_close, 103 .close = snd_dmaengine_pcm_close,
135 .ioctl = snd_pcm_lib_ioctl, 104 .ioctl = snd_pcm_lib_ioctl,
136 .hw_params = ep93xx_pcm_hw_params, 105 .hw_params = ep93xx_pcm_hw_params,
137 .hw_free = ep93xx_pcm_hw_free, 106 .hw_free = ep93xx_pcm_hw_free,
diff --git a/sound/soc/cirrus/ep93xx-pcm.h b/sound/soc/cirrus/ep93xx-pcm.h
deleted file mode 100644
index 111e1121ecb8..000000000000
--- a/sound/soc/cirrus/ep93xx-pcm.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * sound/soc/ep93xx/ep93xx-pcm.h - EP93xx ALSA PCM interface
3 *
4 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
5 * Copyright (C) 2006 Applied Data Systems
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
12#ifndef _EP93XX_SND_SOC_PCM_H
13#define _EP93XX_SND_SOC_PCM_H
14
15struct ep93xx_pcm_dma_params {
16 char *name;
17 int dma_port;
18};
19
20#endif /* _EP93XX_SND_SOC_PCM_H */
diff --git a/sound/soc/cirrus/simone.c b/sound/soc/cirrus/simone.c
index a397bb0d8179..4d094d00c34a 100644
--- a/sound/soc/cirrus/simone.c
+++ b/sound/soc/cirrus/simone.c
@@ -21,8 +21,6 @@
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23 23
24#include "ep93xx-pcm.h"
25
26static struct snd_soc_dai_link simone_dai = { 24static struct snd_soc_dai_link simone_dai = {
27 .name = "AC97", 25 .name = "AC97",
28 .stream_name = "AC97 HiFi", 26 .stream_name = "AC97 HiFi",
diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c
index 9d77fe28dfcc..69041074f2c1 100644
--- a/sound/soc/cirrus/snappercl15.c
+++ b/sound/soc/cirrus/snappercl15.c
@@ -21,7 +21,6 @@
21#include <mach/hardware.h> 21#include <mach/hardware.h>
22 22
23#include "../codecs/tlv320aic23.h" 23#include "../codecs/tlv320aic23.h"
24#include "ep93xx-pcm.h"
25 24
26#define CODEC_CLOCK 5644800 25#define CODEC_CLOCK 5644800
27 26
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 45b72561c615..cf7b9897fa6b 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -26,6 +26,7 @@ config SND_SOC_ALL_CODECS
26 select SND_SOC_AK4641 if I2C 26 select SND_SOC_AK4641 if I2C
27 select SND_SOC_AK4642 if I2C 27 select SND_SOC_AK4642 if I2C
28 select SND_SOC_AK4671 if I2C 28 select SND_SOC_AK4671 if I2C
29 select SND_SOC_AK5386
29 select SND_SOC_ALC5623 if I2C 30 select SND_SOC_ALC5623 if I2C
30 select SND_SOC_ALC5632 if I2C 31 select SND_SOC_ALC5632 if I2C
31 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 32 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
@@ -203,6 +204,9 @@ config SND_SOC_AK4642
203config SND_SOC_AK4671 204config SND_SOC_AK4671
204 tristate 205 tristate
205 206
207config SND_SOC_AK5386
208 tristate
209
206config SND_SOC_ALC5623 210config SND_SOC_ALC5623
207 tristate 211 tristate
208config SND_SOC_ALC5632 212config SND_SOC_ALC5632
@@ -324,7 +328,7 @@ config SND_SOC_TLV320AIC23
324 tristate 328 tristate
325 329
326config SND_SOC_TLV320AIC26 330config SND_SOC_TLV320AIC26
327 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE 331 tristate
328 depends on SPI 332 depends on SPI
329 333
330config SND_SOC_TLV320AIC32X4 334config SND_SOC_TLV320AIC32X4
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 6a3b3c3b8b41..3a7ec1c39741 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -14,6 +14,7 @@ snd-soc-ak4535-objs := ak4535.o
14snd-soc-ak4641-objs := ak4641.o 14snd-soc-ak4641-objs := ak4641.o
15snd-soc-ak4642-objs := ak4642.o 15snd-soc-ak4642-objs := ak4642.o
16snd-soc-ak4671-objs := ak4671.o 16snd-soc-ak4671-objs := ak4671.o
17snd-soc-ak5386-objs := ak5386.o
17snd-soc-arizona-objs := arizona.o 18snd-soc-arizona-objs := arizona.o
18snd-soc-cq93vc-objs := cq93vc.o 19snd-soc-cq93vc-objs := cq93vc.o
19snd-soc-cs42l51-objs := cs42l51.o 20snd-soc-cs42l51-objs := cs42l51.o
@@ -137,6 +138,7 @@ obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
137obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o 138obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
138obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 139obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
139obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 140obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
141obj-$(CONFIG_SND_SOC_AK5386) += snd-soc-ak5386.o
140obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o 142obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
141obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o 143obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
142obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o 144obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 068b3ae56a17..1aa10ddf3a61 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -133,6 +133,8 @@ struct adau1373 {
133#define ADAU1373_DAI_FORMAT_DSP 0x3 133#define ADAU1373_DAI_FORMAT_DSP 0x3
134 134
135#define ADAU1373_BCLKDIV_SOURCE BIT(5) 135#define ADAU1373_BCLKDIV_SOURCE BIT(5)
136#define ADAU1373_BCLKDIV_SR_MASK (0x07 << 2)
137#define ADAU1373_BCLKDIV_BCLK_MASK 0x03
136#define ADAU1373_BCLKDIV_32 0x03 138#define ADAU1373_BCLKDIV_32 0x03
137#define ADAU1373_BCLKDIV_64 0x02 139#define ADAU1373_BCLKDIV_64 0x02
138#define ADAU1373_BCLKDIV_128 0x01 140#define ADAU1373_BCLKDIV_128 0x01
@@ -937,7 +939,8 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream,
937 adau1373_dai->enable_src = (div != 0); 939 adau1373_dai->enable_src = (div != 0);
938 940
939 snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id), 941 snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id),
940 ~ADAU1373_BCLKDIV_SOURCE, (div << 2) | ADAU1373_BCLKDIV_64); 942 ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK,
943 (div << 2) | ADAU1373_BCLKDIV_64);
941 944
942 switch (params_format(params)) { 945 switch (params_format(params)) {
943 case SNDRV_PCM_FORMAT_S16_LE: 946 case SNDRV_PCM_FORMAT_S16_LE:
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 6f6c335a5baa..c7cfdf957e4d 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -55,6 +55,7 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
55 unsigned int format) 55 unsigned int format)
56{ 56{
57 struct snd_soc_codec *codec = codec_dai->codec; 57 struct snd_soc_codec *codec = codec_dai->codec;
58 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
58 int val = 0; 59 int val = 0;
59 int ret; 60 int ret;
60 61
@@ -77,9 +78,9 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
77 if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) 78 if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
78 return -EINVAL; 79 return -EINVAL;
79 80
80 ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1, 81 ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,
81 AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1, 82 AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1,
82 val); 83 val);
83 if (ret < 0) 84 if (ret < 0)
84 return ret; 85 return ret;
85 86
@@ -91,11 +92,12 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
91 struct snd_soc_dai *dai) 92 struct snd_soc_dai *dai)
92{ 93{
93 struct snd_soc_codec *codec = dai->codec; 94 struct snd_soc_codec *codec = dai->codec;
94 int val = 0; 95 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
96 int ret, val = 0;
95 97
96 /* set the IEC958 bits: consumer mode, no copyright bit */ 98 /* set the IEC958 bits: consumer mode, no copyright bit */
97 val |= IEC958_AES0_CON_NOT_COPYRIGHT; 99 val |= IEC958_AES0_CON_NOT_COPYRIGHT;
98 snd_soc_write(codec, AK4104_REG_CHN_STATUS(0), val); 100 regmap_write(ak4104->regmap, AK4104_REG_CHN_STATUS(0), val);
99 101
100 val = 0; 102 val = 0;
101 103
@@ -132,11 +134,33 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
132 return -EINVAL; 134 return -EINVAL;
133 } 135 }
134 136
135 return snd_soc_write(codec, AK4104_REG_CHN_STATUS(3), val); 137 ret = regmap_write(ak4104->regmap, AK4104_REG_CHN_STATUS(3), val);
138 if (ret < 0)
139 return ret;
140
141 /* enable transmitter */
142 ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX,
143 AK4104_TX_TXE, AK4104_TX_TXE);
144 if (ret < 0)
145 return ret;
146
147 return 0;
148}
149
150static int ak4104_hw_free(struct snd_pcm_substream *substream,
151 struct snd_soc_dai *dai)
152{
153 struct snd_soc_codec *codec = dai->codec;
154 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
155
156 /* disable transmitter */
157 return regmap_update_bits(ak4104->regmap, AK4104_REG_TX,
158 AK4104_TX_TXE, 0);
136} 159}
137 160
138static const struct snd_soc_dai_ops ak4101_dai_ops = { 161static const struct snd_soc_dai_ops ak4101_dai_ops = {
139 .hw_params = ak4104_hw_params, 162 .hw_params = ak4104_hw_params,
163 .hw_free = ak4104_hw_free,
140 .set_fmt = ak4104_set_dai_fmt, 164 .set_fmt = ak4104_set_dai_fmt,
141}; 165};
142 166
@@ -160,20 +184,17 @@ static int ak4104_probe(struct snd_soc_codec *codec)
160 int ret; 184 int ret;
161 185
162 codec->control_data = ak4104->regmap; 186 codec->control_data = ak4104->regmap;
163 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
164 if (ret != 0)
165 return ret;
166 187
167 /* set power-up and non-reset bits */ 188 /* set power-up and non-reset bits */
168 ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1, 189 ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,
169 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 190 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN,
170 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); 191 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
171 if (ret < 0) 192 if (ret < 0)
172 return ret; 193 return ret;
173 194
174 /* enable transmitter */ 195 /* enable transmitter */
175 ret = snd_soc_update_bits(codec, AK4104_REG_TX, 196 ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX,
176 AK4104_TX_TXE, AK4104_TX_TXE); 197 AK4104_TX_TXE, AK4104_TX_TXE);
177 if (ret < 0) 198 if (ret < 0)
178 return ret; 199 return ret;
179 200
@@ -182,8 +203,10 @@ static int ak4104_probe(struct snd_soc_codec *codec)
182 203
183static int ak4104_remove(struct snd_soc_codec *codec) 204static int ak4104_remove(struct snd_soc_codec *codec)
184{ 205{
185 snd_soc_update_bits(codec, AK4104_REG_CONTROL1, 206 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
186 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0); 207
208 regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,
209 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);
187 210
188 return 0; 211 return 0;
189} 212}
diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c
new file mode 100644
index 000000000000..1f303983ae02
--- /dev/null
+++ b/sound/soc/codecs/ak5386.c
@@ -0,0 +1,152 @@
1/*
2 * ALSA SoC driver for
3 * Asahi Kasei AK5386 Single-ended 24-Bit 192kHz delta-sigma ADC
4 *
5 * (c) 2013 Daniel Mack <zonque@gmail.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
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/of.h>
15#include <linux/of_gpio.h>
16#include <linux/of_device.h>
17#include <sound/soc.h>
18#include <sound/pcm.h>
19#include <sound/initval.h>
20
21struct ak5386_priv {
22 int reset_gpio;
23};
24
25static struct snd_soc_codec_driver soc_codec_ak5386;
26
27static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai,
28 unsigned int format)
29{
30 struct snd_soc_codec *codec = codec_dai->codec;
31
32 format &= SND_SOC_DAIFMT_FORMAT_MASK;
33 if (format != SND_SOC_DAIFMT_LEFT_J &&
34 format != SND_SOC_DAIFMT_I2S) {
35 dev_err(codec->dev, "Invalid DAI format\n");
36 return -EINVAL;
37 }
38
39 return 0;
40}
41
42static int ak5386_hw_params(struct snd_pcm_substream *substream,
43 struct snd_pcm_hw_params *params,
44 struct snd_soc_dai *dai)
45{
46 struct snd_soc_codec *codec = dai->codec;
47 struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
48
49 /*
50 * From the datasheet:
51 *
52 * All external clocks (MCLK, SCLK and LRCK) must be present unless
53 * PDN pin = “L”. If these clocks are not provided, the AK5386 may
54 * draw excess current due to its use of internal dynamically
55 * refreshed logic. If the external clocks are not present, place
56 * the AK5386 in power-down mode (PDN pin = “L”).
57 */
58
59 if (gpio_is_valid(priv->reset_gpio))
60 gpio_set_value(priv->reset_gpio, 1);
61
62 return 0;
63}
64
65static int ak5386_hw_free(struct snd_pcm_substream *substream,
66 struct snd_soc_dai *dai)
67{
68 struct snd_soc_codec *codec = dai->codec;
69 struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
70
71 if (gpio_is_valid(priv->reset_gpio))
72 gpio_set_value(priv->reset_gpio, 0);
73
74 return 0;
75}
76
77static const struct snd_soc_dai_ops ak5386_dai_ops = {
78 .set_fmt = ak5386_set_dai_fmt,
79 .hw_params = ak5386_hw_params,
80 .hw_free = ak5386_hw_free,
81};
82
83static struct snd_soc_dai_driver ak5386_dai = {
84 .name = "ak5386-hifi",
85 .capture = {
86 .stream_name = "Capture",
87 .channels_min = 1,
88 .channels_max = 2,
89 .rates = SNDRV_PCM_RATE_8000_192000,
90 .formats = SNDRV_PCM_FMTBIT_S8 |
91 SNDRV_PCM_FMTBIT_S16_LE |
92 SNDRV_PCM_FMTBIT_S24_LE |
93 SNDRV_PCM_FMTBIT_S24_3LE,
94 },
95 .ops = &ak5386_dai_ops,
96};
97
98#ifdef CONFIG_OF
99static const struct of_device_id ak5386_dt_ids[] = {
100 { .compatible = "asahi-kasei,ak5386", },
101 { }
102};
103MODULE_DEVICE_TABLE(of, ak5386_dt_ids);
104#endif
105
106static int ak5386_probe(struct platform_device *pdev)
107{
108 struct device *dev = &pdev->dev;
109 struct ak5386_priv *priv;
110
111 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
112 if (!priv)
113 return -ENOMEM;
114
115 priv->reset_gpio = -EINVAL;
116 dev_set_drvdata(dev, priv);
117
118 if (of_match_device(of_match_ptr(ak5386_dt_ids), dev))
119 priv->reset_gpio = of_get_named_gpio(dev->of_node,
120 "reset-gpio", 0);
121
122 if (gpio_is_valid(priv->reset_gpio))
123 if (devm_gpio_request_one(dev, priv->reset_gpio,
124 GPIOF_OUT_INIT_LOW,
125 "AK5386 Reset"))
126 priv->reset_gpio = -EINVAL;
127
128 return snd_soc_register_codec(dev, &soc_codec_ak5386,
129 &ak5386_dai, 1);
130}
131
132static int ak5386_remove(struct platform_device *pdev)
133{
134 snd_soc_unregister_codec(&pdev->dev);
135 return 0;
136}
137
138static struct platform_driver ak5386_driver = {
139 .probe = ak5386_probe,
140 .remove = ak5386_remove,
141 .driver = {
142 .name = "ak5386",
143 .owner = THIS_MODULE,
144 .of_match_table = of_match_ptr(ak5386_dt_ids),
145 },
146};
147
148module_platform_driver(ak5386_driver);
149
150MODULE_DESCRIPTION("ASoC driver for AK5386 ADC");
151MODULE_AUTHOR("Daniel Mack <zonque@gmail.com>");
152MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index ac948a671ea6..389f23253831 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -10,6 +10,7 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/delay.h>
13#include <linux/gcd.h> 14#include <linux/gcd.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/pm_runtime.h> 16#include <linux/pm_runtime.h>
@@ -65,6 +66,163 @@
65#define arizona_aif_dbg(_dai, fmt, ...) \ 66#define arizona_aif_dbg(_dai, fmt, ...) \
66 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 67 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
67 68
69static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
70 struct snd_kcontrol *kcontrol,
71 int event)
72{
73 struct snd_soc_codec *codec = w->codec;
74 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
75 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
76 bool manual_ena = false;
77 int val;
78
79 switch (arizona->type) {
80 case WM5102:
81 switch (arizona->rev) {
82 case 0:
83 break;
84 default:
85 manual_ena = true;
86 break;
87 }
88 default:
89 break;
90 }
91
92 switch (event) {
93 case SND_SOC_DAPM_PRE_PMU:
94 if (!priv->spk_ena && manual_ena) {
95 snd_soc_write(codec, 0x4f5, 0x25a);
96 priv->spk_ena_pending = true;
97 }
98 break;
99 case SND_SOC_DAPM_POST_PMU:
100 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
101 if (val & ARIZONA_SPK_SHUTDOWN_STS) {
102 dev_crit(arizona->dev,
103 "Speaker not enabled due to temperature\n");
104 return -EBUSY;
105 }
106
107 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
108 1 << w->shift, 1 << w->shift);
109
110 if (priv->spk_ena_pending) {
111 msleep(75);
112 snd_soc_write(codec, 0x4f5, 0xda);
113 priv->spk_ena_pending = false;
114 priv->spk_ena++;
115 }
116 break;
117 case SND_SOC_DAPM_PRE_PMD:
118 if (manual_ena) {
119 priv->spk_ena--;
120 if (!priv->spk_ena)
121 snd_soc_write(codec, 0x4f5, 0x25a);
122 }
123
124 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
125 1 << w->shift, 0);
126 break;
127 case SND_SOC_DAPM_POST_PMD:
128 if (manual_ena) {
129 if (!priv->spk_ena)
130 snd_soc_write(codec, 0x4f5, 0x0da);
131 }
132 break;
133 }
134
135 return 0;
136}
137
138static irqreturn_t arizona_thermal_warn(int irq, void *data)
139{
140 struct arizona *arizona = data;
141 unsigned int val;
142 int ret;
143
144 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
145 &val);
146 if (ret != 0) {
147 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
148 ret);
149 } else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) {
150 dev_crit(arizona->dev, "Thermal warning\n");
151 }
152
153 return IRQ_HANDLED;
154}
155
156static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
157{
158 struct arizona *arizona = data;
159 unsigned int val;
160 int ret;
161
162 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
163 &val);
164 if (ret != 0) {
165 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
166 ret);
167 } else if (val & ARIZONA_SPK_SHUTDOWN_STS) {
168 dev_crit(arizona->dev, "Thermal shutdown\n");
169 ret = regmap_update_bits(arizona->regmap,
170 ARIZONA_OUTPUT_ENABLES_1,
171 ARIZONA_OUT4L_ENA |
172 ARIZONA_OUT4R_ENA, 0);
173 if (ret != 0)
174 dev_crit(arizona->dev,
175 "Failed to disable speaker outputs: %d\n",
176 ret);
177 }
178
179 return IRQ_HANDLED;
180}
181
182static const struct snd_soc_dapm_widget arizona_spkl =
183 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
184 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
185 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
186
187static const struct snd_soc_dapm_widget arizona_spkr =
188 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
189 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
190 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
191
192int arizona_init_spk(struct snd_soc_codec *codec)
193{
194 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
195 struct arizona *arizona = priv->arizona;
196 int ret;
197
198 ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1);
199 if (ret != 0)
200 return ret;
201
202 ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkr, 1);
203 if (ret != 0)
204 return ret;
205
206 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN,
207 "Thermal warning", arizona_thermal_warn,
208 arizona);
209 if (ret != 0)
210 dev_err(arizona->dev,
211 "Failed to get thermal warning IRQ: %d\n",
212 ret);
213
214 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN,
215 "Thermal shutdown", arizona_thermal_shutdown,
216 arizona);
217 if (ret != 0)
218 dev_err(arizona->dev,
219 "Failed to get thermal shutdown IRQ: %d\n",
220 ret);
221
222 return 0;
223}
224EXPORT_SYMBOL_GPL(arizona_init_spk);
225
68const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 226const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
69 "None", 227 "None",
70 "Tone Generator 1", 228 "Tone Generator 1",
@@ -274,6 +432,33 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values);
274const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); 432const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
275EXPORT_SYMBOL_GPL(arizona_mixer_tlv); 433EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
276 434
435const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
436 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
437};
438EXPORT_SYMBOL_GPL(arizona_rate_text);
439
440const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
441 0, 1, 2, 8,
442};
443EXPORT_SYMBOL_GPL(arizona_rate_val);
444
445
446const struct soc_enum arizona_isrc_fsl[] = {
447 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
448 ARIZONA_ISRC1_FSL_SHIFT, 0xf,
449 ARIZONA_RATE_ENUM_SIZE,
450 arizona_rate_text, arizona_rate_val),
451 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
452 ARIZONA_ISRC2_FSL_SHIFT, 0xf,
453 ARIZONA_RATE_ENUM_SIZE,
454 arizona_rate_text, arizona_rate_val),
455 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
456 ARIZONA_ISRC3_FSL_SHIFT, 0xf,
457 ARIZONA_RATE_ENUM_SIZE,
458 arizona_rate_text, arizona_rate_val),
459};
460EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
461
277static const char *arizona_vol_ramp_text[] = { 462static const char *arizona_vol_ramp_text[] = {
278 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", 463 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
279 "15ms/6dB", "30ms/6dB", 464 "15ms/6dB", "30ms/6dB",
@@ -332,9 +517,27 @@ const struct soc_enum arizona_ng_hold =
332 4, arizona_ng_hold_text); 517 4, arizona_ng_hold_text);
333EXPORT_SYMBOL_GPL(arizona_ng_hold); 518EXPORT_SYMBOL_GPL(arizona_ng_hold);
334 519
520static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
521{
522 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
523 unsigned int val;
524 int i;
525
526 if (ena)
527 val = ARIZONA_IN_VU;
528 else
529 val = 0;
530
531 for (i = 0; i < priv->num_inputs; i++)
532 snd_soc_update_bits(codec,
533 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
534 ARIZONA_IN_VU, val);
535}
536
335int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 537int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
336 int event) 538 int event)
337{ 539{
540 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
338 unsigned int reg; 541 unsigned int reg;
339 542
340 if (w->shift % 2) 543 if (w->shift % 2)
@@ -343,13 +546,29 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
343 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); 546 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
344 547
345 switch (event) { 548 switch (event) {
549 case SND_SOC_DAPM_PRE_PMU:
550 priv->in_pending++;
551 break;
346 case SND_SOC_DAPM_POST_PMU: 552 case SND_SOC_DAPM_POST_PMU:
347 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); 553 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
554
555 /* If this is the last input pending then allow VU */
556 priv->in_pending--;
557 if (priv->in_pending == 0) {
558 msleep(1);
559 arizona_in_set_vu(w->codec, 1);
560 }
348 break; 561 break;
349 case SND_SOC_DAPM_PRE_PMD: 562 case SND_SOC_DAPM_PRE_PMD:
350 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 563 snd_soc_update_bits(w->codec, reg,
351 ARIZONA_IN1L_MUTE); 564 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
565 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
352 break; 566 break;
567 case SND_SOC_DAPM_POST_PMD:
568 /* Disable volume updates if no inputs are enabled */
569 reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
570 if (reg == 0)
571 arizona_in_set_vu(w->codec, 0);
353 } 572 }
354 573
355 return 0; 574 return 0;
@@ -360,10 +579,61 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
360 struct snd_kcontrol *kcontrol, 579 struct snd_kcontrol *kcontrol,
361 int event) 580 int event)
362{ 581{
582 switch (event) {
583 case SND_SOC_DAPM_POST_PMU:
584 switch (w->shift) {
585 case ARIZONA_OUT1L_ENA_SHIFT:
586 case ARIZONA_OUT1R_ENA_SHIFT:
587 case ARIZONA_OUT2L_ENA_SHIFT:
588 case ARIZONA_OUT2R_ENA_SHIFT:
589 case ARIZONA_OUT3L_ENA_SHIFT:
590 case ARIZONA_OUT3R_ENA_SHIFT:
591 msleep(17);
592 break;
593
594 default:
595 break;
596 }
597 break;
598 }
599
363 return 0; 600 return 0;
364} 601}
365EXPORT_SYMBOL_GPL(arizona_out_ev); 602EXPORT_SYMBOL_GPL(arizona_out_ev);
366 603
604int arizona_hp_ev(struct snd_soc_dapm_widget *w,
605 struct snd_kcontrol *kcontrol,
606 int event)
607{
608 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
609 unsigned int mask = 1 << w->shift;
610 unsigned int val;
611
612 switch (event) {
613 case SND_SOC_DAPM_POST_PMU:
614 val = mask;
615 break;
616 case SND_SOC_DAPM_PRE_PMD:
617 val = 0;
618 break;
619 default:
620 return -EINVAL;
621 }
622
623 /* Store the desired state for the HP outputs */
624 priv->arizona->hp_ena &= ~mask;
625 priv->arizona->hp_ena |= val;
626
627 /* Force off if HPDET magic is active */
628 if (priv->arizona->hpdet_magic)
629 val = 0;
630
631 snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val);
632
633 return arizona_out_ev(w, kcontrol, event);
634}
635EXPORT_SYMBOL_GPL(arizona_hp_ev);
636
367static unsigned int arizona_sysclk_48k_rates[] = { 637static unsigned int arizona_sysclk_48k_rates[] = {
368 6144000, 638 6144000,
369 12288000, 639 12288000,
@@ -469,27 +739,27 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
469 break; 739 break;
470 case 11289600: 740 case 11289600:
471 case 12288000: 741 case 12288000:
472 val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT; 742 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
473 break; 743 break;
474 case 22579200: 744 case 22579200:
475 case 24576000: 745 case 24576000:
476 val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT; 746 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
477 break; 747 break;
478 case 45158400: 748 case 45158400:
479 case 49152000: 749 case 49152000:
480 val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; 750 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
481 break; 751 break;
482 case 67737600: 752 case 67737600:
483 case 73728000: 753 case 73728000:
484 val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT; 754 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
485 break; 755 break;
486 case 90316800: 756 case 90316800:
487 case 98304000: 757 case 98304000:
488 val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; 758 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
489 break; 759 break;
490 case 135475200: 760 case 135475200:
491 case 147456000: 761 case 147456000:
492 val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; 762 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
493 break; 763 break;
494 case 0: 764 case 0:
495 dev_dbg(arizona->dev, "%s cleared\n", name); 765 dev_dbg(arizona->dev, "%s cleared\n", name);
@@ -783,7 +1053,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
783 struct arizona *arizona = priv->arizona; 1053 struct arizona *arizona = priv->arizona;
784 int base = dai->driver->base; 1054 int base = dai->driver->base;
785 const int *rates; 1055 const int *rates;
786 int i, ret; 1056 int i, ret, val;
787 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; 1057 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
788 int bclk, lrclk, wl, frame, bclk_target; 1058 int bclk, lrclk, wl, frame, bclk_target;
789 1059
@@ -799,6 +1069,13 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
799 bclk_target *= chan_limit; 1069 bclk_target *= chan_limit;
800 } 1070 }
801 1071
1072 /* Force stereo for I2S mode */
1073 val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1074 if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) {
1075 arizona_aif_dbg(dai, "Forcing stereo mode\n");
1076 bclk_target *= 2;
1077 }
1078
802 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { 1079 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
803 if (rates[i] >= bclk_target && 1080 if (rates[i] >= bclk_target &&
804 rates[i] % params_rate(params) == 0) { 1081 rates[i] % params_rate(params) == 0) {
@@ -955,6 +1232,16 @@ static struct {
955 { 1000000, 13500000, 0, 1 }, 1232 { 1000000, 13500000, 0, 1 },
956}; 1233};
957 1234
1235static struct {
1236 unsigned int min;
1237 unsigned int max;
1238 u16 gain;
1239} fll_gains[] = {
1240 { 0, 256000, 0 },
1241 { 256000, 1000000, 2 },
1242 { 1000000, 13500000, 4 },
1243};
1244
958struct arizona_fll_cfg { 1245struct arizona_fll_cfg {
959 int n; 1246 int n;
960 int theta; 1247 int theta;
@@ -962,6 +1249,7 @@ struct arizona_fll_cfg {
962 int refdiv; 1249 int refdiv;
963 int outdiv; 1250 int outdiv;
964 int fratio; 1251 int fratio;
1252 int gain;
965}; 1253};
966 1254
967static int arizona_calc_fll(struct arizona_fll *fll, 1255static int arizona_calc_fll(struct arizona_fll *fll,
@@ -1021,6 +1309,18 @@ static int arizona_calc_fll(struct arizona_fll *fll,
1021 return -EINVAL; 1309 return -EINVAL;
1022 } 1310 }
1023 1311
1312 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1313 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1314 cfg->gain = fll_gains[i].gain;
1315 break;
1316 }
1317 }
1318 if (i == ARRAY_SIZE(fll_gains)) {
1319 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1320 Fref);
1321 return -EINVAL;
1322 }
1323
1024 cfg->n = target / (ratio * Fref); 1324 cfg->n = target / (ratio * Fref);
1025 1325
1026 if (target % (ratio * Fref)) { 1326 if (target % (ratio * Fref)) {
@@ -1048,13 +1348,15 @@ static int arizona_calc_fll(struct arizona_fll *fll,
1048 cfg->n, cfg->theta, cfg->lambda); 1348 cfg->n, cfg->theta, cfg->lambda);
1049 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", 1349 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1050 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); 1350 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
1351 arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
1051 1352
1052 return 0; 1353 return 0;
1053 1354
1054} 1355}
1055 1356
1056static void arizona_apply_fll(struct arizona *arizona, unsigned int base, 1357static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1057 struct arizona_fll_cfg *cfg, int source) 1358 struct arizona_fll_cfg *cfg, int source,
1359 bool sync)
1058{ 1360{
1059 regmap_update_bits(arizona->regmap, base + 3, 1361 regmap_update_bits(arizona->regmap, base + 3,
1060 ARIZONA_FLL1_THETA_MASK, cfg->theta); 1362 ARIZONA_FLL1_THETA_MASK, cfg->theta);
@@ -1069,87 +1371,84 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1069 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | 1371 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1070 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); 1372 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1071 1373
1374 if (sync)
1375 regmap_update_bits(arizona->regmap, base + 0x7,
1376 ARIZONA_FLL1_GAIN_MASK,
1377 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1378 else
1379 regmap_update_bits(arizona->regmap, base + 0x9,
1380 ARIZONA_FLL1_GAIN_MASK,
1381 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1382
1072 regmap_update_bits(arizona->regmap, base + 2, 1383 regmap_update_bits(arizona->regmap, base + 2,
1073 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, 1384 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1074 ARIZONA_FLL1_CTRL_UPD | cfg->n); 1385 ARIZONA_FLL1_CTRL_UPD | cfg->n);
1075} 1386}
1076 1387
1077int arizona_set_fll(struct arizona_fll *fll, int source, 1388static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1078 unsigned int Fref, unsigned int Fout)
1079{ 1389{
1080 struct arizona *arizona = fll->arizona; 1390 struct arizona *arizona = fll->arizona;
1081 struct arizona_fll_cfg cfg, sync; 1391 unsigned int reg;
1082 unsigned int reg, val;
1083 int syncsrc;
1084 bool ena;
1085 int ret; 1392 int ret;
1086 1393
1087 if (fll->fref == Fref && fll->fout == Fout)
1088 return 0;
1089
1090 ret = regmap_read(arizona->regmap, fll->base + 1, &reg); 1394 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1091 if (ret != 0) { 1395 if (ret != 0) {
1092 arizona_fll_err(fll, "Failed to read current state: %d\n", 1396 arizona_fll_err(fll, "Failed to read current state: %d\n",
1093 ret); 1397 ret);
1094 return ret; 1398 return ret;
1095 } 1399 }
1096 ena = reg & ARIZONA_FLL1_ENA;
1097 1400
1098 if (Fout) { 1401 return reg & ARIZONA_FLL1_ENA;
1099 /* Do we have a 32kHz reference? */ 1402}
1100 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1101 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1102 case ARIZONA_CLK_SRC_MCLK1:
1103 case ARIZONA_CLK_SRC_MCLK2:
1104 syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
1105 break;
1106 default:
1107 syncsrc = -1;
1108 }
1109 1403
1110 if (source == syncsrc) 1404static void arizona_enable_fll(struct arizona_fll *fll,
1111 syncsrc = -1; 1405 struct arizona_fll_cfg *ref,
1406 struct arizona_fll_cfg *sync)
1407{
1408 struct arizona *arizona = fll->arizona;
1409 int ret;
1112 1410
1113 if (syncsrc >= 0) { 1411 /*
1114 ret = arizona_calc_fll(fll, &sync, Fref, Fout); 1412 * If we have both REFCLK and SYNCCLK then enable both,
1115 if (ret != 0) 1413 * otherwise apply the SYNCCLK settings to REFCLK.
1116 return ret; 1414 */
1415 if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) {
1416 regmap_update_bits(arizona->regmap, fll->base + 5,
1417 ARIZONA_FLL1_OUTDIV_MASK,
1418 ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1419
1420 arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
1421 false);
1422 if (fll->sync_src >= 0)
1423 arizona_apply_fll(arizona, fll->base + 0x10, sync,
1424 fll->sync_src, true);
1425 } else if (fll->sync_src >= 0) {
1426 regmap_update_bits(arizona->regmap, fll->base + 5,
1427 ARIZONA_FLL1_OUTDIV_MASK,
1428 sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1429
1430 arizona_apply_fll(arizona, fll->base, sync,
1431 fll->sync_src, false);
1117 1432
1118 ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
1119 if (ret != 0)
1120 return ret;
1121 } else {
1122 ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
1123 if (ret != 0)
1124 return ret;
1125 }
1126 } else {
1127 regmap_update_bits(arizona->regmap, fll->base + 1,
1128 ARIZONA_FLL1_ENA, 0);
1129 regmap_update_bits(arizona->regmap, fll->base + 0x11, 1433 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1130 ARIZONA_FLL1_SYNC_ENA, 0); 1434 ARIZONA_FLL1_SYNC_ENA, 0);
1131
1132 if (ena)
1133 pm_runtime_put_autosuspend(arizona->dev);
1134
1135 fll->fref = Fref;
1136 fll->fout = Fout;
1137
1138 return 0;
1139 }
1140
1141 regmap_update_bits(arizona->regmap, fll->base + 5,
1142 ARIZONA_FLL1_OUTDIV_MASK,
1143 cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1144
1145 if (syncsrc >= 0) {
1146 arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
1147 arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
1148 } else { 1435 } else {
1149 arizona_apply_fll(arizona, fll->base, &cfg, source); 1436 arizona_fll_err(fll, "No clocks provided\n");
1437 return;
1150 } 1438 }
1151 1439
1152 if (!ena) 1440 /*
1441 * Increase the bandwidth if we're not using a low frequency
1442 * sync source.
1443 */
1444 if (fll->sync_src >= 0 && fll->sync_freq > 100000)
1445 regmap_update_bits(arizona->regmap, fll->base + 0x17,
1446 ARIZONA_FLL1_SYNC_BW, 0);
1447 else
1448 regmap_update_bits(arizona->regmap, fll->base + 0x17,
1449 ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW);
1450
1451 if (!arizona_is_enabled_fll(fll))
1153 pm_runtime_get(arizona->dev); 1452 pm_runtime_get(arizona->dev);
1154 1453
1155 /* Clear any pending completions */ 1454 /* Clear any pending completions */
@@ -1157,7 +1456,8 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1157 1456
1158 regmap_update_bits(arizona->regmap, fll->base + 1, 1457 regmap_update_bits(arizona->regmap, fll->base + 1,
1159 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); 1458 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1160 if (syncsrc >= 0) 1459 if (fll->ref_src >= 0 && fll->sync_src >= 0 &&
1460 fll->ref_src != fll->sync_src)
1161 regmap_update_bits(arizona->regmap, fll->base + 0x11, 1461 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1162 ARIZONA_FLL1_SYNC_ENA, 1462 ARIZONA_FLL1_SYNC_ENA,
1163 ARIZONA_FLL1_SYNC_ENA); 1463 ARIZONA_FLL1_SYNC_ENA);
@@ -1166,10 +1466,88 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1166 msecs_to_jiffies(250)); 1466 msecs_to_jiffies(250));
1167 if (ret == 0) 1467 if (ret == 0)
1168 arizona_fll_warn(fll, "Timed out waiting for lock\n"); 1468 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1469}
1470
1471static void arizona_disable_fll(struct arizona_fll *fll)
1472{
1473 struct arizona *arizona = fll->arizona;
1474 bool change;
1475
1476 regmap_update_bits_check(arizona->regmap, fll->base + 1,
1477 ARIZONA_FLL1_ENA, 0, &change);
1478 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1479 ARIZONA_FLL1_SYNC_ENA, 0);
1480
1481 if (change)
1482 pm_runtime_put_autosuspend(arizona->dev);
1483}
1484
1485int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1486 unsigned int Fref, unsigned int Fout)
1487{
1488 struct arizona_fll_cfg ref, sync;
1489 int ret;
1490
1491 if (fll->ref_src == source && fll->ref_freq == Fref)
1492 return 0;
1493
1494 if (fll->fout && Fref > 0) {
1495 ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
1496 if (ret != 0)
1497 return ret;
1498
1499 if (fll->sync_src >= 0) {
1500 ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
1501 fll->fout);
1502 if (ret != 0)
1503 return ret;
1504 }
1505 }
1506
1507 fll->ref_src = source;
1508 fll->ref_freq = Fref;
1169 1509
1170 fll->fref = Fref; 1510 if (fll->fout && Fref > 0) {
1511 arizona_enable_fll(fll, &ref, &sync);
1512 }
1513
1514 return 0;
1515}
1516EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1517
1518int arizona_set_fll(struct arizona_fll *fll, int source,
1519 unsigned int Fref, unsigned int Fout)
1520{
1521 struct arizona_fll_cfg ref, sync;
1522 int ret;
1523
1524 if (fll->sync_src == source &&
1525 fll->sync_freq == Fref && fll->fout == Fout)
1526 return 0;
1527
1528 if (Fout) {
1529 if (fll->ref_src >= 0) {
1530 ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
1531 Fout);
1532 if (ret != 0)
1533 return ret;
1534 }
1535
1536 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1537 if (ret != 0)
1538 return ret;
1539 }
1540
1541 fll->sync_src = source;
1542 fll->sync_freq = Fref;
1171 fll->fout = Fout; 1543 fll->fout = Fout;
1172 1544
1545 if (Fout) {
1546 arizona_enable_fll(fll, &ref, &sync);
1547 } else {
1548 arizona_disable_fll(fll);
1549 }
1550
1173 return 0; 1551 return 0;
1174} 1552}
1175EXPORT_SYMBOL_GPL(arizona_set_fll); 1553EXPORT_SYMBOL_GPL(arizona_set_fll);
@@ -1178,12 +1556,26 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1178 int ok_irq, struct arizona_fll *fll) 1556 int ok_irq, struct arizona_fll *fll)
1179{ 1557{
1180 int ret; 1558 int ret;
1559 unsigned int val;
1181 1560
1182 init_completion(&fll->ok); 1561 init_completion(&fll->ok);
1183 1562
1184 fll->id = id; 1563 fll->id = id;
1185 fll->base = base; 1564 fll->base = base;
1186 fll->arizona = arizona; 1565 fll->arizona = arizona;
1566 fll->sync_src = ARIZONA_FLL_SRC_NONE;
1567
1568 /* Configure default refclk to 32kHz if we have one */
1569 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1570 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1571 case ARIZONA_CLK_SRC_MCLK1:
1572 case ARIZONA_CLK_SRC_MCLK2:
1573 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
1574 break;
1575 default:
1576 fll->ref_src = ARIZONA_FLL_SRC_NONE;
1577 }
1578 fll->ref_freq = 32768;
1187 1579
1188 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); 1580 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1189 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), 1581 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 116372c91f5d..af39f1006427 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -32,6 +32,7 @@
32#define ARIZONA_CLK_SRC_AIF2BCLK 0x9 32#define ARIZONA_CLK_SRC_AIF2BCLK 0x9
33#define ARIZONA_CLK_SRC_AIF3BCLK 0xa 33#define ARIZONA_CLK_SRC_AIF3BCLK 0xa
34 34
35#define ARIZONA_FLL_SRC_NONE -1
35#define ARIZONA_FLL_SRC_MCLK1 0 36#define ARIZONA_FLL_SRC_MCLK1 0
36#define ARIZONA_FLL_SRC_MCLK2 1 37#define ARIZONA_FLL_SRC_MCLK2 1
37#define ARIZONA_FLL_SRC_SLIMCLK 3 38#define ARIZONA_FLL_SRC_SLIMCLK 3
@@ -48,6 +49,14 @@
48#define ARIZONA_MIXER_VOL_SHIFT 1 49#define ARIZONA_MIXER_VOL_SHIFT 1
49#define ARIZONA_MIXER_VOL_WIDTH 7 50#define ARIZONA_MIXER_VOL_WIDTH 7
50 51
52#define ARIZONA_CLK_6MHZ 0
53#define ARIZONA_CLK_12MHZ 1
54#define ARIZONA_CLK_24MHZ 2
55#define ARIZONA_CLK_49MHZ 3
56#define ARIZONA_CLK_73MHZ 4
57#define ARIZONA_CLK_98MHZ 5
58#define ARIZONA_CLK_147MHZ 6
59
51#define ARIZONA_MAX_DAI 4 60#define ARIZONA_MAX_DAI 4
52#define ARIZONA_MAX_ADSP 4 61#define ARIZONA_MAX_ADSP 4
53 62
@@ -64,6 +73,12 @@ struct arizona_priv {
64 int sysclk; 73 int sysclk;
65 int asyncclk; 74 int asyncclk;
66 struct arizona_dai_priv dai[ARIZONA_MAX_DAI]; 75 struct arizona_dai_priv dai[ARIZONA_MAX_DAI];
76
77 int num_inputs;
78 unsigned int in_pending;
79
80 unsigned int spk_ena:2;
81 unsigned int spk_ena_pending:1;
67}; 82};
68 83
69#define ARIZONA_NUM_MIXER_INPUTS 99 84#define ARIZONA_NUM_MIXER_INPUTS 99
@@ -165,6 +180,12 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
165 ARIZONA_MIXER_ROUTES(name, name "L"), \ 180 ARIZONA_MIXER_ROUTES(name, name "L"), \
166 ARIZONA_MIXER_ROUTES(name, name "R") 181 ARIZONA_MIXER_ROUTES(name, name "R")
167 182
183#define ARIZONA_RATE_ENUM_SIZE 4
184extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];
185extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE];
186
187extern const struct soc_enum arizona_isrc_fsl[];
188
168extern const struct soc_enum arizona_in_vi_ramp; 189extern const struct soc_enum arizona_in_vi_ramp;
169extern const struct soc_enum arizona_in_vd_ramp; 190extern const struct soc_enum arizona_in_vd_ramp;
170 191
@@ -184,6 +205,9 @@ extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
184extern int arizona_out_ev(struct snd_soc_dapm_widget *w, 205extern int arizona_out_ev(struct snd_soc_dapm_widget *w,
185 struct snd_kcontrol *kcontrol, 206 struct snd_kcontrol *kcontrol,
186 int event); 207 int event);
208extern int arizona_hp_ev(struct snd_soc_dapm_widget *w,
209 struct snd_kcontrol *kcontrol,
210 int event);
187 211
188extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, 212extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
189 int source, unsigned int freq, int dir); 213 int source, unsigned int freq, int dir);
@@ -198,8 +222,12 @@ struct arizona_fll {
198 unsigned int base; 222 unsigned int base;
199 unsigned int vco_mult; 223 unsigned int vco_mult;
200 struct completion ok; 224 struct completion ok;
201 unsigned int fref; 225
202 unsigned int fout; 226 unsigned int fout;
227 int sync_src;
228 unsigned int sync_freq;
229 int ref_src;
230 unsigned int ref_freq;
203 231
204 char lock_name[ARIZONA_FLL_NAME_LEN]; 232 char lock_name[ARIZONA_FLL_NAME_LEN];
205 char clock_ok_name[ARIZONA_FLL_NAME_LEN]; 233 char clock_ok_name[ARIZONA_FLL_NAME_LEN];
@@ -207,9 +235,13 @@ struct arizona_fll {
207 235
208extern int arizona_init_fll(struct arizona *arizona, int id, int base, 236extern int arizona_init_fll(struct arizona *arizona, int id, int base,
209 int lock_irq, int ok_irq, struct arizona_fll *fll); 237 int lock_irq, int ok_irq, struct arizona_fll *fll);
238extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
239 unsigned int Fref, unsigned int Fout);
210extern int arizona_set_fll(struct arizona_fll *fll, int source, 240extern int arizona_set_fll(struct arizona_fll *fll, int source,
211 unsigned int Fref, unsigned int Fout); 241 unsigned int Fref, unsigned int Fout);
212 242
243extern int arizona_init_spk(struct snd_soc_codec *codec);
244
213extern int arizona_init_dai(struct arizona_priv *priv, int dai); 245extern int arizona_init_dai(struct arizona_priv *priv, int dai);
214 246
215int arizona_set_output_mode(struct snd_soc_codec *codec, int output, 247int arizona_set_output_mode(struct snd_soc_codec *codec, int output,
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 2415a4118dbd..03036b326732 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -39,17 +39,15 @@
39 39
40/* 40/*
41 * CS4271 registers 41 * CS4271 registers
42 * High byte represents SPI chip address (0x10) + write command (0)
43 * Low byte - codec register address
44 */ 42 */
45#define CS4271_MODE1 0x2001 /* Mode Control 1 */ 43#define CS4271_MODE1 0x01 /* Mode Control 1 */
46#define CS4271_DACCTL 0x2002 /* DAC Control */ 44#define CS4271_DACCTL 0x02 /* DAC Control */
47#define CS4271_DACVOL 0x2003 /* DAC Volume & Mixing Control */ 45#define CS4271_DACVOL 0x03 /* DAC Volume & Mixing Control */
48#define CS4271_VOLA 0x2004 /* DAC Channel A Volume Control */ 46#define CS4271_VOLA 0x04 /* DAC Channel A Volume Control */
49#define CS4271_VOLB 0x2005 /* DAC Channel B Volume Control */ 47#define CS4271_VOLB 0x05 /* DAC Channel B Volume Control */
50#define CS4271_ADCCTL 0x2006 /* ADC Control */ 48#define CS4271_ADCCTL 0x06 /* ADC Control */
51#define CS4271_MODE2 0x2007 /* Mode Control 2 */ 49#define CS4271_MODE2 0x07 /* Mode Control 2 */
52#define CS4271_CHIPID 0x2008 /* Chip ID */ 50#define CS4271_CHIPID 0x08 /* Chip ID */
53 51
54#define CS4271_FIRSTREG CS4271_MODE1 52#define CS4271_FIRSTREG CS4271_MODE1
55#define CS4271_LASTREG CS4271_MODE2 53#define CS4271_LASTREG CS4271_MODE2
@@ -144,23 +142,27 @@
144 * Array do not include Chip ID, as codec driver does not use 142 * Array do not include Chip ID, as codec driver does not use
145 * registers read operations at all 143 * registers read operations at all
146 */ 144 */
147static const u8 cs4271_dflt_reg[CS4271_NR_REGS] = { 145static const struct reg_default cs4271_reg_defaults[] = {
148 0, 146 { CS4271_MODE1, 0, },
149 0, 147 { CS4271_DACCTL, CS4271_DACCTL_AMUTE, },
150 CS4271_DACCTL_AMUTE, 148 { CS4271_DACVOL, CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR, },
151 CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR, 149 { CS4271_VOLA, 0, },
152 0, 150 { CS4271_VOLB, 0, },
153 0, 151 { CS4271_ADCCTL, 0, },
154 0, 152 { CS4271_MODE2, 0, },
155 0,
156}; 153};
157 154
155static bool cs4271_volatile_reg(struct device *dev, unsigned int reg)
156{
157 return reg == CS4271_CHIPID;
158}
159
158struct cs4271_private { 160struct cs4271_private {
159 /* SND_SOC_I2C or SND_SOC_SPI */ 161 /* SND_SOC_I2C or SND_SOC_SPI */
160 enum snd_soc_control_type bus_type;
161 unsigned int mclk; 162 unsigned int mclk;
162 bool master; 163 bool master;
163 bool deemph; 164 bool deemph;
165 struct regmap *regmap;
164 /* Current sample rate for de-emphasis control */ 166 /* Current sample rate for de-emphasis control */
165 int rate; 167 int rate;
166 /* GPIO driving Reset pin, if any */ 168 /* GPIO driving Reset pin, if any */
@@ -210,14 +212,14 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
210 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 212 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
211 case SND_SOC_DAIFMT_LEFT_J: 213 case SND_SOC_DAIFMT_LEFT_J:
212 val |= CS4271_MODE1_DAC_DIF_LJ; 214 val |= CS4271_MODE1_DAC_DIF_LJ;
213 ret = snd_soc_update_bits(codec, CS4271_ADCCTL, 215 ret = regmap_update_bits(cs4271->regmap, CS4271_ADCCTL,
214 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ); 216 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ);
215 if (ret < 0) 217 if (ret < 0)
216 return ret; 218 return ret;
217 break; 219 break;
218 case SND_SOC_DAIFMT_I2S: 220 case SND_SOC_DAIFMT_I2S:
219 val |= CS4271_MODE1_DAC_DIF_I2S; 221 val |= CS4271_MODE1_DAC_DIF_I2S;
220 ret = snd_soc_update_bits(codec, CS4271_ADCCTL, 222 ret = regmap_update_bits(cs4271->regmap, CS4271_ADCCTL,
221 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S); 223 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S);
222 if (ret < 0) 224 if (ret < 0)
223 return ret; 225 return ret;
@@ -227,7 +229,7 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
227 return -EINVAL; 229 return -EINVAL;
228 } 230 }
229 231
230 ret = snd_soc_update_bits(codec, CS4271_MODE1, 232 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE1,
231 CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val); 233 CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val);
232 if (ret < 0) 234 if (ret < 0)
233 return ret; 235 return ret;
@@ -252,7 +254,7 @@ static int cs4271_set_deemph(struct snd_soc_codec *codec)
252 val <<= 4; 254 val <<= 4;
253 } 255 }
254 256
255 ret = snd_soc_update_bits(codec, CS4271_DACCTL, 257 ret = regmap_update_bits(cs4271->regmap, CS4271_DACCTL,
256 CS4271_DACCTL_DEM_MASK, val); 258 CS4271_DACCTL_DEM_MASK, val);
257 if (ret < 0) 259 if (ret < 0)
258 return ret; 260 return ret;
@@ -341,14 +343,14 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
341 !dai->capture_active) || 343 !dai->capture_active) ||
342 (substream->stream == SNDRV_PCM_STREAM_CAPTURE && 344 (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
343 !dai->playback_active)) { 345 !dai->playback_active)) {
344 ret = snd_soc_update_bits(codec, CS4271_MODE2, 346 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
345 CS4271_MODE2_PDN, 347 CS4271_MODE2_PDN,
346 CS4271_MODE2_PDN); 348 CS4271_MODE2_PDN);
347 if (ret < 0) 349 if (ret < 0)
348 return ret; 350 return ret;
349 351
350 ret = snd_soc_update_bits(codec, CS4271_MODE2, 352 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
351 CS4271_MODE2_PDN, 0); 353 CS4271_MODE2_PDN, 0);
352 if (ret < 0) 354 if (ret < 0)
353 return ret; 355 return ret;
354 } 356 }
@@ -378,7 +380,7 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
378 380
379 val |= cs4271_clk_tab[i].ratio_mask; 381 val |= cs4271_clk_tab[i].ratio_mask;
380 382
381 ret = snd_soc_update_bits(codec, CS4271_MODE1, 383 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE1,
382 CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val); 384 CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val);
383 if (ret < 0) 385 if (ret < 0)
384 return ret; 386 return ret;
@@ -386,22 +388,29 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
386 return cs4271_set_deemph(codec); 388 return cs4271_set_deemph(codec);
387} 389}
388 390
389static int cs4271_digital_mute(struct snd_soc_dai *dai, int mute) 391static int cs4271_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
390{ 392{
391 struct snd_soc_codec *codec = dai->codec; 393 struct snd_soc_codec *codec = dai->codec;
394 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
392 int ret; 395 int ret;
393 int val_a = 0; 396 int val_a = 0;
394 int val_b = 0; 397 int val_b = 0;
395 398
399 if (stream != SNDRV_PCM_STREAM_PLAYBACK)
400 return 0;
401
396 if (mute) { 402 if (mute) {
397 val_a = CS4271_VOLA_MUTE; 403 val_a = CS4271_VOLA_MUTE;
398 val_b = CS4271_VOLB_MUTE; 404 val_b = CS4271_VOLB_MUTE;
399 } 405 }
400 406
401 ret = snd_soc_update_bits(codec, CS4271_VOLA, CS4271_VOLA_MUTE, val_a); 407 ret = regmap_update_bits(cs4271->regmap, CS4271_VOLA,
408 CS4271_VOLA_MUTE, val_a);
402 if (ret < 0) 409 if (ret < 0)
403 return ret; 410 return ret;
404 ret = snd_soc_update_bits(codec, CS4271_VOLB, CS4271_VOLB_MUTE, val_b); 411
412 ret = regmap_update_bits(cs4271->regmap, CS4271_VOLB,
413 CS4271_VOLB_MUTE, val_b);
405 if (ret < 0) 414 if (ret < 0)
406 return ret; 415 return ret;
407 416
@@ -436,7 +445,7 @@ static const struct snd_soc_dai_ops cs4271_dai_ops = {
436 .hw_params = cs4271_hw_params, 445 .hw_params = cs4271_hw_params,
437 .set_sysclk = cs4271_set_dai_sysclk, 446 .set_sysclk = cs4271_set_dai_sysclk,
438 .set_fmt = cs4271_set_dai_fmt, 447 .set_fmt = cs4271_set_dai_fmt,
439 .digital_mute = cs4271_digital_mute, 448 .mute_stream = cs4271_mute_stream,
440}; 449};
441 450
442static struct snd_soc_dai_driver cs4271_dai = { 451static struct snd_soc_dai_driver cs4271_dai = {
@@ -463,25 +472,33 @@ static struct snd_soc_dai_driver cs4271_dai = {
463static int cs4271_soc_suspend(struct snd_soc_codec *codec) 472static int cs4271_soc_suspend(struct snd_soc_codec *codec)
464{ 473{
465 int ret; 474 int ret;
475 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
476
466 /* Set power-down bit */ 477 /* Set power-down bit */
467 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 478 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
468 CS4271_MODE2_PDN); 479 CS4271_MODE2_PDN, CS4271_MODE2_PDN);
469 if (ret < 0) 480 if (ret < 0)
470 return ret; 481 return ret;
482
471 return 0; 483 return 0;
472} 484}
473 485
474static int cs4271_soc_resume(struct snd_soc_codec *codec) 486static int cs4271_soc_resume(struct snd_soc_codec *codec)
475{ 487{
476 int ret; 488 int ret;
489 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
490
477 /* Restore codec state */ 491 /* Restore codec state */
478 ret = snd_soc_cache_sync(codec); 492 ret = regcache_sync(cs4271->regmap);
479 if (ret < 0) 493 if (ret < 0)
480 return ret; 494 return ret;
495
481 /* then disable the power-down bit */ 496 /* then disable the power-down bit */
482 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0); 497 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
498 CS4271_MODE2_PDN, 0);
483 if (ret < 0) 499 if (ret < 0)
484 return ret; 500 return ret;
501
485 return 0; 502 return 0;
486} 503}
487#else 504#else
@@ -542,40 +559,22 @@ static int cs4271_probe(struct snd_soc_codec *codec)
542 559
543 cs4271->gpio_nreset = gpio_nreset; 560 cs4271->gpio_nreset = gpio_nreset;
544 561
545 /* 562 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
546 * In case of I2C, chip address specified in board data. 563 CS4271_MODE2_PDN | CS4271_MODE2_CPEN,
547 * So cache IO operations use 8 bit codec register address. 564 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
548 * In case of SPI, chip address and register address
549 * passed together as 16 bit value.
550 * Anyway, register address is masked with 0xFF inside
551 * soc-cache code.
552 */
553 if (cs4271->bus_type == SND_SOC_SPI)
554 ret = snd_soc_codec_set_cache_io(codec, 16, 8,
555 cs4271->bus_type);
556 else
557 ret = snd_soc_codec_set_cache_io(codec, 8, 8,
558 cs4271->bus_type);
559 if (ret) {
560 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
561 return ret;
562 }
563
564 ret = snd_soc_update_bits(codec, CS4271_MODE2,
565 CS4271_MODE2_PDN | CS4271_MODE2_CPEN,
566 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
567 if (ret < 0) 565 if (ret < 0)
568 return ret; 566 return ret;
569 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0); 567 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
568 CS4271_MODE2_PDN, 0);
570 if (ret < 0) 569 if (ret < 0)
571 return ret; 570 return ret;
572 /* Power-up sequence requires 85 uS */ 571 /* Power-up sequence requires 85 uS */
573 udelay(85); 572 udelay(85);
574 573
575 if (amutec_eq_bmutec) 574 if (amutec_eq_bmutec)
576 snd_soc_update_bits(codec, CS4271_MODE2, 575 regmap_update_bits(cs4271->regmap, CS4271_MODE2,
577 CS4271_MODE2_MUTECAEQUB, 576 CS4271_MODE2_MUTECAEQUB,
578 CS4271_MODE2_MUTECAEQUB); 577 CS4271_MODE2_MUTECAEQUB);
579 578
580 return snd_soc_add_codec_controls(codec, cs4271_snd_controls, 579 return snd_soc_add_codec_controls(codec, cs4271_snd_controls,
581 ARRAY_SIZE(cs4271_snd_controls)); 580 ARRAY_SIZE(cs4271_snd_controls));
@@ -597,13 +596,24 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
597 .remove = cs4271_remove, 596 .remove = cs4271_remove,
598 .suspend = cs4271_soc_suspend, 597 .suspend = cs4271_soc_suspend,
599 .resume = cs4271_soc_resume, 598 .resume = cs4271_soc_resume,
600 .reg_cache_default = cs4271_dflt_reg,
601 .reg_cache_size = ARRAY_SIZE(cs4271_dflt_reg),
602 .reg_word_size = sizeof(cs4271_dflt_reg[0]),
603 .compress_type = SND_SOC_FLAT_COMPRESSION,
604}; 599};
605 600
606#if defined(CONFIG_SPI_MASTER) 601#if defined(CONFIG_SPI_MASTER)
602
603static const struct regmap_config cs4271_spi_regmap = {
604 .reg_bits = 16,
605 .val_bits = 8,
606 .max_register = CS4271_LASTREG,
607 .read_flag_mask = 0x21,
608 .write_flag_mask = 0x20,
609
610 .reg_defaults = cs4271_reg_defaults,
611 .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults),
612 .cache_type = REGCACHE_RBTREE,
613
614 .volatile_reg = cs4271_volatile_reg,
615};
616
607static int cs4271_spi_probe(struct spi_device *spi) 617static int cs4271_spi_probe(struct spi_device *spi)
608{ 618{
609 struct cs4271_private *cs4271; 619 struct cs4271_private *cs4271;
@@ -613,7 +623,9 @@ static int cs4271_spi_probe(struct spi_device *spi)
613 return -ENOMEM; 623 return -ENOMEM;
614 624
615 spi_set_drvdata(spi, cs4271); 625 spi_set_drvdata(spi, cs4271);
616 cs4271->bus_type = SND_SOC_SPI; 626 cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap);
627 if (IS_ERR(cs4271->regmap))
628 return PTR_ERR(cs4271->regmap);
617 629
618 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271, 630 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271,
619 &cs4271_dai, 1); 631 &cs4271_dai, 1);
@@ -643,6 +655,18 @@ static const struct i2c_device_id cs4271_i2c_id[] = {
643}; 655};
644MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id); 656MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id);
645 657
658static const struct regmap_config cs4271_i2c_regmap = {
659 .reg_bits = 8,
660 .val_bits = 8,
661 .max_register = CS4271_LASTREG,
662
663 .reg_defaults = cs4271_reg_defaults,
664 .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults),
665 .cache_type = REGCACHE_RBTREE,
666
667 .volatile_reg = cs4271_volatile_reg,
668};
669
646static int cs4271_i2c_probe(struct i2c_client *client, 670static int cs4271_i2c_probe(struct i2c_client *client,
647 const struct i2c_device_id *id) 671 const struct i2c_device_id *id)
648{ 672{
@@ -653,7 +677,9 @@ static int cs4271_i2c_probe(struct i2c_client *client,
653 return -ENOMEM; 677 return -ENOMEM;
654 678
655 i2c_set_clientdata(client, cs4271); 679 i2c_set_clientdata(client, cs4271);
656 cs4271->bus_type = SND_SOC_I2C; 680 cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap);
681 if (IS_ERR(cs4271->regmap))
682 return PTR_ERR(cs4271->regmap);
657 683
658 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271, 684 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271,
659 &cs4271_dai, 1); 685 &cs4271_dai, 1);
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index 6361dab48bd1..3b20c86cdb01 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -1180,7 +1180,11 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
1180 priv->config[id].mmcc &= 0xC0; 1180 priv->config[id].mmcc &= 0xC0;
1181 priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; 1181 priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc;
1182 priv->config[id].spc &= 0xFC; 1182 priv->config[id].spc &= 0xFC;
1183 priv->config[id].spc |= MCK_SCLK_MCLK; 1183 /* Use SCLK=64*Fs if internal MCLK >= 6.4MHz */
1184 if (priv->mclk >= 6400000)
1185 priv->config[id].spc |= MCK_SCLK_64FS;
1186 else
1187 priv->config[id].spc |= MCK_SCLK_MCLK;
1184 } else { 1188 } else {
1185 /* CS42L73 Slave */ 1189 /* CS42L73 Slave */
1186 priv->config[id].spc &= 0xFC; 1190 priv->config[id].spc &= 0xFC;
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index a4c16fd70f77..3a7b7fd14e3e 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -739,14 +739,32 @@ static const unsigned int max98088_micboost_tlv[] = {
739 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), 739 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
740}; 740};
741 741
742static const unsigned int max98088_hp_tlv[] = {
743 TLV_DB_RANGE_HEAD(5),
744 0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0),
745 7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0),
746 15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0),
747 22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0),
748 28, 31, TLV_DB_SCALE_ITEM(150, 50, 0),
749};
750
751static const unsigned int max98088_spk_tlv[] = {
752 TLV_DB_RANGE_HEAD(5),
753 0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0),
754 7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0),
755 15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0),
756 22, 27, TLV_DB_SCALE_ITEM(100, 100, 0),
757 28, 31, TLV_DB_SCALE_ITEM(650, 50, 0),
758};
759
742static const struct snd_kcontrol_new max98088_snd_controls[] = { 760static const struct snd_kcontrol_new max98088_snd_controls[] = {
743 761
744 SOC_DOUBLE_R("Headphone Volume", M98088_REG_39_LVL_HP_L, 762 SOC_DOUBLE_R_TLV("Headphone Volume", M98088_REG_39_LVL_HP_L,
745 M98088_REG_3A_LVL_HP_R, 0, 31, 0), 763 M98088_REG_3A_LVL_HP_R, 0, 31, 0, max98088_hp_tlv),
746 SOC_DOUBLE_R("Speaker Volume", M98088_REG_3D_LVL_SPK_L, 764 SOC_DOUBLE_R_TLV("Speaker Volume", M98088_REG_3D_LVL_SPK_L,
747 M98088_REG_3E_LVL_SPK_R, 0, 31, 0), 765 M98088_REG_3E_LVL_SPK_R, 0, 31, 0, max98088_spk_tlv),
748 SOC_DOUBLE_R("Receiver Volume", M98088_REG_3B_LVL_REC_L, 766 SOC_DOUBLE_R_TLV("Receiver Volume", M98088_REG_3B_LVL_REC_L,
749 M98088_REG_3C_LVL_REC_R, 0, 31, 0), 767 M98088_REG_3C_LVL_REC_R, 0, 31, 0, max98088_spk_tlv),
750 768
751 SOC_DOUBLE_R("Headphone Switch", M98088_REG_39_LVL_HP_L, 769 SOC_DOUBLE_R("Headphone Switch", M98088_REG_39_LVL_HP_L,
752 M98088_REG_3A_LVL_HP_R, 7, 1, 1), 770 M98088_REG_3A_LVL_HP_R, 7, 1, 1),
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index fc176044994d..ce0d36412c97 100755..100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -23,8 +23,6 @@
23#include <sound/max98090.h> 23#include <sound/max98090.h>
24#include "max98090.h" 24#include "max98090.h"
25 25
26#include <linux/version.h>
27
28#define DEBUG 26#define DEBUG
29#define EXTMIC_METHOD 27#define EXTMIC_METHOD
30#define EXTMIC_METHOD_TEST 28#define EXTMIC_METHOD_TEST
@@ -509,16 +507,16 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol,
509 return 0; 507 return 0;
510} 508}
511 509
512static const char * max98090_perf_pwr_text[] = 510static const char *max98090_perf_pwr_text[] =
513 { "High Performance", "Low Power" }; 511 { "High Performance", "Low Power" };
514static const char * max98090_pwr_perf_text[] = 512static const char *max98090_pwr_perf_text[] =
515 { "Low Power", "High Performance" }; 513 { "Low Power", "High Performance" };
516 514
517static const struct soc_enum max98090_vcmbandgap_enum = 515static const struct soc_enum max98090_vcmbandgap_enum =
518 SOC_ENUM_SINGLE(M98090_REG_BIAS_CONTROL, M98090_VCM_MODE_SHIFT, 516 SOC_ENUM_SINGLE(M98090_REG_BIAS_CONTROL, M98090_VCM_MODE_SHIFT,
519 ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); 517 ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text);
520 518
521static const char * max98090_osr128_text[] = { "64*fs", "128*fs" }; 519static const char *max98090_osr128_text[] = { "64*fs", "128*fs" };
522 520
523static const struct soc_enum max98090_osr128_enum = 521static const struct soc_enum max98090_osr128_enum =
524 SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_OSR128_SHIFT, 522 SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_OSR128_SHIFT,
@@ -535,28 +533,28 @@ static const struct soc_enum max98090_filter_dmic34mode_enum =
535 M98090_FLT_DMIC34MODE_SHIFT, 533 M98090_FLT_DMIC34MODE_SHIFT,
536 ARRAY_SIZE(max98090_mode_text), max98090_mode_text); 534 ARRAY_SIZE(max98090_mode_text), max98090_mode_text);
537 535
538static const char * max98090_drcatk_text[] = 536static const char *max98090_drcatk_text[] =
539 { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" }; 537 { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" };
540 538
541static const struct soc_enum max98090_drcatk_enum = 539static const struct soc_enum max98090_drcatk_enum =
542 SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCATK_SHIFT, 540 SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCATK_SHIFT,
543 ARRAY_SIZE(max98090_drcatk_text), max98090_drcatk_text); 541 ARRAY_SIZE(max98090_drcatk_text), max98090_drcatk_text);
544 542
545static const char * max98090_drcrls_text[] = 543static const char *max98090_drcrls_text[] =
546 { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" }; 544 { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" };
547 545
548static const struct soc_enum max98090_drcrls_enum = 546static const struct soc_enum max98090_drcrls_enum =
549 SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCRLS_SHIFT, 547 SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCRLS_SHIFT,
550 ARRAY_SIZE(max98090_drcrls_text), max98090_drcrls_text); 548 ARRAY_SIZE(max98090_drcrls_text), max98090_drcrls_text);
551 549
552static const char * max98090_alccmp_text[] = 550static const char *max98090_alccmp_text[] =
553 { "1:1", "1:1.5", "1:2", "1:4", "1:INF" }; 551 { "1:1", "1:1.5", "1:2", "1:4", "1:INF" };
554 552
555static const struct soc_enum max98090_alccmp_enum = 553static const struct soc_enum max98090_alccmp_enum =
556 SOC_ENUM_SINGLE(M98090_REG_DRC_COMPRESSOR, M98090_DRCCMP_SHIFT, 554 SOC_ENUM_SINGLE(M98090_REG_DRC_COMPRESSOR, M98090_DRCCMP_SHIFT,
557 ARRAY_SIZE(max98090_alccmp_text), max98090_alccmp_text); 555 ARRAY_SIZE(max98090_alccmp_text), max98090_alccmp_text);
558 556
559static const char * max98090_drcexp_text[] = { "1:1", "2:1", "3:1" }; 557static const char *max98090_drcexp_text[] = { "1:1", "2:1", "3:1" };
560 558
561static const struct soc_enum max98090_drcexp_enum = 559static const struct soc_enum max98090_drcexp_enum =
562 SOC_ENUM_SINGLE(M98090_REG_DRC_EXPANDER, M98090_DRCEXP_SHIFT, 560 SOC_ENUM_SINGLE(M98090_REG_DRC_EXPANDER, M98090_DRCEXP_SHIFT,
@@ -859,7 +857,7 @@ static const struct soc_enum mic2_mux_enum =
859static const struct snd_kcontrol_new max98090_mic2_mux = 857static const struct snd_kcontrol_new max98090_mic2_mux =
860 SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum); 858 SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum);
861 859
862static const char * max98090_micpre_text[] = { "Off", "On" }; 860static const char *max98090_micpre_text[] = { "Off", "On" };
863 861
864static const struct soc_enum max98090_pa1en_enum = 862static const struct soc_enum max98090_pa1en_enum =
865 SOC_ENUM_SINGLE(M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT, 863 SOC_ENUM_SINGLE(M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT,
@@ -1703,9 +1701,8 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
1703 * seen for the case of TDM mode. The remaining cases have 1701 * seen for the case of TDM mode. The remaining cases have
1704 * normal logic. 1702 * normal logic.
1705 */ 1703 */
1706 if (max98090->tdm_slots > 1) { 1704 if (max98090->tdm_slots > 1)
1707 regval ^= M98090_BCI_MASK; 1705 regval ^= M98090_BCI_MASK;
1708 }
1709 1706
1710 snd_soc_write(codec, 1707 snd_soc_write(codec,
1711 M98090_REG_INTERFACE_FORMAT, regval); 1708 M98090_REG_INTERFACE_FORMAT, regval);
@@ -2059,17 +2056,14 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
2059 if (!active) 2056 if (!active)
2060 return IRQ_NONE; 2057 return IRQ_NONE;
2061 2058
2062 if (active & M98090_CLD_MASK) { 2059 if (active & M98090_CLD_MASK)
2063 dev_err(codec->dev, "M98090_CLD_MASK\n"); 2060 dev_err(codec->dev, "M98090_CLD_MASK\n");
2064 }
2065 2061
2066 if (active & M98090_SLD_MASK) { 2062 if (active & M98090_SLD_MASK)
2067 dev_dbg(codec->dev, "M98090_SLD_MASK\n"); 2063 dev_dbg(codec->dev, "M98090_SLD_MASK\n");
2068 }
2069 2064
2070 if (active & M98090_ULK_MASK) { 2065 if (active & M98090_ULK_MASK)
2071 dev_err(codec->dev, "M98090_ULK_MASK\n"); 2066 dev_err(codec->dev, "M98090_ULK_MASK\n");
2072 }
2073 2067
2074 if (active & M98090_JDET_MASK) { 2068 if (active & M98090_JDET_MASK) {
2075 dev_dbg(codec->dev, "M98090_JDET_MASK\n"); 2069 dev_dbg(codec->dev, "M98090_JDET_MASK\n");
@@ -2080,13 +2074,11 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
2080 msecs_to_jiffies(100)); 2074 msecs_to_jiffies(100));
2081 } 2075 }
2082 2076
2083 if (active & M98090_DRCACT_MASK) { 2077 if (active & M98090_DRCACT_MASK)
2084 dev_dbg(codec->dev, "M98090_DRCACT_MASK\n"); 2078 dev_dbg(codec->dev, "M98090_DRCACT_MASK\n");
2085 }
2086 2079
2087 if (active & M98090_DRCCLP_MASK) { 2080 if (active & M98090_DRCCLP_MASK)
2088 dev_err(codec->dev, "M98090_DRCCLP_MASK\n"); 2081 dev_err(codec->dev, "M98090_DRCCLP_MASK\n");
2089 }
2090 2082
2091 return IRQ_HANDLED; 2083 return IRQ_HANDLED;
2092} 2084}
@@ -2324,7 +2316,7 @@ static int max98090_i2c_probe(struct i2c_client *i2c,
2324 max98090->pdata = i2c->dev.platform_data; 2316 max98090->pdata = i2c->dev.platform_data;
2325 max98090->irq = i2c->irq; 2317 max98090->irq = i2c->irq;
2326 2318
2327 max98090->regmap = regmap_init_i2c(i2c, &max98090_regmap); 2319 max98090->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap);
2328 if (IS_ERR(max98090->regmap)) { 2320 if (IS_ERR(max98090->regmap)) {
2329 ret = PTR_ERR(max98090->regmap); 2321 ret = PTR_ERR(max98090->regmap);
2330 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); 2322 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
@@ -2334,18 +2326,13 @@ static int max98090_i2c_probe(struct i2c_client *i2c,
2334 ret = snd_soc_register_codec(&i2c->dev, 2326 ret = snd_soc_register_codec(&i2c->dev,
2335 &soc_codec_dev_max98090, max98090_dai, 2327 &soc_codec_dev_max98090, max98090_dai,
2336 ARRAY_SIZE(max98090_dai)); 2328 ARRAY_SIZE(max98090_dai));
2337 if (ret < 0)
2338 regmap_exit(max98090->regmap);
2339
2340err_enable: 2329err_enable:
2341 return ret; 2330 return ret;
2342} 2331}
2343 2332
2344static int max98090_i2c_remove(struct i2c_client *client) 2333static int max98090_i2c_remove(struct i2c_client *client)
2345{ 2334{
2346 struct max98090_priv *max98090 = dev_get_drvdata(&client->dev);
2347 snd_soc_unregister_codec(&client->dev); 2335 snd_soc_unregister_codec(&client->dev);
2348 regmap_exit(max98090->regmap);
2349 return 0; 2336 return 0;
2350} 2337}
2351 2338
@@ -2369,7 +2356,7 @@ static int max98090_runtime_suspend(struct device *dev)
2369 return 0; 2356 return 0;
2370} 2357}
2371 2358
2372static struct dev_pm_ops max98090_pm = { 2359static const struct dev_pm_ops max98090_pm = {
2373 SET_RUNTIME_PM_OPS(max98090_runtime_suspend, 2360 SET_RUNTIME_PM_OPS(max98090_runtime_suspend,
2374 max98090_runtime_resume, NULL) 2361 max98090_runtime_resume, NULL)
2375}; 2362};
diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h
index 7e103f249053..7e103f249053 100755..100644
--- a/sound/soc/codecs/max98090.h
+++ b/sound/soc/codecs/max98090.h
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
index f2d61a187830..721587c9cd84 100644
--- a/sound/soc/codecs/si476x.c
+++ b/sound/soc/codecs/si476x.c
@@ -1,3 +1,22 @@
1/*
2 * sound/soc/codecs/si476x.c -- Codec driver for SI476X chips
3 *
4 * Copyright (C) 2012 Innovative Converged Devices(ICD)
5 * Copyright (C) 2013 Andrey Smirnov
6 *
7 * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
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 as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 */
19
1#include <linux/module.h> 20#include <linux/module.h>
2#include <linux/slab.h> 21#include <linux/slab.h>
3#include <sound/pcm.h> 22#include <sound/pcm.h>
@@ -45,13 +64,23 @@ static unsigned int si476x_codec_read(struct snd_soc_codec *codec,
45 unsigned int reg) 64 unsigned int reg)
46{ 65{
47 int err; 66 int err;
67 unsigned int val;
48 struct si476x_core *core = codec->control_data; 68 struct si476x_core *core = codec->control_data;
49 69
50 si476x_core_lock(core); 70 si476x_core_lock(core);
51 err = si476x_core_cmd_get_property(core, reg); 71 if (!si476x_core_is_powered_up(core))
72 regcache_cache_only(core->regmap, true);
73
74 err = regmap_read(core->regmap, reg, &val);
75
76 if (!si476x_core_is_powered_up(core))
77 regcache_cache_only(core->regmap, false);
52 si476x_core_unlock(core); 78 si476x_core_unlock(core);
53 79
54 return err; 80 if (err < 0)
81 return err;
82
83 return val;
55} 84}
56 85
57static int si476x_codec_write(struct snd_soc_codec *codec, 86static int si476x_codec_write(struct snd_soc_codec *codec,
@@ -61,7 +90,13 @@ static int si476x_codec_write(struct snd_soc_codec *codec,
61 struct si476x_core *core = codec->control_data; 90 struct si476x_core *core = codec->control_data;
62 91
63 si476x_core_lock(core); 92 si476x_core_lock(core);
64 err = si476x_core_cmd_set_property(core, reg, val); 93 if (!si476x_core_is_powered_up(core))
94 regcache_cache_only(core->regmap, true);
95
96 err = regmap_write(core->regmap, reg, val);
97
98 if (!si476x_core_is_powered_up(core))
99 regcache_cache_only(core->regmap, false);
65 si476x_core_unlock(core); 100 si476x_core_unlock(core);
66 101
67 return err; 102 return err;
@@ -140,7 +175,7 @@ static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
140 dev_err(codec_dai->codec->dev, "Failed to set output format\n"); 175 dev_err(codec_dai->codec->dev, "Failed to set output format\n");
141 return err; 176 return err;
142 } 177 }
143 178
144 return 0; 179 return 0;
145} 180}
146 181
@@ -159,6 +194,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
159 switch (params_format(params)) { 194 switch (params_format(params)) {
160 case SNDRV_PCM_FORMAT_S8: 195 case SNDRV_PCM_FORMAT_S8:
161 width = SI476X_PCM_FORMAT_S8; 196 width = SI476X_PCM_FORMAT_S8;
197 break;
162 case SNDRV_PCM_FORMAT_S16_LE: 198 case SNDRV_PCM_FORMAT_S16_LE:
163 width = SI476X_PCM_FORMAT_S16_LE; 199 width = SI476X_PCM_FORMAT_S16_LE;
164 break; 200 break;
@@ -181,7 +217,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
181 217
182 err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, 218 err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
183 SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK, 219 SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK,
184 (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | 220 (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) |
185 (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)); 221 (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT));
186 if (err < 0) { 222 if (err < 0) {
187 dev_err(dai->codec->dev, "Failed to set output width\n"); 223 dev_err(dai->codec->dev, "Failed to set output width\n");
@@ -250,6 +286,6 @@ static struct platform_driver si476x_platform_driver = {
250}; 286};
251module_platform_driver(si476x_platform_driver); 287module_platform_driver(si476x_platform_driver);
252 288
253MODULE_AUTHOR("Andrey Smirnov <andrey.smirnov@convergeddevices.net>"); 289MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
254MODULE_DESCRIPTION("ASoC Si4761/64 codec driver"); 290MODULE_DESCRIPTION("ASoC Si4761/64 codec driver");
255MODULE_LICENSE("GPL"); 291MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index ddc98f02ecbd..57ba315d0c84 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -1565,7 +1565,7 @@ static int wm2200_probe(struct snd_soc_codec *codec)
1565 return ret; 1565 return ret;
1566 } 1566 }
1567 1567
1568 ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2); 1568 ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2);
1569 if (ret != 0) 1569 if (ret != 0)
1570 return ret; 1570 return ret;
1571 1571
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index b82bbf584146..e895d3939eef 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -36,9 +36,6 @@
36struct wm5102_priv { 36struct wm5102_priv {
37 struct arizona_priv core; 37 struct arizona_priv core;
38 struct arizona_fll fll[2]; 38 struct arizona_fll fll[2];
39
40 unsigned int spk_ena:2;
41 unsigned int spk_ena_pending:1;
42}; 39};
43 40
44static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); 41static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
@@ -584,7 +581,7 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
584 struct snd_kcontrol *kcontrol, int event) 581 struct snd_kcontrol *kcontrol, int event)
585{ 582{
586 struct snd_soc_codec *codec = w->codec; 583 struct snd_soc_codec *codec = w->codec;
587 struct arizona *arizona = dev_get_drvdata(codec->dev); 584 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
588 struct regmap *regmap = codec->control_data; 585 struct regmap *regmap = codec->control_data;
589 const struct reg_default *patch = NULL; 586 const struct reg_default *patch = NULL;
590 int i, patch_size; 587 int i, patch_size;
@@ -615,6 +612,26 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
615 return 0; 612 return 0;
616} 613}
617 614
615static const char *wm5102_osr_text[] = {
616 "Low power", "Normal", "High performance",
617};
618
619static const unsigned int wm5102_osr_val[] = {
620 0x0, 0x3, 0x5,
621};
622
623static const struct soc_enum wm5102_hpout_osr[] = {
624 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
625 ARIZONA_OUT1_OSR_SHIFT, 0x7, 3,
626 wm5102_osr_text, wm5102_osr_val),
627 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
628 ARIZONA_OUT2_OSR_SHIFT, 0x7, 3,
629 wm5102_osr_text, wm5102_osr_val),
630 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
631 ARIZONA_OUT3_OSR_SHIFT, 0x7, 3,
632 wm5102_osr_text, wm5102_osr_val),
633};
634
618#define WM5102_NG_SRC(name, base) \ 635#define WM5102_NG_SRC(name, base) \
619 SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \ 636 SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \
620 SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \ 637 SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \
@@ -745,6 +762,9 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
745SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), 762SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
746SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), 763SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
747 764
765SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]),
766SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]),
767
748ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), 768ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
749ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), 769ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
750 770
@@ -761,6 +781,8 @@ ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
761ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), 781ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
762ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), 782ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
763 783
784SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
785 ARIZONA_OUT4_OSR_SHIFT, 1, 0),
764SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, 786SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
765 ARIZONA_OUT5_OSR_SHIFT, 1, 0), 787 ARIZONA_OUT5_OSR_SHIFT, 1, 0),
766 788
@@ -790,6 +812,10 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
790 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 812 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
791 0xbf, 0, digital_tlv), 813 0xbf, 0, digital_tlv),
792 814
815SOC_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]),
816SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]),
817SOC_VALUE_ENUM("HPOUT3 OSR", wm5102_hpout_osr[2]),
818
793SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), 819SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
794SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), 820SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
795 821
@@ -828,47 +854,6 @@ ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
828ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), 854ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
829}; 855};
830 856
831static int wm5102_spk_ev(struct snd_soc_dapm_widget *w,
832 struct snd_kcontrol *kcontrol,
833 int event)
834{
835 struct snd_soc_codec *codec = w->codec;
836 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
837 struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec);
838
839 if (arizona->rev < 1)
840 return 0;
841
842 switch (event) {
843 case SND_SOC_DAPM_PRE_PMU:
844 if (!wm5102->spk_ena) {
845 snd_soc_write(codec, 0x4f5, 0x25a);
846 wm5102->spk_ena_pending = true;
847 }
848 break;
849 case SND_SOC_DAPM_POST_PMU:
850 if (wm5102->spk_ena_pending) {
851 msleep(75);
852 snd_soc_write(codec, 0x4f5, 0xda);
853 wm5102->spk_ena_pending = false;
854 wm5102->spk_ena++;
855 }
856 break;
857 case SND_SOC_DAPM_PRE_PMD:
858 wm5102->spk_ena--;
859 if (!wm5102->spk_ena)
860 snd_soc_write(codec, 0x4f5, 0x25a);
861 break;
862 case SND_SOC_DAPM_POST_PMD:
863 if (!wm5102->spk_ena)
864 snd_soc_write(codec, 0x4f5, 0x0da);
865 break;
866 }
867
868 return 0;
869}
870
871
872ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); 857ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
873ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); 858ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
874ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); 859ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE);
@@ -984,22 +969,28 @@ SND_SOC_DAPM_INPUT("IN3R"),
984 969
985SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 970SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
986 0, NULL, 0, arizona_in_ev, 971 0, NULL, 0, arizona_in_ev,
987 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 972 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
973 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
988SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, 974SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
989 0, NULL, 0, arizona_in_ev, 975 0, NULL, 0, arizona_in_ev,
990 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 976 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
977 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
991SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, 978SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
992 0, NULL, 0, arizona_in_ev, 979 0, NULL, 0, arizona_in_ev,
993 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 980 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
981 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
994SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, 982SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
995 0, NULL, 0, arizona_in_ev, 983 0, NULL, 0, arizona_in_ev,
996 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 984 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
985 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
997SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, 986SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
998 0, NULL, 0, arizona_in_ev, 987 0, NULL, 0, arizona_in_ev,
999 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 988 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
989 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1000SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, 990SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
1001 0, NULL, 0, arizona_in_ev, 991 0, NULL, 0, arizona_in_ev,
1002 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 992 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
993 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1003 994
1004SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, 995SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
1005 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), 996 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
@@ -1131,11 +1122,11 @@ ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),
1131SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, 1122SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
1132 ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), 1123 ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux),
1133 1124
1134SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, 1125SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
1135 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1126 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
1136 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1127 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1137SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1, 1128SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
1138 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1129 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
1139 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1130 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1140SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, 1131SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
1141 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1132 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
@@ -1146,12 +1137,6 @@ SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
1146SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, 1137SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
1147 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1138 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
1148 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1139 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1149SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
1150 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev,
1151 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1152SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1,
1153 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev,
1154 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1155SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, 1140SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
1156 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1141 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
1157 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1142 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
@@ -1494,6 +1479,12 @@ static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1494 return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout); 1479 return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout);
1495 case WM5102_FLL2: 1480 case WM5102_FLL2:
1496 return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout); 1481 return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout);
1482 case WM5102_FLL1_REFCLK:
1483 return arizona_set_fll_refclk(&wm5102->fll[0], source, Fref,
1484 Fout);
1485 case WM5102_FLL2_REFCLK:
1486 return arizona_set_fll_refclk(&wm5102->fll[1], source, Fref,
1487 Fout);
1497 default: 1488 default:
1498 return -EINVAL; 1489 return -EINVAL;
1499 } 1490 }
@@ -1581,10 +1572,12 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
1581 if (ret != 0) 1572 if (ret != 0)
1582 return ret; 1573 return ret;
1583 1574
1584 ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 1); 1575 ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2);
1585 if (ret != 0) 1576 if (ret != 0)
1586 return ret; 1577 return ret;
1587 1578
1579 arizona_init_spk(codec);
1580
1588 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); 1581 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
1589 1582
1590 priv->core.arizona->dapm = &codec->dapm; 1583 priv->core.arizona->dapm = &codec->dapm;
@@ -1604,13 +1597,6 @@ static int wm5102_codec_remove(struct snd_soc_codec *codec)
1604#define WM5102_DIG_VU 0x0200 1597#define WM5102_DIG_VU 0x0200
1605 1598
1606static unsigned int wm5102_digital_vu[] = { 1599static unsigned int wm5102_digital_vu[] = {
1607 ARIZONA_ADC_DIGITAL_VOLUME_1L,
1608 ARIZONA_ADC_DIGITAL_VOLUME_1R,
1609 ARIZONA_ADC_DIGITAL_VOLUME_2L,
1610 ARIZONA_ADC_DIGITAL_VOLUME_2R,
1611 ARIZONA_ADC_DIGITAL_VOLUME_3L,
1612 ARIZONA_ADC_DIGITAL_VOLUME_3R,
1613
1614 ARIZONA_DAC_DIGITAL_VOLUME_1L, 1600 ARIZONA_DAC_DIGITAL_VOLUME_1L,
1615 ARIZONA_DAC_DIGITAL_VOLUME_1R, 1601 ARIZONA_DAC_DIGITAL_VOLUME_1R,
1616 ARIZONA_DAC_DIGITAL_VOLUME_2L, 1602 ARIZONA_DAC_DIGITAL_VOLUME_2L,
@@ -1653,6 +1639,7 @@ static int wm5102_probe(struct platform_device *pdev)
1653 platform_set_drvdata(pdev, wm5102); 1639 platform_set_drvdata(pdev, wm5102);
1654 1640
1655 wm5102->core.arizona = arizona; 1641 wm5102->core.arizona = arizona;
1642 wm5102->core.num_inputs = 6;
1656 1643
1657 wm5102->core.adsp[0].part = "wm5102"; 1644 wm5102->core.adsp[0].part = "wm5102";
1658 wm5102->core.adsp[0].num = 1; 1645 wm5102->core.adsp[0].num = 1;
@@ -1677,6 +1664,12 @@ static int wm5102_probe(struct platform_device *pdev)
1677 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK, 1664 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
1678 &wm5102->fll[1]); 1665 &wm5102->fll[1]);
1679 1666
1667 /* SR2 fixed at 8kHz, SR3 fixed at 16kHz */
1668 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2,
1669 ARIZONA_SAMPLE_RATE_2_MASK, 0x11);
1670 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3,
1671 ARIZONA_SAMPLE_RATE_3_MASK, 0x12);
1672
1680 for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++) 1673 for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++)
1681 arizona_init_dai(&wm5102->core, i); 1674 arizona_init_dai(&wm5102->core, i);
1682 1675
diff --git a/sound/soc/codecs/wm5102.h b/sound/soc/codecs/wm5102.h
index d30477f3070c..adb38040f661 100644
--- a/sound/soc/codecs/wm5102.h
+++ b/sound/soc/codecs/wm5102.h
@@ -15,7 +15,9 @@
15 15
16#include "arizona.h" 16#include "arizona.h"
17 17
18#define WM5102_FLL1 1 18#define WM5102_FLL1 1
19#define WM5102_FLL2 2 19#define WM5102_FLL2 2
20#define WM5102_FLL1_REFCLK 3
21#define WM5102_FLL2_REFCLK 4
20 22
21#endif 23#endif
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index cdeb301da1f6..731884e04776 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -416,28 +416,36 @@ SND_SOC_DAPM_INPUT("IN4R"),
416 416
417SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 417SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
418 0, NULL, 0, arizona_in_ev, 418 0, NULL, 0, arizona_in_ev,
419 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 419 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
420 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
420SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, 421SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
421 0, NULL, 0, arizona_in_ev, 422 0, NULL, 0, arizona_in_ev,
422 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 423 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
424 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
423SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, 425SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
424 0, NULL, 0, arizona_in_ev, 426 0, NULL, 0, arizona_in_ev,
425 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 427 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
428 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
426SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, 429SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
427 0, NULL, 0, arizona_in_ev, 430 0, NULL, 0, arizona_in_ev,
428 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 431 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
432 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
429SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, 433SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
430 0, NULL, 0, arizona_in_ev, 434 0, NULL, 0, arizona_in_ev,
431 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 435 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
436 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
432SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, 437SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
433 0, NULL, 0, arizona_in_ev, 438 0, NULL, 0, arizona_in_ev,
434 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 439 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
440 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
435SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT, 441SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT,
436 0, NULL, 0, arizona_in_ev, 442 0, NULL, 0, arizona_in_ev,
437 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 443 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
444 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
438SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT, 445SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT,
439 0, NULL, 0, arizona_in_ev, 446 0, NULL, 0, arizona_in_ev,
440 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 447 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
448 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
441 449
442SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, 450SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
443 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), 451 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
@@ -551,11 +559,11 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
551SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, 559SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
552 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), 560 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
553 561
554SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, 562SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
555 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 563 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
556 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 564 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
557SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1, 565SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
558 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 566 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
559 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 567 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
560SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, 568SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
561 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 569 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
@@ -569,12 +577,6 @@ SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
569SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1, 577SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1,
570 ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 578 ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
571 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 579 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
572SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
573 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
574 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
575SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1,
576 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
577 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
578SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, 580SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
579 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 581 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
580 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 582 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
@@ -880,6 +882,12 @@ static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
880 return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout); 882 return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout);
881 case WM5110_FLL2: 883 case WM5110_FLL2:
882 return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout); 884 return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout);
885 case WM5110_FLL1_REFCLK:
886 return arizona_set_fll_refclk(&wm5110->fll[0], source, Fref,
887 Fout);
888 case WM5110_FLL2_REFCLK:
889 return arizona_set_fll_refclk(&wm5110->fll[1], source, Fref,
890 Fout);
883 default: 891 default:
884 return -EINVAL; 892 return -EINVAL;
885 } 893 }
@@ -987,15 +995,6 @@ static int wm5110_codec_remove(struct snd_soc_codec *codec)
987#define WM5110_DIG_VU 0x0200 995#define WM5110_DIG_VU 0x0200
988 996
989static unsigned int wm5110_digital_vu[] = { 997static unsigned int wm5110_digital_vu[] = {
990 ARIZONA_ADC_DIGITAL_VOLUME_1L,
991 ARIZONA_ADC_DIGITAL_VOLUME_1R,
992 ARIZONA_ADC_DIGITAL_VOLUME_2L,
993 ARIZONA_ADC_DIGITAL_VOLUME_2R,
994 ARIZONA_ADC_DIGITAL_VOLUME_3L,
995 ARIZONA_ADC_DIGITAL_VOLUME_3R,
996 ARIZONA_ADC_DIGITAL_VOLUME_4L,
997 ARIZONA_ADC_DIGITAL_VOLUME_4R,
998
999 ARIZONA_DAC_DIGITAL_VOLUME_1L, 998 ARIZONA_DAC_DIGITAL_VOLUME_1L,
1000 ARIZONA_DAC_DIGITAL_VOLUME_1R, 999 ARIZONA_DAC_DIGITAL_VOLUME_1R,
1001 ARIZONA_DAC_DIGITAL_VOLUME_2L, 1000 ARIZONA_DAC_DIGITAL_VOLUME_2L,
@@ -1040,6 +1039,7 @@ static int wm5110_probe(struct platform_device *pdev)
1040 platform_set_drvdata(pdev, wm5110); 1039 platform_set_drvdata(pdev, wm5110);
1041 1040
1042 wm5110->core.arizona = arizona; 1041 wm5110->core.arizona = arizona;
1042 wm5110->core.num_inputs = 8;
1043 1043
1044 for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++) 1044 for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++)
1045 wm5110->fll[i].vco_mult = 3; 1045 wm5110->fll[i].vco_mult = 3;
diff --git a/sound/soc/codecs/wm5110.h b/sound/soc/codecs/wm5110.h
index 75e9351ccab0..e6c0cd4235c5 100644
--- a/sound/soc/codecs/wm5110.h
+++ b/sound/soc/codecs/wm5110.h
@@ -15,7 +15,9 @@
15 15
16#include "arizona.h" 16#include "arizona.h"
17 17
18#define WM5110_FLL1 1 18#define WM5110_FLL1 1
19#define WM5110_FLL2 2 19#define WM5110_FLL2 2
20#define WM5110_FLL1_REFCLK 3
21#define WM5110_FLL2_REFCLK 4
20 22
21#endif 23#endif
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 134e41c870b9..f8a31ad0b203 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1083,6 +1083,8 @@ static const struct snd_soc_dapm_route wm8903_intercon[] = {
1083 { "ROP", NULL, "Right Speaker PGA" }, 1083 { "ROP", NULL, "Right Speaker PGA" },
1084 { "RON", NULL, "Right Speaker PGA" }, 1084 { "RON", NULL, "Right Speaker PGA" },
1085 1085
1086 { "Charge Pump", NULL, "CLK_DSP" },
1087
1086 { "Left Headphone Output PGA", NULL, "Charge Pump" }, 1088 { "Left Headphone Output PGA", NULL, "Charge Pump" },
1087 { "Right Headphone Output PGA", NULL, "Charge Pump" }, 1089 { "Right Headphone Output PGA", NULL, "Charge Pump" },
1088 { "Left Line Output PGA", NULL, "Charge Pump" }, 1090 { "Left Line Output PGA", NULL, "Charge Pump" },
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index f3f7e75f8628..3470b649c0b2 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -31,6 +31,7 @@
31 31
32#include <linux/mfd/arizona/registers.h> 32#include <linux/mfd/arizona/registers.h>
33 33
34#include "arizona.h"
34#include "wm_adsp.h" 35#include "wm_adsp.h"
35 36
36#define adsp_crit(_dsp, fmt, ...) \ 37#define adsp_crit(_dsp, fmt, ...) \
@@ -193,17 +194,25 @@ static void wm_adsp_buf_free(struct list_head *list)
193 194
194#define WM_ADSP_NUM_FW 4 195#define WM_ADSP_NUM_FW 4
195 196
197#define WM_ADSP_FW_MBC_VSS 0
198#define WM_ADSP_FW_TX 1
199#define WM_ADSP_FW_TX_SPK 2
200#define WM_ADSP_FW_RX_ANC 3
201
196static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { 202static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = {
197 "MBC/VSS", "Tx", "Tx Speaker", "Rx ANC" 203 [WM_ADSP_FW_MBC_VSS] = "MBC/VSS",
204 [WM_ADSP_FW_TX] = "Tx",
205 [WM_ADSP_FW_TX_SPK] = "Tx Speaker",
206 [WM_ADSP_FW_RX_ANC] = "Rx ANC",
198}; 207};
199 208
200static struct { 209static struct {
201 const char *file; 210 const char *file;
202} wm_adsp_fw[WM_ADSP_NUM_FW] = { 211} wm_adsp_fw[WM_ADSP_NUM_FW] = {
203 { .file = "mbc-vss" }, 212 [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" },
204 { .file = "tx" }, 213 [WM_ADSP_FW_TX] = { .file = "tx" },
205 { .file = "tx-spk" }, 214 [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" },
206 { .file = "rx-anc" }, 215 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" },
207}; 216};
208 217
209static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, 218static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
@@ -246,17 +255,52 @@ static const struct soc_enum wm_adsp_fw_enum[] = {
246 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 255 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
247}; 256};
248 257
249const struct snd_kcontrol_new wm_adsp_fw_controls[] = { 258const struct snd_kcontrol_new wm_adsp1_fw_controls[] = {
259 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
260 wm_adsp_fw_get, wm_adsp_fw_put),
261 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
262 wm_adsp_fw_get, wm_adsp_fw_put),
263 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
264 wm_adsp_fw_get, wm_adsp_fw_put),
265};
266EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls);
267
268#if IS_ENABLED(CONFIG_SND_SOC_ARIZONA)
269static const struct soc_enum wm_adsp2_rate_enum[] = {
270 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
271 ARIZONA_DSP1_RATE_SHIFT, 0xf,
272 ARIZONA_RATE_ENUM_SIZE,
273 arizona_rate_text, arizona_rate_val),
274 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
275 ARIZONA_DSP1_RATE_SHIFT, 0xf,
276 ARIZONA_RATE_ENUM_SIZE,
277 arizona_rate_text, arizona_rate_val),
278 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
279 ARIZONA_DSP1_RATE_SHIFT, 0xf,
280 ARIZONA_RATE_ENUM_SIZE,
281 arizona_rate_text, arizona_rate_val),
282 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
283 ARIZONA_DSP1_RATE_SHIFT, 0xf,
284 ARIZONA_RATE_ENUM_SIZE,
285 arizona_rate_text, arizona_rate_val),
286};
287
288const struct snd_kcontrol_new wm_adsp2_fw_controls[] = {
250 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], 289 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
251 wm_adsp_fw_get, wm_adsp_fw_put), 290 wm_adsp_fw_get, wm_adsp_fw_put),
291 SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]),
252 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], 292 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
253 wm_adsp_fw_get, wm_adsp_fw_put), 293 wm_adsp_fw_get, wm_adsp_fw_put),
294 SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]),
254 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], 295 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
255 wm_adsp_fw_get, wm_adsp_fw_put), 296 wm_adsp_fw_get, wm_adsp_fw_put),
297 SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]),
256 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], 298 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
257 wm_adsp_fw_get, wm_adsp_fw_put), 299 wm_adsp_fw_get, wm_adsp_fw_put),
300 SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]),
258}; 301};
259EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); 302EXPORT_SYMBOL_GPL(wm_adsp2_fw_controls);
303#endif
260 304
261static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, 305static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
262 int type) 306 int type)
@@ -549,13 +593,30 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
549 buf_size = sizeof(adsp1_id); 593 buf_size = sizeof(adsp1_id);
550 594
551 algs = be32_to_cpu(adsp1_id.algs); 595 algs = be32_to_cpu(adsp1_id.algs);
596 dsp->fw_id = be32_to_cpu(adsp1_id.fw.id);
552 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", 597 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n",
553 be32_to_cpu(adsp1_id.fw.id), 598 dsp->fw_id,
554 (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16, 599 (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16,
555 (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8, 600 (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8,
556 be32_to_cpu(adsp1_id.fw.ver) & 0xff, 601 be32_to_cpu(adsp1_id.fw.ver) & 0xff,
557 algs); 602 algs);
558 603
604 region = kzalloc(sizeof(*region), GFP_KERNEL);
605 if (!region)
606 return -ENOMEM;
607 region->type = WMFW_ADSP1_ZM;
608 region->alg = be32_to_cpu(adsp1_id.fw.id);
609 region->base = be32_to_cpu(adsp1_id.zm);
610 list_add_tail(&region->list, &dsp->alg_regions);
611
612 region = kzalloc(sizeof(*region), GFP_KERNEL);
613 if (!region)
614 return -ENOMEM;
615 region->type = WMFW_ADSP1_DM;
616 region->alg = be32_to_cpu(adsp1_id.fw.id);
617 region->base = be32_to_cpu(adsp1_id.dm);
618 list_add_tail(&region->list, &dsp->alg_regions);
619
559 pos = sizeof(adsp1_id) / 2; 620 pos = sizeof(adsp1_id) / 2;
560 term = pos + ((sizeof(*adsp1_alg) * algs) / 2); 621 term = pos + ((sizeof(*adsp1_alg) * algs) / 2);
561 break; 622 break;
@@ -573,13 +634,38 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
573 buf_size = sizeof(adsp2_id); 634 buf_size = sizeof(adsp2_id);
574 635
575 algs = be32_to_cpu(adsp2_id.algs); 636 algs = be32_to_cpu(adsp2_id.algs);
637 dsp->fw_id = be32_to_cpu(adsp2_id.fw.id);
576 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", 638 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n",
577 be32_to_cpu(adsp2_id.fw.id), 639 dsp->fw_id,
578 (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16, 640 (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16,
579 (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8, 641 (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8,
580 be32_to_cpu(adsp2_id.fw.ver) & 0xff, 642 be32_to_cpu(adsp2_id.fw.ver) & 0xff,
581 algs); 643 algs);
582 644
645 region = kzalloc(sizeof(*region), GFP_KERNEL);
646 if (!region)
647 return -ENOMEM;
648 region->type = WMFW_ADSP2_XM;
649 region->alg = be32_to_cpu(adsp2_id.fw.id);
650 region->base = be32_to_cpu(adsp2_id.xm);
651 list_add_tail(&region->list, &dsp->alg_regions);
652
653 region = kzalloc(sizeof(*region), GFP_KERNEL);
654 if (!region)
655 return -ENOMEM;
656 region->type = WMFW_ADSP2_YM;
657 region->alg = be32_to_cpu(adsp2_id.fw.id);
658 region->base = be32_to_cpu(adsp2_id.ym);
659 list_add_tail(&region->list, &dsp->alg_regions);
660
661 region = kzalloc(sizeof(*region), GFP_KERNEL);
662 if (!region)
663 return -ENOMEM;
664 region->type = WMFW_ADSP2_ZM;
665 region->alg = be32_to_cpu(adsp2_id.fw.id);
666 region->base = be32_to_cpu(adsp2_id.zm);
667 list_add_tail(&region->list, &dsp->alg_regions);
668
583 pos = sizeof(adsp2_id) / 2; 669 pos = sizeof(adsp2_id) / 2;
584 term = pos + ((sizeof(*adsp2_alg) * algs) / 2); 670 term = pos + ((sizeof(*adsp2_alg) * algs) / 2);
585 break; 671 break;
@@ -781,8 +867,24 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
781 case (WMFW_INFO_TEXT << 8): 867 case (WMFW_INFO_TEXT << 8):
782 break; 868 break;
783 case (WMFW_ABSOLUTE << 8): 869 case (WMFW_ABSOLUTE << 8):
784 region_name = "register"; 870 /*
785 reg = offset; 871 * Old files may use this for global
872 * coefficients.
873 */
874 if (le32_to_cpu(blk->id) == dsp->fw_id &&
875 offset == 0) {
876 region_name = "global coefficients";
877 mem = wm_adsp_find_region(dsp, type);
878 if (!mem) {
879 adsp_err(dsp, "No ZM\n");
880 break;
881 }
882 reg = wm_adsp_region_to_reg(mem, 0);
883
884 } else {
885 region_name = "register";
886 reg = offset;
887 }
786 break; 888 break;
787 889
788 case WMFW_ADSP1_DM: 890 case WMFW_ADSP1_DM:
@@ -828,7 +930,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
828 &buf_list); 930 &buf_list);
829 if (!buf) { 931 if (!buf) {
830 adsp_err(dsp, "Out of memory\n"); 932 adsp_err(dsp, "Out of memory\n");
831 return -ENOMEM; 933 ret = -ENOMEM;
934 goto out_fw;
832 } 935 }
833 936
834 adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", 937 adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n",
@@ -865,7 +968,7 @@ out_fw:
865 wm_adsp_buf_free(&buf_list); 968 wm_adsp_buf_free(&buf_list);
866out: 969out:
867 kfree(file); 970 kfree(file);
868 return 0; 971 return ret;
869} 972}
870 973
871int wm_adsp1_init(struct wm_adsp *adsp) 974int wm_adsp1_init(struct wm_adsp *adsp)
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index cb8871a3ec00..fea514627526 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -46,6 +46,8 @@ struct wm_adsp {
46 46
47 struct list_head alg_regions; 47 struct list_head alg_regions;
48 48
49 int fw_id;
50
49 const struct wm_adsp_region *mem; 51 const struct wm_adsp_region *mem;
50 int num_mems; 52 int num_mems;
51 53
@@ -65,7 +67,8 @@ struct wm_adsp {
65 .shift = num, .event = wm_adsp2_event, \ 67 .shift = num, .event = wm_adsp2_event, \
66 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } 68 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
67 69
68extern const struct snd_kcontrol_new wm_adsp_fw_controls[]; 70extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];
71extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];
69 72
70int wm_adsp1_init(struct wm_adsp *adsp); 73int wm_adsp1_init(struct wm_adsp *adsp);
71int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); 74int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs);
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 821831207180..ebe82947bab3 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -645,6 +645,10 @@ static struct snd_soc_dai_driver davinci_i2s_dai = {
645 645
646}; 646};
647 647
648static const struct snd_soc_component_driver davinci_i2s_component = {
649 .name = "davinci-i2s",
650};
651
648static int davinci_i2s_probe(struct platform_device *pdev) 652static int davinci_i2s_probe(struct platform_device *pdev)
649{ 653{
650 struct snd_platform_data *pdata = pdev->dev.platform_data; 654 struct snd_platform_data *pdata = pdev->dev.platform_data;
@@ -727,20 +731,21 @@ static int davinci_i2s_probe(struct platform_device *pdev)
727 731
728 dev_set_drvdata(&pdev->dev, dev); 732 dev_set_drvdata(&pdev->dev, dev);
729 733
730 ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai); 734 ret = snd_soc_register_component(&pdev->dev, &davinci_i2s_component,
735 &davinci_i2s_dai, 1);
731 if (ret != 0) 736 if (ret != 0)
732 goto err_release_clk; 737 goto err_release_clk;
733 738
734 ret = davinci_soc_platform_register(&pdev->dev); 739 ret = davinci_soc_platform_register(&pdev->dev);
735 if (ret) { 740 if (ret) {
736 dev_err(&pdev->dev, "register PCM failed: %d\n", ret); 741 dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
737 goto err_unregister_dai; 742 goto err_unregister_component;
738 } 743 }
739 744
740 return 0; 745 return 0;
741 746
742err_unregister_dai: 747err_unregister_component:
743 snd_soc_unregister_dai(&pdev->dev); 748 snd_soc_unregister_component(&pdev->dev);
744err_release_clk: 749err_release_clk:
745 clk_disable(dev->clk); 750 clk_disable(dev->clk);
746 clk_put(dev->clk); 751 clk_put(dev->clk);
@@ -751,7 +756,7 @@ static int davinci_i2s_remove(struct platform_device *pdev)
751{ 756{
752 struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); 757 struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
753 758
754 snd_soc_unregister_dai(&pdev->dev); 759 snd_soc_unregister_component(&pdev->dev);
755 davinci_soc_platform_unregister(&pdev->dev); 760 davinci_soc_platform_unregister(&pdev->dev);
756 761
757 clk_disable(dev->clk); 762 clk_disable(dev->clk);
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 9321e5c9d8c1..aeb3a6627d6a 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -235,6 +235,8 @@
235#define DISMOD (val)(val<<2) 235#define DISMOD (val)(val<<2)
236#define TXSTATE BIT(4) 236#define TXSTATE BIT(4)
237#define RXSTATE BIT(5) 237#define RXSTATE BIT(5)
238#define SRMOD_MASK 3
239#define SRMOD_INACTIVE 0
238 240
239/* 241/*
240 * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits 242 * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits
@@ -643,26 +645,33 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,
643 /* mapping of the XSSZ bit-field as described in the datasheet */ 645 /* mapping of the XSSZ bit-field as described in the datasheet */
644 fmt = (word_length >> 1) - 1; 646 fmt = (word_length >> 1) - 1;
645 647
646 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, 648 if (dev->op_mode != DAVINCI_MCASP_DIT_MODE) {
647 RXSSZ(fmt), RXSSZ(0x0F)); 649 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
648 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, 650 RXSSZ(fmt), RXSSZ(0x0F));
649 TXSSZ(fmt), TXSSZ(0x0F)); 651 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
650 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate), 652 TXSSZ(fmt), TXSSZ(0x0F));
651 TXROT(7)); 653 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
652 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXROT(rotate), 654 TXROT(rotate), TXROT(7));
653 RXROT(7)); 655 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
656 RXROT(rotate), RXROT(7));
657 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG,
658 mask);
659 }
660
654 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask); 661 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask);
655 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, mask);
656 662
657 return 0; 663 return 0;
658} 664}
659 665
660static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) 666static int davinci_hw_common_param(struct davinci_audio_dev *dev, int stream,
667 int channels)
661{ 668{
662 int i; 669 int i;
663 u8 tx_ser = 0; 670 u8 tx_ser = 0;
664 u8 rx_ser = 0; 671 u8 rx_ser = 0;
665 672 u8 ser;
673 u8 slots = dev->tdm_slots;
674 u8 max_active_serializers = (channels + slots - 1) / slots;
666 /* Default configuration */ 675 /* Default configuration */
667 mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); 676 mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
668 677
@@ -682,17 +691,33 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
682 for (i = 0; i < dev->num_serializer; i++) { 691 for (i = 0; i < dev->num_serializer; i++) {
683 mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), 692 mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i),
684 dev->serial_dir[i]); 693 dev->serial_dir[i]);
685 if (dev->serial_dir[i] == TX_MODE) { 694 if (dev->serial_dir[i] == TX_MODE &&
695 tx_ser < max_active_serializers) {
686 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, 696 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
687 AXR(i)); 697 AXR(i));
688 tx_ser++; 698 tx_ser++;
689 } else if (dev->serial_dir[i] == RX_MODE) { 699 } else if (dev->serial_dir[i] == RX_MODE &&
700 rx_ser < max_active_serializers) {
690 mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, 701 mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
691 AXR(i)); 702 AXR(i));
692 rx_ser++; 703 rx_ser++;
704 } else {
705 mcasp_mod_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i),
706 SRMOD_INACTIVE, SRMOD_MASK);
693 } 707 }
694 } 708 }
695 709
710 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
711 ser = tx_ser;
712 else
713 ser = rx_ser;
714
715 if (ser < max_active_serializers) {
716 dev_warn(dev->dev, "stream has more channels (%d) than are "
717 "enabled in mcasp (%d)\n", channels, ser * slots);
718 return -EINVAL;
719 }
720
696 if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { 721 if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) {
697 if (dev->txnumevt * tx_ser > 64) 722 if (dev->txnumevt * tx_ser > 64)
698 dev->txnumevt = 1; 723 dev->txnumevt = 1;
@@ -729,6 +754,8 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
729 ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); 754 ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
730 } 755 }
731 } 756 }
757
758 return 0;
732} 759}
733 760
734static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) 761static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
@@ -772,12 +799,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
772/* S/PDIF */ 799/* S/PDIF */
773static void davinci_hw_dit_param(struct davinci_audio_dev *dev) 800static void davinci_hw_dit_param(struct davinci_audio_dev *dev)
774{ 801{
775 /* Set the PDIR for Serialiser as output */
776 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AFSX);
777
778 /* TXMASK for 24 bits */
779 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0x00FFFFFF);
780
781 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 802 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
782 and LSB first */ 803 and LSB first */
783 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, 804 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
@@ -812,8 +833,14 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
812 &dev->dma_params[substream->stream]; 833 &dev->dma_params[substream->stream];
813 int word_length; 834 int word_length;
814 u8 fifo_level; 835 u8 fifo_level;
836 u8 slots = dev->tdm_slots;
837 int channels;
838 struct snd_interval *pcm_channels = hw_param_interval(params,
839 SNDRV_PCM_HW_PARAM_CHANNELS);
840 channels = pcm_channels->min;
815 841
816 davinci_hw_common_param(dev, substream->stream); 842 if (davinci_hw_common_param(dev, substream->stream, channels) == -EINVAL)
843 return -EINVAL;
817 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 844 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
818 fifo_level = dev->txnumevt; 845 fifo_level = dev->txnumevt;
819 else 846 else
@@ -862,6 +889,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
862 dma_params->acnt = dma_params->data_type; 889 dma_params->acnt = dma_params->data_type;
863 890
864 dma_params->fifo_level = fifo_level; 891 dma_params->fifo_level = fifo_level;
892 dma_params->active_serializers = (channels + slots - 1) / slots;
865 davinci_config_channel_size(dev, word_length); 893 davinci_config_channel_size(dev, word_length);
866 894
867 return 0; 895 return 0;
@@ -936,13 +964,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
936 .name = "davinci-mcasp.0", 964 .name = "davinci-mcasp.0",
937 .playback = { 965 .playback = {
938 .channels_min = 2, 966 .channels_min = 2,
939 .channels_max = 2, 967 .channels_max = 32 * 16,
940 .rates = DAVINCI_MCASP_RATES, 968 .rates = DAVINCI_MCASP_RATES,
941 .formats = DAVINCI_MCASP_PCM_FMTS, 969 .formats = DAVINCI_MCASP_PCM_FMTS,
942 }, 970 },
943 .capture = { 971 .capture = {
944 .channels_min = 2, 972 .channels_min = 2,
945 .channels_max = 2, 973 .channels_max = 32 * 16,
946 .rates = DAVINCI_MCASP_RATES, 974 .rates = DAVINCI_MCASP_RATES,
947 .formats = DAVINCI_MCASP_PCM_FMTS, 975 .formats = DAVINCI_MCASP_PCM_FMTS,
948 }, 976 },
@@ -962,6 +990,10 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
962 990
963}; 991};
964 992
993static const struct snd_soc_component_driver davinci_mcasp_component = {
994 .name = "davinci-mcasp",
995};
996
965static const struct of_device_id mcasp_dt_ids[] = { 997static const struct of_device_id mcasp_dt_ids[] = {
966 { 998 {
967 .compatible = "ti,dm646x-mcasp-audio", 999 .compatible = "ti,dm646x-mcasp-audio",
@@ -1015,8 +1047,16 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
1015 pdata->op_mode = val; 1047 pdata->op_mode = val;
1016 1048
1017 ret = of_property_read_u32(np, "tdm-slots", &val); 1049 ret = of_property_read_u32(np, "tdm-slots", &val);
1018 if (ret >= 0) 1050 if (ret >= 0) {
1051 if (val < 2 || val > 32) {
1052 dev_err(&pdev->dev,
1053 "tdm-slots must be in rage [2-32]\n");
1054 ret = -EINVAL;
1055 goto nodata;
1056 }
1057
1019 pdata->tdm_slots = val; 1058 pdata->tdm_slots = val;
1059 }
1020 1060
1021 ret = of_property_read_u32(np, "num-serializer", &val); 1061 ret = of_property_read_u32(np, "num-serializer", &val);
1022 if (ret >= 0) 1062 if (ret >= 0)
@@ -1170,7 +1210,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1170 1210
1171 dma_data->channel = res->start; 1211 dma_data->channel = res->start;
1172 dev_set_drvdata(&pdev->dev, dev); 1212 dev_set_drvdata(&pdev->dev, dev);
1173 ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]); 1213 ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component,
1214 &davinci_mcasp_dai[pdata->op_mode], 1);
1174 1215
1175 if (ret != 0) 1216 if (ret != 0)
1176 goto err_release_clk; 1217 goto err_release_clk;
@@ -1178,13 +1219,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1178 ret = davinci_soc_platform_register(&pdev->dev); 1219 ret = davinci_soc_platform_register(&pdev->dev);
1179 if (ret) { 1220 if (ret) {
1180 dev_err(&pdev->dev, "register PCM failed: %d\n", ret); 1221 dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
1181 goto err_unregister_dai; 1222 goto err_unregister_component;
1182 } 1223 }
1183 1224
1184 return 0; 1225 return 0;
1185 1226
1186err_unregister_dai: 1227err_unregister_component:
1187 snd_soc_unregister_dai(&pdev->dev); 1228 snd_soc_unregister_component(&pdev->dev);
1188err_release_clk: 1229err_release_clk:
1189 pm_runtime_put_sync(&pdev->dev); 1230 pm_runtime_put_sync(&pdev->dev);
1190 pm_runtime_disable(&pdev->dev); 1231 pm_runtime_disable(&pdev->dev);
@@ -1194,7 +1235,7 @@ err_release_clk:
1194static int davinci_mcasp_remove(struct platform_device *pdev) 1235static int davinci_mcasp_remove(struct platform_device *pdev)
1195{ 1236{
1196 1237
1197 snd_soc_unregister_dai(&pdev->dev); 1238 snd_soc_unregister_component(&pdev->dev);
1198 davinci_soc_platform_unregister(&pdev->dev); 1239 davinci_soc_platform_unregister(&pdev->dev);
1199 1240
1200 pm_runtime_put_sync(&pdev->dev); 1241 pm_runtime_put_sync(&pdev->dev);
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index afab81f844ae..078031d61167 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -181,6 +181,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
181 unsigned short acnt; 181 unsigned short acnt;
182 unsigned int count; 182 unsigned int count;
183 unsigned int fifo_level; 183 unsigned int fifo_level;
184 unsigned char serializers = prtd->params->active_serializers;
184 185
185 period_size = snd_pcm_lib_period_bytes(substream); 186 period_size = snd_pcm_lib_period_bytes(substream);
186 dma_offset = prtd->period * period_size; 187 dma_offset = prtd->period * period_size;
@@ -194,14 +195,14 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
194 data_type = prtd->params->data_type; 195 data_type = prtd->params->data_type;
195 count = period_size / data_type; 196 count = period_size / data_type;
196 if (fifo_level) 197 if (fifo_level)
197 count /= fifo_level; 198 count /= fifo_level * serializers;
198 199
199 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 200 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
200 src = dma_pos; 201 src = dma_pos;
201 dst = prtd->params->dma_addr; 202 dst = prtd->params->dma_addr;
202 src_bidx = data_type; 203 src_bidx = data_type;
203 dst_bidx = 0; 204 dst_bidx = 4;
204 src_cidx = data_type * fifo_level; 205 src_cidx = data_type * fifo_level * serializers;
205 dst_cidx = 0; 206 dst_cidx = 0;
206 } else { 207 } else {
207 src = prtd->params->dma_addr; 208 src = prtd->params->dma_addr;
@@ -209,7 +210,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
209 src_bidx = 0; 210 src_bidx = 0;
210 dst_bidx = data_type; 211 dst_bidx = data_type;
211 src_cidx = 0; 212 src_cidx = 0;
212 dst_cidx = data_type * fifo_level; 213 dst_cidx = data_type * fifo_level * serializers;
213 } 214 }
214 215
215 acnt = prtd->params->acnt; 216 acnt = prtd->params->acnt;
@@ -223,9 +224,10 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
223 edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, 224 edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
224 ASYNC); 225 ASYNC);
225 else 226 else
226 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, 227 edma_set_transfer_params(prtd->asp_link[0], acnt,
227 count, fifo_level, 228 fifo_level * serializers,
228 ABSYNC); 229 count, fifo_level * serializers,
230 ABSYNC);
229} 231}
230 232
231static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) 233static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index b6ef7039dd09..32d7634d7b26 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -27,6 +27,7 @@ struct davinci_pcm_dma_params {
27 unsigned char data_type; /* xfer data type */ 27 unsigned char data_type; /* xfer data type */
28 unsigned char convert_mono_stereo; 28 unsigned char convert_mono_stereo;
29 unsigned int fifo_level; 29 unsigned int fifo_level;
30 unsigned char active_serializers; /* num. of active audio serializers */
30}; 31};
31 32
32int davinci_soc_platform_register(struct device *dev); 33int davinci_soc_platform_register(struct device *dev);
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index 07bde2e6f84e..30587c0cdbd2 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -204,6 +204,10 @@ static struct snd_soc_dai_driver davinci_vcif_dai = {
204 204
205}; 205};
206 206
207static const struct snd_soc_component_driver davinci_vcif_component = {
208 .name = "davinci-vcif",
209};
210
207static int davinci_vcif_probe(struct platform_device *pdev) 211static int davinci_vcif_probe(struct platform_device *pdev)
208{ 212{
209 struct davinci_vc *davinci_vc = pdev->dev.platform_data; 213 struct davinci_vc *davinci_vc = pdev->dev.platform_data;
@@ -234,7 +238,8 @@ static int davinci_vcif_probe(struct platform_device *pdev)
234 238
235 dev_set_drvdata(&pdev->dev, davinci_vcif_dev); 239 dev_set_drvdata(&pdev->dev, davinci_vcif_dev);
236 240
237 ret = snd_soc_register_dai(&pdev->dev, &davinci_vcif_dai); 241 ret = snd_soc_register_component(&pdev->dev, &davinci_vcif_component,
242 &davinci_vcif_dai, 1);
238 if (ret != 0) { 243 if (ret != 0) {
239 dev_err(&pdev->dev, "could not register dai\n"); 244 dev_err(&pdev->dev, "could not register dai\n");
240 return ret; 245 return ret;
@@ -243,7 +248,7 @@ static int davinci_vcif_probe(struct platform_device *pdev)
243 ret = davinci_soc_platform_register(&pdev->dev); 248 ret = davinci_soc_platform_register(&pdev->dev);
244 if (ret) { 249 if (ret) {
245 dev_err(&pdev->dev, "register PCM failed: %d\n", ret); 250 dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
246 snd_soc_unregister_dai(&pdev->dev); 251 snd_soc_unregister_component(&pdev->dev);
247 return ret; 252 return ret;
248 } 253 }
249 254
@@ -252,7 +257,7 @@ static int davinci_vcif_probe(struct platform_device *pdev)
252 257
253static int davinci_vcif_remove(struct platform_device *pdev) 258static int davinci_vcif_remove(struct platform_device *pdev)
254{ 259{
255 snd_soc_unregister_dai(&pdev->dev); 260 snd_soc_unregister_component(&pdev->dev);
256 davinci_soc_platform_unregister(&pdev->dev); 261 davinci_soc_platform_unregister(&pdev->dev);
257 262
258 return 0; 263 return 0;
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index deb30d59965e..593a3ea12d4c 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -297,6 +297,10 @@ static struct snd_soc_dai_ops dw_i2s_dai_ops = {
297 .trigger = dw_i2s_trigger, 297 .trigger = dw_i2s_trigger,
298}; 298};
299 299
300static const struct snd_soc_component_driver dw_i2s_component = {
301 .name = "dw-i2s",
302};
303
300#ifdef CONFIG_PM 304#ifdef CONFIG_PM
301 305
302static int dw_i2s_suspend(struct snd_soc_dai *dai) 306static int dw_i2s_suspend(struct snd_soc_dai *dai)
@@ -413,7 +417,8 @@ static int dw_i2s_probe(struct platform_device *pdev)
413 417
414 dev->dev = &pdev->dev; 418 dev->dev = &pdev->dev;
415 dev_set_drvdata(&pdev->dev, dev); 419 dev_set_drvdata(&pdev->dev, dev);
416 ret = snd_soc_register_dai(&pdev->dev, dw_i2s_dai); 420 ret = snd_soc_register_component(&pdev->dev, &dw_i2s_component,
421 dw_i2s_dai, 1);
417 if (ret != 0) { 422 if (ret != 0) {
418 dev_err(&pdev->dev, "not able to register dai\n"); 423 dev_err(&pdev->dev, "not able to register dai\n");
419 goto err_set_drvdata; 424 goto err_set_drvdata;
@@ -434,7 +439,7 @@ static int dw_i2s_remove(struct platform_device *pdev)
434{ 439{
435 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); 440 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
436 441
437 snd_soc_unregister_dai(&pdev->dev); 442 snd_soc_unregister_component(&pdev->dev);
438 dev_set_drvdata(&pdev->dev, NULL); 443 dev_set_drvdata(&pdev->dev, NULL);
439 444
440 clk_put(dev->clk); 445 clk_put(dev->clk);
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 7decbd9b2340..42366d776f62 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -27,6 +27,7 @@
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/initval.h> 28#include <sound/initval.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/dmaengine_pcm.h>
30 31
31#include "fsl_ssi.h" 32#include "fsl_ssi.h"
32#include "imx-pcm.h" 33#include "imx-pcm.h"
@@ -122,8 +123,10 @@ struct fsl_ssi_private {
122 bool ssi_on_imx; 123 bool ssi_on_imx;
123 struct clk *clk; 124 struct clk *clk;
124 struct platform_device *imx_pcm_pdev; 125 struct platform_device *imx_pcm_pdev;
125 struct imx_pcm_dma_params dma_params_tx; 126 struct snd_dmaengine_dai_dma_data dma_params_tx;
126 struct imx_pcm_dma_params dma_params_rx; 127 struct snd_dmaengine_dai_dma_data dma_params_rx;
128 struct imx_dma_data filter_data_tx;
129 struct imx_dma_data filter_data_rx;
127 130
128 struct { 131 struct {
129 unsigned int rfrc; 132 unsigned int rfrc;
@@ -574,6 +577,10 @@ static struct snd_soc_dai_driver fsl_ssi_dai_template = {
574 .ops = &fsl_ssi_dai_ops, 577 .ops = &fsl_ssi_dai_ops,
575}; 578};
576 579
580static const struct snd_soc_component_driver fsl_ssi_component = {
581 .name = "fsl-ssi",
582};
583
577/* Show the statistics of a flag only if its interrupt is enabled. The 584/* Show the statistics of a flag only if its interrupt is enabled. The
578 * compiler will optimze this code to a no-op if the interrupt is not 585 * compiler will optimze this code to a no-op if the interrupt is not
579 * enabled. 586 * enabled.
@@ -649,6 +656,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
649 const uint32_t *iprop; 656 const uint32_t *iprop;
650 struct resource res; 657 struct resource res;
651 char name[64]; 658 char name[64];
659 bool shared;
652 660
653 /* SSIs that are not connected on the board should have a 661 /* SSIs that are not connected on the board should have a
654 * status = "disabled" 662 * status = "disabled"
@@ -737,14 +745,18 @@ static int fsl_ssi_probe(struct platform_device *pdev)
737 * We have burstsize be "fifo_depth - 2" to match the SSI 745 * We have burstsize be "fifo_depth - 2" to match the SSI
738 * watermark setting in fsl_ssi_startup(). 746 * watermark setting in fsl_ssi_startup().
739 */ 747 */
740 ssi_private->dma_params_tx.burstsize = 748 ssi_private->dma_params_tx.maxburst =
741 ssi_private->fifo_depth - 2; 749 ssi_private->fifo_depth - 2;
742 ssi_private->dma_params_rx.burstsize = 750 ssi_private->dma_params_rx.maxburst =
743 ssi_private->fifo_depth - 2; 751 ssi_private->fifo_depth - 2;
744 ssi_private->dma_params_tx.dma_addr = 752 ssi_private->dma_params_tx.addr =
745 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0); 753 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
746 ssi_private->dma_params_rx.dma_addr = 754 ssi_private->dma_params_rx.addr =
747 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0); 755 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
756 ssi_private->dma_params_tx.filter_data =
757 &ssi_private->filter_data_tx;
758 ssi_private->dma_params_rx.filter_data =
759 &ssi_private->filter_data_rx;
748 /* 760 /*
749 * TODO: This is a temporary solution and should be changed 761 * TODO: This is a temporary solution and should be changed
750 * to use generic DMA binding later when the helplers get in. 762 * to use generic DMA binding later when the helplers get in.
@@ -755,14 +767,14 @@ static int fsl_ssi_probe(struct platform_device *pdev)
755 dev_err(&pdev->dev, "could not get dma events\n"); 767 dev_err(&pdev->dev, "could not get dma events\n");
756 goto error_clk; 768 goto error_clk;
757 } 769 }
758 ssi_private->dma_params_tx.dma = dma_events[0];
759 ssi_private->dma_params_rx.dma = dma_events[1];
760 770
761 ssi_private->dma_params_tx.shared_peripheral = 771 shared = of_device_is_compatible(of_get_parent(np),
762 of_device_is_compatible(of_get_parent(np), 772 "fsl,spba-bus");
763 "fsl,spba-bus"); 773
764 ssi_private->dma_params_rx.shared_peripheral = 774 imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx,
765 ssi_private->dma_params_tx.shared_peripheral; 775 dma_events[0], shared);
776 imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
777 dma_events[1], shared);
766 } 778 }
767 779
768 /* Initialize the the device_attribute structure */ 780 /* Initialize the the device_attribute structure */
@@ -782,7 +794,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
782 /* Register with ASoC */ 794 /* Register with ASoC */
783 dev_set_drvdata(&pdev->dev, ssi_private); 795 dev_set_drvdata(&pdev->dev, ssi_private);
784 796
785 ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv); 797 ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component,
798 &ssi_private->cpu_dai_drv, 1);
786 if (ret) { 799 if (ret) {
787 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); 800 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
788 goto error_dev; 801 goto error_dev;
@@ -835,7 +848,7 @@ done:
835error_dai: 848error_dai:
836 if (ssi_private->ssi_on_imx) 849 if (ssi_private->ssi_on_imx)
837 platform_device_unregister(ssi_private->imx_pcm_pdev); 850 platform_device_unregister(ssi_private->imx_pcm_pdev);
838 snd_soc_unregister_dai(&pdev->dev); 851 snd_soc_unregister_component(&pdev->dev);
839 852
840error_dev: 853error_dev:
841 dev_set_drvdata(&pdev->dev, NULL); 854 dev_set_drvdata(&pdev->dev, NULL);
@@ -873,7 +886,7 @@ static int fsl_ssi_remove(struct platform_device *pdev)
873 clk_disable_unprepare(ssi_private->clk); 886 clk_disable_unprepare(ssi_private->clk);
874 clk_put(ssi_private->clk); 887 clk_put(ssi_private->clk);
875 } 888 }
876 snd_soc_unregister_dai(&pdev->dev); 889 snd_soc_unregister_component(&pdev->dev);
877 device_remove_file(&pdev->dev, &ssi_private->dev_attr); 890 device_remove_file(&pdev->dev, &ssi_private->dev_attr);
878 891
879 free_irq(ssi_private->irq, ssi_private); 892 free_irq(ssi_private->irq, ssi_private);
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 3f333e5b4673..47f046a8fdab 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -262,7 +262,7 @@ static int imx_audmux_probe(struct platform_device *pdev)
262 return PTR_ERR(pinctrl); 262 return PTR_ERR(pinctrl);
263 } 263 }
264 264
265 audmux_clk = clk_get(&pdev->dev, "audmux"); 265 audmux_clk = devm_clk_get(&pdev->dev, "audmux");
266 if (IS_ERR(audmux_clk)) { 266 if (IS_ERR(audmux_clk)) {
267 dev_dbg(&pdev->dev, "cannot get clock: %ld\n", 267 dev_dbg(&pdev->dev, "cannot get clock: %ld\n",
268 PTR_ERR(audmux_clk)); 268 PTR_ERR(audmux_clk));
@@ -282,7 +282,6 @@ static int imx_audmux_remove(struct platform_device *pdev)
282{ 282{
283 if (audmux_type == IMX31_AUDMUX) 283 if (audmux_type == IMX31_AUDMUX)
284 audmux_debugfs_remove(); 284 audmux_debugfs_remove();
285 clk_put(audmux_clk);
286 285
287 return 0; 286 return 0;
288} 287}
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index 500f8ce55d78..ee838c8a3b11 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -30,16 +30,16 @@
30#include <sound/soc.h> 30#include <sound/soc.h>
31#include <sound/dmaengine_pcm.h> 31#include <sound/dmaengine_pcm.h>
32 32
33#include <linux/platform_data/dma-imx.h>
34
35#include "imx-pcm.h" 33#include "imx-pcm.h"
36 34
37static bool filter(struct dma_chan *chan, void *param) 35static bool filter(struct dma_chan *chan, void *param)
38{ 36{
37 struct snd_dmaengine_dai_dma_data *dma_data = param;
38
39 if (!imx_dma_is_general_purpose(chan)) 39 if (!imx_dma_is_general_purpose(chan))
40 return false; 40 return false;
41 41
42 chan->private = param; 42 chan->private = dma_data->filter_data;
43 43
44 return true; 44 return true;
45} 45}
@@ -49,25 +49,16 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
49{ 49{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data; 50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); 51 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
52 struct imx_pcm_dma_params *dma_params;
53 struct dma_slave_config slave_config; 52 struct dma_slave_config slave_config;
54 int ret; 53 int ret;
55 54
56 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
57
58 ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config); 55 ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config);
59 if (ret) 56 if (ret)
60 return ret; 57 return ret;
61 58
62 slave_config.device_fc = false; 59 snd_dmaengine_pcm_set_config_from_dai_data(substream,
63 60 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
64 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 61 &slave_config);
65 slave_config.dst_addr = dma_params->dma_addr;
66 slave_config.dst_maxburst = dma_params->burstsize;
67 } else {
68 slave_config.src_addr = dma_params->dma_addr;
69 slave_config.src_maxburst = dma_params->burstsize;
70 }
71 62
72 ret = dmaengine_slave_config(chan, &slave_config); 63 ret = dmaengine_slave_config(chan, &slave_config);
73 if (ret) 64 if (ret)
@@ -100,47 +91,16 @@ static struct snd_pcm_hardware snd_imx_hardware = {
100static int snd_imx_open(struct snd_pcm_substream *substream) 91static int snd_imx_open(struct snd_pcm_substream *substream)
101{ 92{
102 struct snd_soc_pcm_runtime *rtd = substream->private_data; 93 struct snd_soc_pcm_runtime *rtd = substream->private_data;
103 struct imx_pcm_dma_params *dma_params;
104 struct imx_dma_data *dma_data;
105 int ret;
106 94
107 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); 95 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
108 96
109 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 97 return snd_dmaengine_pcm_open(substream, filter,
110 98 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
111 dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
112 if (!dma_data)
113 return -ENOMEM;
114
115 dma_data->peripheral_type = dma_params->shared_peripheral ?
116 IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI;
117 dma_data->priority = DMA_PRIO_HIGH;
118 dma_data->dma_request = dma_params->dma;
119
120 ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
121 if (ret) {
122 kfree(dma_data);
123 return ret;
124 }
125
126 snd_dmaengine_pcm_set_data(substream, dma_data);
127
128 return 0;
129}
130
131static int snd_imx_close(struct snd_pcm_substream *substream)
132{
133 struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
134
135 snd_dmaengine_pcm_close(substream);
136 kfree(dma_data);
137
138 return 0;
139} 99}
140 100
141static struct snd_pcm_ops imx_pcm_ops = { 101static struct snd_pcm_ops imx_pcm_ops = {
142 .open = snd_imx_open, 102 .open = snd_imx_open,
143 .close = snd_imx_close, 103 .close = snd_dmaengine_pcm_close,
144 .ioctl = snd_pcm_lib_ioctl, 104 .ioctl = snd_pcm_lib_ioctl,
145 .hw_params = snd_imx_pcm_hw_params, 105 .hw_params = snd_imx_pcm_hw_params,
146 .trigger = snd_dmaengine_pcm_trigger, 106 .trigger = snd_dmaengine_pcm_trigger,
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 920f945cb2f4..670b96b0ce2f 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -34,7 +34,7 @@
34#include "imx-ssi.h" 34#include "imx-ssi.h"
35 35
36struct imx_pcm_runtime_data { 36struct imx_pcm_runtime_data {
37 int period; 37 unsigned int period;
38 int periods; 38 int periods;
39 unsigned long offset; 39 unsigned long offset;
40 unsigned long last_offset; 40 unsigned long last_offset;
@@ -299,8 +299,8 @@ int imx_pcm_fiq_init(struct platform_device *pdev)
299 299
300 imx_ssi_fiq_base = (unsigned long)ssi->base; 300 imx_ssi_fiq_base = (unsigned long)ssi->base;
301 301
302 ssi->dma_params_tx.burstsize = 4; 302 ssi->dma_params_tx.maxburst = 4;
303 ssi->dma_params_rx.burstsize = 6; 303 ssi->dma_params_rx.maxburst = 6;
304 304
305 ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq); 305 ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
306 if (ret) 306 if (ret)
diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h
index 5ae13a13a353..be9cc64a208b 100644
--- a/sound/soc/fsl/imx-pcm.h
+++ b/sound/soc/fsl/imx-pcm.h
@@ -13,17 +13,24 @@
13#ifndef _IMX_PCM_H 13#ifndef _IMX_PCM_H
14#define _IMX_PCM_H 14#define _IMX_PCM_H
15 15
16#include <linux/platform_data/dma-imx.h>
17
16/* 18/*
17 * Do not change this as the FIQ handler depends on this size 19 * Do not change this as the FIQ handler depends on this size
18 */ 20 */
19#define IMX_SSI_DMABUF_SIZE (64 * 1024) 21#define IMX_SSI_DMABUF_SIZE (64 * 1024)
20 22
21struct imx_pcm_dma_params { 23static inline void
22 int dma; 24imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data,
23 unsigned long dma_addr; 25 int dma, bool shared)
24 int burstsize; 26{
25 bool shared_peripheral; /* The peripheral is on SPBA bus */ 27 dma_data->dma_request = dma;
26}; 28 dma_data->priority = DMA_PRIO_HIGH;
29 if (shared)
30 dma_data->peripheral_type = IMX_DMATYPE_SSI_SP;
31 else
32 dma_data->peripheral_type = IMX_DMATYPE_SSI;
33}
27 34
28int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, 35int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
29 struct vm_area_struct *vma); 36 struct vm_area_struct *vma);
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index 424347e9b2d7..9584e78858df 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -148,7 +148,7 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
148 data->dai.stream_name = "HiFi"; 148 data->dai.stream_name = "HiFi";
149 data->dai.codec_dai_name = "sgtl5000"; 149 data->dai.codec_dai_name = "sgtl5000";
150 data->dai.codec_of_node = codec_np; 150 data->dai.codec_of_node = codec_np;
151 data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev); 151 data->dai.cpu_of_node = ssi_np;
152 data->dai.platform_name = "imx-pcm-audio"; 152 data->dai.platform_name = "imx-pcm-audio";
153 data->dai.init = &imx_sgtl5000_dai_init; 153 data->dai.init = &imx_sgtl5000_dai_init;
154 data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 154 data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 55464a5b0706..4ce2d608b37a 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -236,7 +236,7 @@ static int imx_ssi_startup(struct snd_pcm_substream *substream,
236 struct snd_soc_dai *cpu_dai) 236 struct snd_soc_dai *cpu_dai)
237{ 237{
238 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai); 238 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
239 struct imx_pcm_dma_params *dma_data; 239 struct snd_dmaengine_dai_dma_data *dma_data;
240 240
241 /* Tx/Rx config */ 241 /* Tx/Rx config */
242 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 242 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -369,8 +369,8 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
369 369
370 snd_soc_dai_set_drvdata(dai, ssi); 370 snd_soc_dai_set_drvdata(dai, ssi);
371 371
372 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) | 372 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.maxburst) |
373 SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize); 373 SSI_SFCSR_RFWM0(ssi->dma_params_rx.maxburst);
374 writel(val, ssi->base + SSI_SFCSR); 374 writel(val, ssi->base + SSI_SFCSR);
375 375
376 return 0; 376 return 0;
@@ -400,7 +400,7 @@ static struct snd_soc_dai_driver imx_ac97_dai = {
400 .stream_name = "AC97 Playback", 400 .stream_name = "AC97 Playback",
401 .channels_min = 2, 401 .channels_min = 2,
402 .channels_max = 2, 402 .channels_max = 2,
403 .rates = SNDRV_PCM_RATE_48000, 403 .rates = SNDRV_PCM_RATE_8000_48000,
404 .formats = SNDRV_PCM_FMTBIT_S16_LE, 404 .formats = SNDRV_PCM_FMTBIT_S16_LE,
405 }, 405 },
406 .capture = { 406 .capture = {
@@ -413,6 +413,10 @@ static struct snd_soc_dai_driver imx_ac97_dai = {
413 .ops = &imx_ssi_pcm_dai_ops, 413 .ops = &imx_ssi_pcm_dai_ops,
414}; 414};
415 415
416static const struct snd_soc_component_driver imx_component = {
417 .name = DRV_NAME,
418};
419
416static void setup_channel_to_ac97(struct imx_ssi *imx_ssi) 420static void setup_channel_to_ac97(struct imx_ssi *imx_ssi)
417{ 421{
418 void __iomem *base = imx_ssi->base; 422 void __iomem *base = imx_ssi->base;
@@ -496,6 +500,8 @@ static void imx_ssi_ac97_reset(struct snd_ac97 *ac97)
496 500
497 if (imx_ssi->ac97_reset) 501 if (imx_ssi->ac97_reset)
498 imx_ssi->ac97_reset(ac97); 502 imx_ssi->ac97_reset(ac97);
503 /* First read sometimes fails, do a dummy read */
504 imx_ssi_ac97_read(ac97, 0);
499} 505}
500 506
501static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97) 507static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
@@ -504,6 +510,9 @@ static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
504 510
505 if (imx_ssi->ac97_warm_reset) 511 if (imx_ssi->ac97_warm_reset)
506 imx_ssi->ac97_warm_reset(ac97); 512 imx_ssi->ac97_warm_reset(ac97);
513
514 /* First read sometimes fails, do a dummy read */
515 imx_ssi_ac97_read(ac97, 0);
507} 516}
508 517
509struct snd_ac97_bus_ops soc_ac97_ops = { 518struct snd_ac97_bus_ops soc_ac97_ops = {
@@ -570,23 +579,31 @@ static int imx_ssi_probe(struct platform_device *pdev)
570 579
571 writel(0x0, ssi->base + SSI_SIER); 580 writel(0x0, ssi->base + SSI_SIER);
572 581
573 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0; 582 ssi->dma_params_rx.addr = res->start + SSI_SRX0;
574 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0; 583 ssi->dma_params_tx.addr = res->start + SSI_STX0;
575 584
576 ssi->dma_params_tx.burstsize = 6; 585 ssi->dma_params_tx.maxburst = 6;
577 ssi->dma_params_rx.burstsize = 4; 586 ssi->dma_params_rx.maxburst = 4;
587
588 ssi->dma_params_tx.filter_data = &ssi->filter_data_tx;
589 ssi->dma_params_rx.filter_data = &ssi->filter_data_rx;
578 590
579 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); 591 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
580 if (res) 592 if (res) {
581 ssi->dma_params_tx.dma = res->start; 593 imx_pcm_dma_params_init_data(&ssi->filter_data_tx, res->start,
594 false);
595 }
582 596
583 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0"); 597 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0");
584 if (res) 598 if (res) {
585 ssi->dma_params_rx.dma = res->start; 599 imx_pcm_dma_params_init_data(&ssi->filter_data_rx, res->start,
600 false);
601 }
586 602
587 platform_set_drvdata(pdev, ssi); 603 platform_set_drvdata(pdev, ssi);
588 604
589 ret = snd_soc_register_dai(&pdev->dev, dai); 605 ret = snd_soc_register_component(&pdev->dev, &imx_component,
606 dai, 1);
590 if (ret) { 607 if (ret) {
591 dev_err(&pdev->dev, "register DAI failed\n"); 608 dev_err(&pdev->dev, "register DAI failed\n");
592 goto failed_register; 609 goto failed_register;
@@ -627,7 +644,7 @@ failed_pdev_alloc:
627failed_pdev_fiq_add: 644failed_pdev_fiq_add:
628 platform_device_put(ssi->soc_platform_pdev_fiq); 645 platform_device_put(ssi->soc_platform_pdev_fiq);
629failed_pdev_fiq_alloc: 646failed_pdev_fiq_alloc:
630 snd_soc_unregister_dai(&pdev->dev); 647 snd_soc_unregister_component(&pdev->dev);
631failed_register: 648failed_register:
632 release_mem_region(res->start, resource_size(res)); 649 release_mem_region(res->start, resource_size(res));
633failed_get_resource: 650failed_get_resource:
@@ -645,7 +662,7 @@ static int imx_ssi_remove(struct platform_device *pdev)
645 platform_device_unregister(ssi->soc_platform_pdev); 662 platform_device_unregister(ssi->soc_platform_pdev);
646 platform_device_unregister(ssi->soc_platform_pdev_fiq); 663 platform_device_unregister(ssi->soc_platform_pdev_fiq);
647 664
648 snd_soc_unregister_dai(&pdev->dev); 665 snd_soc_unregister_component(&pdev->dev);
649 666
650 if (ssi->flags & IMX_SSI_USE_AC97) 667 if (ssi->flags & IMX_SSI_USE_AC97)
651 ac97_ssi = NULL; 668 ac97_ssi = NULL;
diff --git a/sound/soc/fsl/imx-ssi.h b/sound/soc/fsl/imx-ssi.h
index dc114bdedce5..bb6b3dbb13fd 100644
--- a/sound/soc/fsl/imx-ssi.h
+++ b/sound/soc/fsl/imx-ssi.h
@@ -187,6 +187,7 @@
187 187
188#include <linux/dmaengine.h> 188#include <linux/dmaengine.h>
189#include <linux/platform_data/dma-imx.h> 189#include <linux/platform_data/dma-imx.h>
190#include <sound/dmaengine_pcm.h>
190#include "imx-pcm.h" 191#include "imx-pcm.h"
191 192
192struct imx_ssi { 193struct imx_ssi {
@@ -204,8 +205,10 @@ struct imx_ssi {
204 void (*ac97_reset) (struct snd_ac97 *ac97); 205 void (*ac97_reset) (struct snd_ac97 *ac97);
205 void (*ac97_warm_reset)(struct snd_ac97 *ac97); 206 void (*ac97_warm_reset)(struct snd_ac97 *ac97);
206 207
207 struct imx_pcm_dma_params dma_params_rx; 208 struct snd_dmaengine_dai_dma_data dma_params_rx;
208 struct imx_pcm_dma_params dma_params_tx; 209 struct snd_dmaengine_dai_dma_data dma_params_tx;
210 struct imx_dma_data filter_data_tx;
211 struct imx_dma_data filter_data_rx;
209 212
210 int enabled; 213 int enabled;
211 214
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index a4aec0488dd3..4141b35ef0bb 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -270,6 +270,9 @@ static struct snd_soc_dai_driver psc_ac97_dai[] = {
270 .ops = &psc_ac97_digital_ops, 270 .ops = &psc_ac97_digital_ops,
271} }; 271} };
272 272
273static const struct snd_soc_component_driver psc_ac97_component = {
274 .name = DRV_NAME,
275};
273 276
274 277
275/* --------------------------------------------------------------------- 278/* ---------------------------------------------------------------------
@@ -287,7 +290,8 @@ static int psc_ac97_of_probe(struct platform_device *op)
287 if (rc != 0) 290 if (rc != 0)
288 return rc; 291 return rc;
289 292
290 rc = snd_soc_register_dais(&op->dev, psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai)); 293 rc = snd_soc_register_component(&op->dev, &psc_ac97_component,
294 psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
291 if (rc != 0) { 295 if (rc != 0) {
292 dev_err(&op->dev, "Failed to register DAI\n"); 296 dev_err(&op->dev, "Failed to register DAI\n");
293 return rc; 297 return rc;
@@ -313,7 +317,7 @@ static int psc_ac97_of_probe(struct platform_device *op)
313static int psc_ac97_of_remove(struct platform_device *op) 317static int psc_ac97_of_remove(struct platform_device *op)
314{ 318{
315 mpc5200_audio_dma_destroy(op); 319 mpc5200_audio_dma_destroy(op);
316 snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai)); 320 snd_soc_unregister_component(&op->dev);
317 return 0; 321 return 0;
318} 322}
319 323
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index b95b966f25a0..f4efaadb80a2 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -148,6 +148,10 @@ static struct snd_soc_dai_driver psc_i2s_dai[] = {{
148 .ops = &psc_i2s_dai_ops, 148 .ops = &psc_i2s_dai_ops,
149} }; 149} };
150 150
151static const struct snd_soc_component_driver psc_i2s_component = {
152 .name = "mpc5200-i2s",
153};
154
151/* --------------------------------------------------------------------- 155/* ---------------------------------------------------------------------
152 * OF platform bus binding code: 156 * OF platform bus binding code:
153 * - Probe/remove operations 157 * - Probe/remove operations
@@ -163,7 +167,8 @@ static int psc_i2s_of_probe(struct platform_device *op)
163 if (rc != 0) 167 if (rc != 0)
164 return rc; 168 return rc;
165 169
166 rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai)); 170 rc = snd_soc_register_component(&op->dev, &psc_i2s_component,
171 psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
167 if (rc != 0) { 172 if (rc != 0) {
168 pr_err("Failed to register DAI\n"); 173 pr_err("Failed to register DAI\n");
169 return rc; 174 return rc;
@@ -208,7 +213,7 @@ static int psc_i2s_of_probe(struct platform_device *op)
208static int psc_i2s_of_remove(struct platform_device *op) 213static int psc_i2s_of_remove(struct platform_device *op)
209{ 214{
210 mpc5200_audio_dma_destroy(op); 215 mpc5200_audio_dma_destroy(op);
211 snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai)); 216 snd_soc_unregister_component(&op->dev);
212 return 0; 217 return 0;
213} 218}
214 219
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index 8e52c1485df3..eb4373840bb6 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -51,7 +51,7 @@ static struct snd_soc_card pcm030_card = {
51 .num_links = ARRAY_SIZE(pcm030_fabric_dai), 51 .num_links = ARRAY_SIZE(pcm030_fabric_dai),
52}; 52};
53 53
54static int __init pcm030_fabric_probe(struct platform_device *op) 54static int pcm030_fabric_probe(struct platform_device *op)
55{ 55{
56 struct device_node *np = op->dev.of_node; 56 struct device_node *np = op->dev.of_node;
57 struct device_node *platform_np; 57 struct device_node *platform_np;
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 6cef491f4823..9a126441c5f3 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -425,6 +425,10 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
425 .resume = jz4740_i2s_resume, 425 .resume = jz4740_i2s_resume,
426}; 426};
427 427
428static const struct snd_soc_component_driver jz4740_i2s_component = {
429 .name = "jz4740-i2s",
430};
431
428static int jz4740_i2s_dev_probe(struct platform_device *pdev) 432static int jz4740_i2s_dev_probe(struct platform_device *pdev)
429{ 433{
430 struct jz4740_i2s *i2s; 434 struct jz4740_i2s *i2s;
@@ -469,7 +473,8 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
469 } 473 }
470 474
471 platform_set_drvdata(pdev, i2s); 475 platform_set_drvdata(pdev, i2s);
472 ret = snd_soc_register_dai(&pdev->dev, &jz4740_i2s_dai); 476 ret = snd_soc_register_component(&pdev->dev, &jz4740_i2s_component,
477 &jz4740_i2s_dai, 1);
473 478
474 if (ret) { 479 if (ret) {
475 dev_err(&pdev->dev, "Failed to register DAI\n"); 480 dev_err(&pdev->dev, "Failed to register DAI\n");
@@ -496,7 +501,7 @@ static int jz4740_i2s_dev_remove(struct platform_device *pdev)
496{ 501{
497 struct jz4740_i2s *i2s = platform_get_drvdata(pdev); 502 struct jz4740_i2s *i2s = platform_get_drvdata(pdev);
498 503
499 snd_soc_unregister_dai(&pdev->dev); 504 snd_soc_unregister_component(&pdev->dev);
500 505
501 clk_put(i2s->clk_i2s); 506 clk_put(i2s->clk_i2s);
502 clk_put(i2s->clk_aic); 507 clk_put(i2s->clk_aic);
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index c74c89065493..befe68f59285 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -451,6 +451,10 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = {
451 .ops = &kirkwood_i2s_dai_ops, 451 .ops = &kirkwood_i2s_dai_ops,
452}; 452};
453 453
454static const struct snd_soc_component_driver kirkwood_i2s_component = {
455 .name = DRV_NAME,
456};
457
454static int kirkwood_i2s_dev_probe(struct platform_device *pdev) 458static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
455{ 459{
456 struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; 460 struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
@@ -524,10 +528,11 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
524 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; 528 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
525 } 529 }
526 530
527 err = snd_soc_register_dai(&pdev->dev, soc_dai); 531 err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component,
532 soc_dai, 1);
528 if (!err) 533 if (!err)
529 return 0; 534 return 0;
530 dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); 535 dev_err(&pdev->dev, "snd_soc_register_component failed\n");
531 536
532 if (!IS_ERR(priv->extclk)) { 537 if (!IS_ERR(priv->extclk)) {
533 clk_disable_unprepare(priv->extclk); 538 clk_disable_unprepare(priv->extclk);
@@ -542,7 +547,7 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
542{ 547{
543 struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev); 548 struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
544 549
545 snd_soc_unregister_dai(&pdev->dev); 550 snd_soc_unregister_component(&pdev->dev);
546 551
547 if (!IS_ERR(priv->extclk)) { 552 if (!IS_ERR(priv->extclk)) {
548 clk_disable_unprepare(priv->extclk); 553 clk_disable_unprepare(priv->extclk);
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index a263cbed8624..392fc0b8f5b8 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * sst_platform.c - Intel MID Platform driver 2 * sst_platform.c - Intel MID Platform driver
3 * 3 *
4 * Copyright (C) 2010-2012 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>
6 * Author: Harsha Priya <priya.harsha@intel.com> 6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -165,6 +165,10 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
165}, 165},
166}; 166};
167 167
168static const struct snd_soc_component_driver sst_component = {
169 .name = "sst",
170};
171
168/* helper functions */ 172/* helper functions */
169static inline void sst_set_stream_status(struct sst_runtime_stream *stream, 173static inline void sst_set_stream_status(struct sst_runtime_stream *stream,
170 int state) 174 int state)
@@ -652,11 +656,21 @@ static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream,
652 return stream->compr_ops->get_codec_caps(codec); 656 return stream->compr_ops->get_codec_caps(codec);
653} 657}
654 658
659static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream,
660 struct snd_compr_metadata *metadata)
661{
662 struct sst_runtime_stream *stream =
663 cstream->runtime->private_data;
664
665 return stream->compr_ops->set_metadata(stream->id, metadata);
666}
667
655static struct snd_compr_ops sst_platform_compr_ops = { 668static struct snd_compr_ops sst_platform_compr_ops = {
656 669
657 .open = sst_platform_compr_open, 670 .open = sst_platform_compr_open,
658 .free = sst_platform_compr_free, 671 .free = sst_platform_compr_free,
659 .set_params = sst_platform_compr_set_params, 672 .set_params = sst_platform_compr_set_params,
673 .set_metadata = sst_platform_compr_set_metadata,
660 .trigger = sst_platform_compr_trigger, 674 .trigger = sst_platform_compr_trigger,
661 .pointer = sst_platform_compr_pointer, 675 .pointer = sst_platform_compr_pointer,
662 .ack = sst_platform_compr_ack, 676 .ack = sst_platform_compr_ack,
@@ -683,7 +697,7 @@ static int sst_platform_probe(struct platform_device *pdev)
683 return ret; 697 return ret;
684 } 698 }
685 699
686 ret = snd_soc_register_dais(&pdev->dev, 700 ret = snd_soc_register_component(&pdev->dev, &sst_component,
687 sst_platform_dai, ARRAY_SIZE(sst_platform_dai)); 701 sst_platform_dai, ARRAY_SIZE(sst_platform_dai));
688 if (ret) { 702 if (ret) {
689 pr_err("registering cpu dais failed\n"); 703 pr_err("registering cpu dais failed\n");
@@ -695,7 +709,7 @@ static int sst_platform_probe(struct platform_device *pdev)
695static int sst_platform_remove(struct platform_device *pdev) 709static int sst_platform_remove(struct platform_device *pdev)
696{ 710{
697 711
698 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sst_platform_dai)); 712 snd_soc_unregister_component(&pdev->dev);
699 snd_soc_unregister_platform(&pdev->dev); 713 snd_soc_unregister_platform(&pdev->dev);
700 pr_debug("sst_platform_remove success\n"); 714 pr_debug("sst_platform_remove success\n");
701 return 0; 715 return 0;
diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h
index d61c5d514ffa..cacc9066ec52 100644
--- a/sound/soc/mid-x86/sst_platform.h
+++ b/sound/soc/mid-x86/sst_platform.h
@@ -124,6 +124,8 @@ struct compress_sst_ops {
124 int (*close) (unsigned int str_id); 124 int (*close) (unsigned int str_id);
125 int (*get_caps) (struct snd_compr_caps *caps); 125 int (*get_caps) (struct snd_compr_caps *caps);
126 int (*get_codec_caps) (struct snd_compr_codec_caps *codec); 126 int (*get_codec_caps) (struct snd_compr_codec_caps *codec);
127 int (*set_metadata) (unsigned int str_id,
128 struct snd_compr_metadata *mdata);
127 129
128}; 130};
129 131
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index 564b5b60319d..ebbef8597554 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -28,7 +28,6 @@
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/dmaengine.h> 30#include <linux/dmaengine.h>
31#include <linux/fsl/mxs-dma.h>
32 31
33#include <sound/core.h> 32#include <sound/core.h>
34#include <sound/initval.h> 33#include <sound/initval.h>
@@ -39,11 +38,6 @@
39 38
40#include "mxs-pcm.h" 39#include "mxs-pcm.h"
41 40
42struct mxs_pcm_dma_data {
43 struct mxs_dma_data dma_data;
44 struct mxs_pcm_dma_params *dma_params;
45};
46
47static struct snd_pcm_hardware snd_mxs_hardware = { 41static struct snd_pcm_hardware snd_mxs_hardware = {
48 .info = SNDRV_PCM_INFO_MMAP | 42 .info = SNDRV_PCM_INFO_MMAP |
49 SNDRV_PCM_INFO_MMAP_VALID | 43 SNDRV_PCM_INFO_MMAP_VALID |
@@ -66,8 +60,7 @@ static struct snd_pcm_hardware snd_mxs_hardware = {
66 60
67static bool filter(struct dma_chan *chan, void *param) 61static bool filter(struct dma_chan *chan, void *param)
68{ 62{
69 struct mxs_pcm_dma_data *pcm_dma_data = param; 63 struct mxs_pcm_dma_params *dma_params = param;
70 struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params;
71 64
72 if (!mxs_dma_is_apbx(chan)) 65 if (!mxs_dma_is_apbx(chan))
73 return false; 66 return false;
@@ -75,7 +68,7 @@ static bool filter(struct dma_chan *chan, void *param)
75 if (chan->chan_id != dma_params->chan_num) 68 if (chan->chan_id != dma_params->chan_num)
76 return false; 69 return false;
77 70
78 chan->private = &pcm_dma_data->dma_data; 71 chan->private = &dma_params->dma_data;
79 72
80 return true; 73 return true;
81} 74}
@@ -91,37 +84,11 @@ static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
91static int snd_mxs_open(struct snd_pcm_substream *substream) 84static int snd_mxs_open(struct snd_pcm_substream *substream)
92{ 85{
93 struct snd_soc_pcm_runtime *rtd = substream->private_data; 86 struct snd_soc_pcm_runtime *rtd = substream->private_data;
94 struct mxs_pcm_dma_data *pcm_dma_data;
95 int ret;
96
97 pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL);
98 if (pcm_dma_data == NULL)
99 return -ENOMEM;
100
101 pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
102 pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq;
103
104 ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data);
105 if (ret) {
106 kfree(pcm_dma_data);
107 return ret;
108 }
109 87
110 snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); 88 snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
111 89
112 snd_dmaengine_pcm_set_data(substream, pcm_dma_data); 90 return snd_dmaengine_pcm_open(substream, filter,
113 91 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
114 return 0;
115}
116
117static int snd_mxs_close(struct snd_pcm_substream *substream)
118{
119 struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream);
120
121 snd_dmaengine_pcm_close(substream);
122 kfree(pcm_dma_data);
123
124 return 0;
125} 92}
126 93
127static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream, 94static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
@@ -137,7 +104,7 @@ static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
137 104
138static struct snd_pcm_ops mxs_pcm_ops = { 105static struct snd_pcm_ops mxs_pcm_ops = {
139 .open = snd_mxs_open, 106 .open = snd_mxs_open,
140 .close = snd_mxs_close, 107 .close = snd_dmaengine_pcm_close,
141 .ioctl = snd_pcm_lib_ioctl, 108 .ioctl = snd_pcm_lib_ioctl,
142 .hw_params = snd_mxs_pcm_hw_params, 109 .hw_params = snd_mxs_pcm_hw_params,
143 .trigger = snd_dmaengine_pcm_trigger, 110 .trigger = snd_dmaengine_pcm_trigger,
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
index 35ba2ca42384..3aa918f9ed3e 100644
--- a/sound/soc/mxs/mxs-pcm.h
+++ b/sound/soc/mxs/mxs-pcm.h
@@ -19,8 +19,10 @@
19#ifndef _MXS_PCM_H 19#ifndef _MXS_PCM_H
20#define _MXS_PCM_H 20#define _MXS_PCM_H
21 21
22#include <linux/fsl/mxs-dma.h>
23
22struct mxs_pcm_dma_params { 24struct mxs_pcm_dma_params {
23 int chan_irq; 25 struct mxs_dma_data dma_data;
24 int chan_num; 26 int chan_num;
25}; 27};
26 28
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index 3a2aa1d19b93..abf4ddf4ed89 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -627,6 +627,10 @@ static struct snd_soc_dai_driver mxs_saif_dai = {
627 .ops = &mxs_saif_dai_ops, 627 .ops = &mxs_saif_dai_ops,
628}; 628};
629 629
630static const struct snd_soc_component_driver mxs_saif_component = {
631 .name = "mxs-saif",
632};
633
630static irqreturn_t mxs_saif_irq(int irq, void *dev_id) 634static irqreturn_t mxs_saif_irq(int irq, void *dev_id)
631{ 635{
632 struct mxs_saif *saif = dev_id; 636 struct mxs_saif *saif = dev_id;
@@ -753,9 +757,9 @@ static int mxs_saif_probe(struct platform_device *pdev)
753 return ret; 757 return ret;
754 } 758 }
755 759
756 saif->dma_param.chan_irq = platform_get_irq(pdev, 1); 760 saif->dma_param.dma_data.chan_irq = platform_get_irq(pdev, 1);
757 if (saif->dma_param.chan_irq < 0) { 761 if (saif->dma_param.dma_data.chan_irq < 0) {
758 ret = saif->dma_param.chan_irq; 762 ret = saif->dma_param.dma_data.chan_irq;
759 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", 763 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
760 ret); 764 ret);
761 return ret; 765 return ret;
@@ -763,7 +767,8 @@ static int mxs_saif_probe(struct platform_device *pdev)
763 767
764 platform_set_drvdata(pdev, saif); 768 platform_set_drvdata(pdev, saif);
765 769
766 ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); 770 ret = snd_soc_register_component(&pdev->dev, &mxs_saif_component,
771 &mxs_saif_dai, 1);
767 if (ret) { 772 if (ret) {
768 dev_err(&pdev->dev, "register DAI failed\n"); 773 dev_err(&pdev->dev, "register DAI failed\n");
769 return ret; 774 return ret;
@@ -778,7 +783,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
778 return 0; 783 return 0;
779 784
780failed_pdev_alloc: 785failed_pdev_alloc:
781 snd_soc_unregister_dai(&pdev->dev); 786 snd_soc_unregister_component(&pdev->dev);
782 787
783 return ret; 788 return ret;
784} 789}
@@ -786,7 +791,7 @@ failed_pdev_alloc:
786static int mxs_saif_remove(struct platform_device *pdev) 791static int mxs_saif_remove(struct platform_device *pdev)
787{ 792{
788 mxs_pcm_platform_unregister(&pdev->dev); 793 mxs_pcm_platform_unregister(&pdev->dev);
789 snd_soc_unregister_dai(&pdev->dev); 794 snd_soc_unregister_component(&pdev->dev);
790 795
791 return 0; 796 return 0;
792} 797}
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
index 0418467a4848..fe3285ceaf5b 100644
--- a/sound/soc/nuc900/nuc900-ac97.c
+++ b/sound/soc/nuc900/nuc900-ac97.c
@@ -314,6 +314,10 @@ static struct snd_soc_dai_driver nuc900_ac97_dai = {
314 .ops = &nuc900_ac97_dai_ops, 314 .ops = &nuc900_ac97_dai_ops,
315}; 315};
316 316
317static const struct snd_soc_component_driver nuc900_ac97_component = {
318 .name = "nuc900-ac97",
319};
320
317static int nuc900_ac97_drvprobe(struct platform_device *pdev) 321static int nuc900_ac97_drvprobe(struct platform_device *pdev)
318{ 322{
319 struct nuc900_audio *nuc900_audio; 323 struct nuc900_audio *nuc900_audio;
@@ -361,7 +365,8 @@ static int nuc900_ac97_drvprobe(struct platform_device *pdev)
361 365
362 nuc900_ac97_data = nuc900_audio; 366 nuc900_ac97_data = nuc900_audio;
363 367
364 ret = snd_soc_register_dai(&pdev->dev, &nuc900_ac97_dai); 368 ret = snd_soc_register_component(&pdev->dev, &nuc900_ac97_component,
369 &nuc900_ac97_dai, 1);
365 if (ret) 370 if (ret)
366 goto out3; 371 goto out3;
367 372
@@ -384,7 +389,7 @@ out0:
384 389
385static int nuc900_ac97_drvremove(struct platform_device *pdev) 390static int nuc900_ac97_drvremove(struct platform_device *pdev)
386{ 391{
387 snd_soc_unregister_dai(&pdev->dev); 392 snd_soc_unregister_component(&pdev->dev);
388 393
389 clk_put(nuc900_ac97_data->clk); 394 clk_put(nuc900_ac97_data->clk);
390 iounmap(nuc900_ac97_data->mmio); 395 iounmap(nuc900_ac97_data->mmio);
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index c1900b2a6f28..994dcf345975 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -28,7 +28,6 @@
28#include <linux/platform_data/asoc-ti-mcbsp.h> 28#include <linux/platform_data/asoc-ti-mcbsp.h>
29 29
30#include "omap-mcbsp.h" 30#include "omap-mcbsp.h"
31#include "omap-pcm.h"
32 31
33#include "../codecs/tlv320aic23.h" 32#include "../codecs/tlv320aic23.h"
34 33
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 2600447fa74f..629446482a91 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -36,7 +36,6 @@
36#include <linux/platform_data/asoc-ti-mcbsp.h> 36#include <linux/platform_data/asoc-ti-mcbsp.h>
37 37
38#include "omap-mcbsp.h" 38#include "omap-mcbsp.h"
39#include "omap-pcm.h"
40#include "../codecs/cx20442.h" 39#include "../codecs/cx20442.h"
41 40
42 41
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
index 285c8368cb47..eb68c7db1cf3 100644
--- a/sound/soc/omap/mcbsp.c
+++ b/sound/soc/omap/mcbsp.c
@@ -1018,9 +1018,10 @@ int omap_mcbsp_init(struct platform_device *pdev)
1018 return -ENODEV; 1018 return -ENODEV;
1019 } 1019 }
1020 /* RX DMA request number, and port address configuration */ 1020 /* RX DMA request number, and port address configuration */
1021 mcbsp->dma_data[1].name = "Audio Capture"; 1021 mcbsp->dma_req[1] = res->start;
1022 mcbsp->dma_data[1].dma_req = res->start; 1022 mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1];
1023 mcbsp->dma_data[1].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 1); 1023 mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1);
1024 mcbsp->dma_data[1].maxburst = 4;
1024 1025
1025 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); 1026 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
1026 if (!res) { 1027 if (!res) {
@@ -1028,9 +1029,10 @@ int omap_mcbsp_init(struct platform_device *pdev)
1028 return -ENODEV; 1029 return -ENODEV;
1029 } 1030 }
1030 /* TX DMA request number, and port address configuration */ 1031 /* TX DMA request number, and port address configuration */
1031 mcbsp->dma_data[0].name = "Audio Playback"; 1032 mcbsp->dma_req[0] = res->start;
1032 mcbsp->dma_data[0].dma_req = res->start; 1033 mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0];
1033 mcbsp->dma_data[0].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 0); 1034 mcbsp->dma_data[0].addr = omap_mcbsp_dma_reg_params(mcbsp, 0);
1035 mcbsp->dma_data[0].maxburst = 4;
1034 1036
1035 mcbsp->fclk = clk_get(&pdev->dev, "fck"); 1037 mcbsp->fclk = clk_get(&pdev->dev, "fck");
1036 if (IS_ERR(mcbsp->fclk)) { 1038 if (IS_ERR(mcbsp->fclk)) {
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h
index f93e0b0af303..96d1b086bcf8 100644
--- a/sound/soc/omap/mcbsp.h
+++ b/sound/soc/omap/mcbsp.h
@@ -24,14 +24,14 @@
24#ifndef __ASOC_MCBSP_H 24#ifndef __ASOC_MCBSP_H
25#define __ASOC_MCBSP_H 25#define __ASOC_MCBSP_H
26 26
27#include "omap-pcm.h"
28
29#ifdef CONFIG_ARCH_OMAP1 27#ifdef CONFIG_ARCH_OMAP1
30#define mcbsp_omap1() 1 28#define mcbsp_omap1() 1
31#else 29#else
32#define mcbsp_omap1() 0 30#define mcbsp_omap1() 0
33#endif 31#endif
34 32
33#include <sound/dmaengine_pcm.h>
34
35/* McBSP register numbers. Register address offset = num * reg_step */ 35/* McBSP register numbers. Register address offset = num * reg_step */
36enum { 36enum {
37 /* Common registers */ 37 /* Common registers */
@@ -312,7 +312,8 @@ struct omap_mcbsp {
312 struct omap_mcbsp_platform_data *pdata; 312 struct omap_mcbsp_platform_data *pdata;
313 struct omap_mcbsp_st_data *st_data; 313 struct omap_mcbsp_st_data *st_data;
314 struct omap_mcbsp_reg_cfg cfg_regs; 314 struct omap_mcbsp_reg_cfg cfg_regs;
315 struct omap_pcm_dma_data dma_data[2]; 315 struct snd_dmaengine_dai_dma_data dma_data[2];
316 unsigned int dma_req[2];
316 int dma_op_mode; 317 int dma_op_mode;
317 u16 max_tx_thres; 318 u16 max_tx_thres;
318 u16 max_rx_thres; 319 u16 max_rx_thres;
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index ee7cd53aa3ee..5e8d640d314f 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -34,7 +34,6 @@
34#include <linux/platform_data/asoc-ti-mcbsp.h> 34#include <linux/platform_data/asoc-ti-mcbsp.h>
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38 37
39#define N810_HEADSET_AMP_GPIO 10 38#define N810_HEADSET_AMP_GPIO 10
40#define N810_SPEAKER_AMP_GPIO 101 39#define N810_SPEAKER_AMP_GPIO 101
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index e7d93fa412a9..70cd5c7b2e14 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -34,7 +34,6 @@
34 34
35#include "omap-dmic.h" 35#include "omap-dmic.h"
36#include "omap-mcpdm.h" 36#include "omap-mcpdm.h"
37#include "omap-pcm.h"
38#include "../codecs/twl6040.h" 37#include "../codecs/twl6040.h"
39 38
40struct abe_twl6040 { 39struct abe_twl6040 {
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index ba49ccd9eed9..2ad0370146fd 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -39,8 +39,8 @@
39#include <sound/pcm_params.h> 39#include <sound/pcm_params.h>
40#include <sound/initval.h> 40#include <sound/initval.h>
41#include <sound/soc.h> 41#include <sound/soc.h>
42#include <sound/dmaengine_pcm.h>
42 43
43#include "omap-pcm.h"
44#include "omap-dmic.h" 44#include "omap-dmic.h"
45 45
46struct omap_dmic { 46struct omap_dmic {
@@ -55,13 +55,9 @@ struct omap_dmic {
55 u32 ch_enabled; 55 u32 ch_enabled;
56 bool active; 56 bool active;
57 struct mutex mutex; 57 struct mutex mutex;
58};
59 58
60/* 59 struct snd_dmaengine_dai_dma_data dma_data;
61 * Stream DMA parameters 60 unsigned int dma_req;
62 */
63static struct omap_pcm_dma_data omap_dmic_dai_dma_params = {
64 .name = "DMIC capture",
65}; 61};
66 62
67static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) 63static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
@@ -118,7 +114,7 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
118 114
119 mutex_unlock(&dmic->mutex); 115 mutex_unlock(&dmic->mutex);
120 116
121 snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params); 117 snd_soc_dai_set_dma_data(dai, substream, &dmic->dma_data);
122 return ret; 118 return ret;
123} 119}
124 120
@@ -203,7 +199,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
203 struct snd_soc_dai *dai) 199 struct snd_soc_dai *dai)
204{ 200{
205 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); 201 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
206 struct omap_pcm_dma_data *dma_data; 202 struct snd_dmaengine_dai_dma_data *dma_data;
207 int channels; 203 int channels;
208 204
209 dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params)); 205 dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params));
@@ -230,7 +226,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
230 226
231 /* packet size is threshold * channels */ 227 /* packet size is threshold * channels */
232 dma_data = snd_soc_dai_get_dma_data(dai, substream); 228 dma_data = snd_soc_dai_get_dma_data(dai, substream);
233 dma_data->packet_size = dmic->threshold * channels; 229 dma_data->maxburst = dmic->threshold * channels;
234 230
235 return 0; 231 return 0;
236} 232}
@@ -448,6 +444,10 @@ static struct snd_soc_dai_driver omap_dmic_dai = {
448 .ops = &omap_dmic_dai_ops, 444 .ops = &omap_dmic_dai_ops,
449}; 445};
450 446
447static const struct snd_soc_component_driver omap_dmic_component = {
448 .name = "omap-dmic",
449};
450
451static int asoc_dmic_probe(struct platform_device *pdev) 451static int asoc_dmic_probe(struct platform_device *pdev)
452{ 452{
453 struct omap_dmic *dmic; 453 struct omap_dmic *dmic;
@@ -476,7 +476,7 @@ static int asoc_dmic_probe(struct platform_device *pdev)
476 ret = -ENODEV; 476 ret = -ENODEV;
477 goto err_put_clk; 477 goto err_put_clk;
478 } 478 }
479 omap_dmic_dai_dma_params.port_addr = res->start + OMAP_DMIC_DATA_REG; 479 dmic->dma_data.addr = res->start + OMAP_DMIC_DATA_REG;
480 480
481 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 481 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
482 if (!res) { 482 if (!res) {
@@ -484,7 +484,9 @@ static int asoc_dmic_probe(struct platform_device *pdev)
484 ret = -ENODEV; 484 ret = -ENODEV;
485 goto err_put_clk; 485 goto err_put_clk;
486 } 486 }
487 omap_dmic_dai_dma_params.dma_req = res->start; 487
488 dmic->dma_req = res->start;
489 dmic->dma_data.filter_data = &dmic->dma_req;
488 490
489 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); 491 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
490 if (!res) { 492 if (!res) {
@@ -493,21 +495,12 @@ static int asoc_dmic_probe(struct platform_device *pdev)
493 goto err_put_clk; 495 goto err_put_clk;
494 } 496 }
495 497
496 if (!devm_request_mem_region(&pdev->dev, res->start, 498 dmic->io_base = devm_ioremap_resource(&pdev->dev, res);
497 resource_size(res), pdev->name)) { 499 if (IS_ERR(dmic->io_base))
498 dev_err(dmic->dev, "memory region already claimed\n"); 500 return PTR_ERR(dmic->io_base);
499 ret = -ENODEV;
500 goto err_put_clk;
501 }
502
503 dmic->io_base = devm_ioremap(&pdev->dev, res->start,
504 resource_size(res));
505 if (!dmic->io_base) {
506 ret = -ENOMEM;
507 goto err_put_clk;
508 }
509 501
510 ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai); 502 ret = snd_soc_register_component(&pdev->dev, &omap_dmic_component,
503 &omap_dmic_dai, 1);
511 if (ret) 504 if (ret)
512 goto err_put_clk; 505 goto err_put_clk;
513 506
@@ -522,7 +515,7 @@ static int asoc_dmic_remove(struct platform_device *pdev)
522{ 515{
523 struct omap_dmic *dmic = platform_get_drvdata(pdev); 516 struct omap_dmic *dmic = platform_get_drvdata(pdev);
524 517
525 snd_soc_unregister_dai(&pdev->dev); 518 snd_soc_unregister_component(&pdev->dev);
526 clk_put(dmic->fclk); 519 clk_put(dmic->fclk);
527 520
528 return 0; 521 return 0;
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c
index 32fa840c493e..ced3b88b44d4 100644
--- a/sound/soc/omap/omap-hdmi.c
+++ b/sound/soc/omap/omap-hdmi.c
@@ -32,15 +32,16 @@
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <sound/asound.h> 33#include <sound/asound.h>
34#include <sound/asoundef.h> 34#include <sound/asoundef.h>
35#include <sound/dmaengine_pcm.h>
35#include <video/omapdss.h> 36#include <video/omapdss.h>
36 37
37#include "omap-pcm.h"
38#include "omap-hdmi.h" 38#include "omap-hdmi.h"
39 39
40#define DRV_NAME "omap-hdmi-audio-dai" 40#define DRV_NAME "omap-hdmi-audio-dai"
41 41
42struct hdmi_priv { 42struct hdmi_priv {
43 struct omap_pcm_dma_data dma_params; 43 struct snd_dmaengine_dai_dma_data dma_data;
44 unsigned int dma_req;
44 struct omap_dss_audio dss_audio; 45 struct omap_dss_audio dss_audio;
45 struct snd_aes_iec958 iec; 46 struct snd_aes_iec958 iec;
46 struct snd_cea_861_aud_if cea; 47 struct snd_cea_861_aud_if cea;
@@ -68,7 +69,7 @@ static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
68 return -ENODEV; 69 return -ENODEV;
69 } 70 }
70 71
71 snd_soc_dai_set_dma_data(dai, substream, &priv->dma_params); 72 snd_soc_dai_set_dma_data(dai, substream, &priv->dma_data);
72 73
73 return 0; 74 return 0;
74} 75}
@@ -88,25 +89,20 @@ static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
88 struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai); 89 struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
89 struct snd_aes_iec958 *iec = &priv->iec; 90 struct snd_aes_iec958 *iec = &priv->iec;
90 struct snd_cea_861_aud_if *cea = &priv->cea; 91 struct snd_cea_861_aud_if *cea = &priv->cea;
91 struct omap_pcm_dma_data *dma_data;
92 int err = 0; 92 int err = 0;
93 93
94 dma_data = snd_soc_dai_get_dma_data(dai, substream);
95
96 switch (params_format(params)) { 94 switch (params_format(params)) {
97 case SNDRV_PCM_FORMAT_S16_LE: 95 case SNDRV_PCM_FORMAT_S16_LE:
98 dma_data->packet_size = 16; 96 priv->dma_data.maxburst = 16;
99 break; 97 break;
100 case SNDRV_PCM_FORMAT_S24_LE: 98 case SNDRV_PCM_FORMAT_S24_LE:
101 dma_data->packet_size = 32; 99 priv->dma_data.maxburst = 32;
102 break; 100 break;
103 default: 101 default:
104 dev_err(dai->dev, "format not supported!\n"); 102 dev_err(dai->dev, "format not supported!\n");
105 return -EINVAL; 103 return -EINVAL;
106 } 104 }
107 105
108 dma_data->data_type = 32;
109
110 /* 106 /*
111 * fill the IEC-60958 channel status word 107 * fill the IEC-60958 channel status word
112 */ 108 */
@@ -264,6 +260,10 @@ static struct snd_soc_dai_driver omap_hdmi_dai = {
264 .ops = &omap_hdmi_dai_ops, 260 .ops = &omap_hdmi_dai_ops,
265}; 261};
266 262
263static const struct snd_soc_component_driver omap_hdmi_component = {
264 .name = DRV_NAME,
265};
266
267static int omap_hdmi_probe(struct platform_device *pdev) 267static int omap_hdmi_probe(struct platform_device *pdev)
268{ 268{
269 int ret; 269 int ret;
@@ -283,8 +283,7 @@ static int omap_hdmi_probe(struct platform_device *pdev)
283 return -ENODEV; 283 return -ENODEV;
284 } 284 }
285 285
286 hdmi_data->dma_params.port_addr = hdmi_rsrc->start 286 hdmi_data->dma_data.addr = hdmi_rsrc->start + OMAP_HDMI_AUDIO_DMA_PORT;
287 + OMAP_HDMI_AUDIO_DMA_PORT;
288 287
289 hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0); 288 hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0);
290 if (!hdmi_rsrc) { 289 if (!hdmi_rsrc) {
@@ -292,8 +291,9 @@ static int omap_hdmi_probe(struct platform_device *pdev)
292 return -ENODEV; 291 return -ENODEV;
293 } 292 }
294 293
295 hdmi_data->dma_params.dma_req = hdmi_rsrc->start; 294 hdmi_data->dma_req = hdmi_rsrc->start;
296 hdmi_data->dma_params.name = "HDMI playback"; 295 hdmi_data->dma_data.filter_data = &hdmi_data->dma_req;
296 hdmi_data->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
297 297
298 /* 298 /*
299 * TODO: We assume that there is only one DSS HDMI device. Future 299 * TODO: We assume that there is only one DSS HDMI device. Future
@@ -321,7 +321,8 @@ static int omap_hdmi_probe(struct platform_device *pdev)
321 } 321 }
322 322
323 dev_set_drvdata(&pdev->dev, hdmi_data); 323 dev_set_drvdata(&pdev->dev, hdmi_data);
324 ret = snd_soc_register_dai(&pdev->dev, &omap_hdmi_dai); 324 ret = snd_soc_register_component(&pdev->dev, &omap_hdmi_component,
325 &omap_hdmi_dai, 1);
325 326
326 return ret; 327 return ret;
327} 328}
@@ -330,7 +331,7 @@ static int omap_hdmi_remove(struct platform_device *pdev)
330{ 331{
331 struct hdmi_priv *hdmi_data = dev_get_drvdata(&pdev->dev); 332 struct hdmi_priv *hdmi_data = dev_get_drvdata(&pdev->dev);
332 333
333 snd_soc_unregister_dai(&pdev->dev); 334 snd_soc_unregister_component(&pdev->dev);
334 335
335 if (hdmi_data == NULL) { 336 if (hdmi_data == NULL) {
336 dev_err(&pdev->dev, "cannot obtain HDMi data\n"); 337 dev_err(&pdev->dev, "cannot obtain HDMi data\n");
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 8d2defd6fdbe..eadbfb6b5000 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -33,11 +33,11 @@
33#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
34#include <sound/initval.h> 34#include <sound/initval.h>
35#include <sound/soc.h> 35#include <sound/soc.h>
36#include <sound/dmaengine_pcm.h>
36 37
37#include <linux/platform_data/asoc-ti-mcbsp.h> 38#include <linux/platform_data/asoc-ti-mcbsp.h>
38#include "mcbsp.h" 39#include "mcbsp.h"
39#include "omap-mcbsp.h" 40#include "omap-mcbsp.h"
40#include "omap-pcm.h"
41 41
42#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) 42#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
43 43
@@ -62,24 +62,22 @@ enum {
62 * Stream DMA parameters. DMA request line and port address are set runtime 62 * Stream DMA parameters. DMA request line and port address are set runtime
63 * since they are different between OMAP1 and later OMAPs 63 * since they are different between OMAP1 and later OMAPs
64 */ 64 */
65static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) 65static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream,
66 unsigned int packet_size)
66{ 67{
67 struct snd_soc_pcm_runtime *rtd = substream->private_data; 68 struct snd_soc_pcm_runtime *rtd = substream->private_data;
68 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 69 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
69 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); 70 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
70 struct omap_pcm_dma_data *dma_data;
71 int words; 71 int words;
72 72
73 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
74
75 /* 73 /*
76 * Configure McBSP threshold based on either: 74 * Configure McBSP threshold based on either:
77 * packet_size, when the sDMA is in packet mode, or based on the 75 * packet_size, when the sDMA is in packet mode, or based on the
78 * period size in THRESHOLD mode, otherwise use McBSP threshold = 1 76 * period size in THRESHOLD mode, otherwise use McBSP threshold = 1
79 * for mono streams. 77 * for mono streams.
80 */ 78 */
81 if (dma_data->packet_size) 79 if (packet_size)
82 words = dma_data->packet_size; 80 words = packet_size;
83 else 81 else
84 words = 1; 82 words = 1;
85 83
@@ -226,7 +224,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
226{ 224{
227 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); 225 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
228 struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; 226 struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
229 struct omap_pcm_dma_data *dma_data; 227 struct snd_dmaengine_dai_dma_data *dma_data;
230 int wlen, channels, wpf; 228 int wlen, channels, wpf;
231 int pkt_size = 0; 229 int pkt_size = 0;
232 unsigned int format, div, framesize, master; 230 unsigned int format, div, framesize, master;
@@ -245,7 +243,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
245 return -EINVAL; 243 return -EINVAL;
246 } 244 }
247 if (mcbsp->pdata->buffer_size) { 245 if (mcbsp->pdata->buffer_size) {
248 dma_data->set_threshold = omap_mcbsp_set_threshold;
249 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { 246 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
250 int period_words, max_thrsh; 247 int period_words, max_thrsh;
251 int divider = 0; 248 int divider = 0;
@@ -276,9 +273,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
276 /* Use packet mode for non mono streams */ 273 /* Use packet mode for non mono streams */
277 pkt_size = channels; 274 pkt_size = channels;
278 } 275 }
276 omap_mcbsp_set_threshold(substream, pkt_size);
279 } 277 }
280 278
281 dma_data->packet_size = pkt_size; 279 dma_data->maxburst = pkt_size;
282 280
283 if (mcbsp->configured) { 281 if (mcbsp->configured) {
284 /* McBSP already configured by another stream */ 282 /* McBSP already configured by another stream */
@@ -586,6 +584,10 @@ static struct snd_soc_dai_driver omap_mcbsp_dai = {
586 .ops = &mcbsp_dai_ops, 584 .ops = &mcbsp_dai_ops,
587}; 585};
588 586
587static const struct snd_soc_component_driver omap_mcbsp_component = {
588 .name = "omap-mcbsp",
589};
590
589static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol, 591static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
590 struct snd_ctl_elem_info *uinfo) 592 struct snd_ctl_elem_info *uinfo)
591{ 593{
@@ -793,7 +795,8 @@ static int asoc_mcbsp_probe(struct platform_device *pdev)
793 795
794 ret = omap_mcbsp_init(pdev); 796 ret = omap_mcbsp_init(pdev);
795 if (!ret) 797 if (!ret)
796 return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai); 798 return snd_soc_register_component(&pdev->dev, &omap_mcbsp_component,
799 &omap_mcbsp_dai, 1);
797 800
798 return ret; 801 return ret;
799} 802}
@@ -802,7 +805,7 @@ static int asoc_mcbsp_remove(struct platform_device *pdev)
802{ 805{
803 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); 806 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
804 807
805 snd_soc_unregister_dai(&pdev->dev); 808 snd_soc_unregister_component(&pdev->dev);
806 809
807 if (mcbsp->pdata->ops && mcbsp->pdata->ops->free) 810 if (mcbsp->pdata->ops && mcbsp->pdata->ops->free)
808 mcbsp->pdata->ops->free(mcbsp->id); 811 mcbsp->pdata->ops->free(mcbsp->id);
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 5ca11bdac21e..eb05c7ed6d05 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -39,11 +39,14 @@
39#include <sound/pcm.h> 39#include <sound/pcm.h>
40#include <sound/pcm_params.h> 40#include <sound/pcm_params.h>
41#include <sound/soc.h> 41#include <sound/soc.h>
42#include <sound/dmaengine_pcm.h>
42 43
43#include "omap-mcpdm.h" 44#include "omap-mcpdm.h"
44#include "omap-pcm.h"
45 45
46#define OMAP44XX_MCPDM_L3_BASE 0x49032000 46struct mcpdm_link_config {
47 u32 link_mask; /* channel mask for the direction */
48 u32 threshold; /* FIFO threshold */
49};
47 50
48struct omap_mcpdm { 51struct omap_mcpdm {
49 struct device *dev; 52 struct device *dev;
@@ -53,29 +56,22 @@ struct omap_mcpdm {
53 56
54 struct mutex mutex; 57 struct mutex mutex;
55 58
56 /* channel data */ 59 /* Playback/Capture configuration */
57 u32 dn_channels; 60 struct mcpdm_link_config config[2];
58 u32 up_channels;
59
60 /* McPDM FIFO thresholds */
61 u32 dn_threshold;
62 u32 up_threshold;
63 61
64 /* McPDM dn offsets for rx1, and 2 channels */ 62 /* McPDM dn offsets for rx1, and 2 channels */
65 u32 dn_rx_offset; 63 u32 dn_rx_offset;
64
65 /* McPDM needs to be restarted due to runtime reconfiguration */
66 bool restart;
67
68 struct snd_dmaengine_dai_dma_data dma_data[2];
69 unsigned int dma_req[2];
66}; 70};
67 71
68/* 72/*
69 * Stream DMA parameters 73 * Stream DMA parameters
70 */ 74 */
71static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
72 {
73 .name = "Audio playback",
74 },
75 {
76 .name = "Audio capture",
77 },
78};
79 75
80static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val) 76static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val)
81{ 77{
@@ -130,11 +126,12 @@ static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {}
130static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) 126static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
131{ 127{
132 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); 128 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
129 u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask;
133 130
134 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 131 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
135 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 132 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
136 133
137 ctrl |= mcpdm->dn_channels | mcpdm->up_channels; 134 ctrl |= link_mask;
138 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 135 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
139 136
140 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 137 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
@@ -148,11 +145,12 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
148static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm) 145static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm)
149{ 146{
150 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); 147 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
148 u32 link_mask = MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK;
151 149
152 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 150 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
153 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 151 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
154 152
155 ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels); 153 ctrl &= ~(link_mask);
156 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 154 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
157 155
158 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 156 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
@@ -188,8 +186,10 @@ static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm)
188 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); 186 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
189 } 187 }
190 188
191 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold); 189 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN,
192 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold); 190 mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold);
191 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP,
192 mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold);
193 193
194 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET, 194 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET,
195 MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE); 195 MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE);
@@ -267,7 +267,7 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
267 mutex_unlock(&mcpdm->mutex); 267 mutex_unlock(&mcpdm->mutex);
268 268
269 snd_soc_dai_set_dma_data(dai, substream, 269 snd_soc_dai_set_dma_data(dai, substream,
270 &omap_mcpdm_dai_dma_params[substream->stream]); 270 &mcpdm->dma_data[substream->stream]);
271 271
272 return 0; 272 return 0;
273} 273}
@@ -283,6 +283,8 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
283 if (omap_mcpdm_active(mcpdm)) { 283 if (omap_mcpdm_active(mcpdm)) {
284 omap_mcpdm_stop(mcpdm); 284 omap_mcpdm_stop(mcpdm);
285 omap_mcpdm_close_streams(mcpdm); 285 omap_mcpdm_close_streams(mcpdm);
286 mcpdm->config[0].link_mask = 0;
287 mcpdm->config[1].link_mask = 0;
286 } 288 }
287 } 289 }
288 290
@@ -295,7 +297,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
295{ 297{
296 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); 298 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
297 int stream = substream->stream; 299 int stream = substream->stream;
298 struct omap_pcm_dma_data *dma_data; 300 struct snd_dmaengine_dai_dma_data *dma_data;
301 u32 threshold;
299 int channels; 302 int channels;
300 int link_mask = 0; 303 int link_mask = 0;
301 304
@@ -325,16 +328,32 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
325 328
326 dma_data = snd_soc_dai_get_dma_data(dai, substream); 329 dma_data = snd_soc_dai_get_dma_data(dai, substream);
327 330
331 threshold = mcpdm->config[stream].threshold;
328 /* Configure McPDM channels, and DMA packet size */ 332 /* Configure McPDM channels, and DMA packet size */
329 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 333 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
330 mcpdm->dn_channels = link_mask << 3; 334 link_mask <<= 3;
331 dma_data->packet_size = 335
332 (MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels; 336 /* If capture is not running assume a stereo stream to come */
337 if (!mcpdm->config[!stream].link_mask)
338 mcpdm->config[!stream].link_mask = 0x3;
339
340 dma_data->maxburst =
341 (MCPDM_DN_THRES_MAX - threshold) * channels;
333 } else { 342 } else {
334 mcpdm->up_channels = link_mask << 0; 343 /* If playback is not running assume a stereo stream to come */
335 dma_data->packet_size = mcpdm->up_threshold * channels; 344 if (!mcpdm->config[!stream].link_mask)
345 mcpdm->config[!stream].link_mask = (0x3 << 3);
346
347 dma_data->maxburst = threshold * channels;
336 } 348 }
337 349
350 /* Check if we need to restart McPDM with this stream */
351 if (mcpdm->config[stream].link_mask &&
352 mcpdm->config[stream].link_mask != link_mask)
353 mcpdm->restart = true;
354
355 mcpdm->config[stream].link_mask = link_mask;
356
338 return 0; 357 return 0;
339} 358}
340 359
@@ -346,6 +365,11 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
346 if (!omap_mcpdm_active(mcpdm)) { 365 if (!omap_mcpdm_active(mcpdm)) {
347 omap_mcpdm_start(mcpdm); 366 omap_mcpdm_start(mcpdm);
348 omap_mcpdm_reg_dump(mcpdm); 367 omap_mcpdm_reg_dump(mcpdm);
368 } else if (mcpdm->restart) {
369 omap_mcpdm_stop(mcpdm);
370 omap_mcpdm_start(mcpdm);
371 mcpdm->restart = false;
372 omap_mcpdm_reg_dump(mcpdm);
349 } 373 }
350 374
351 return 0; 375 return 0;
@@ -369,7 +393,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
369 pm_runtime_get_sync(mcpdm->dev); 393 pm_runtime_get_sync(mcpdm->dev);
370 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00); 394 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00);
371 395
372 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, 396 ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler,
373 0, "McPDM", (void *)mcpdm); 397 0, "McPDM", (void *)mcpdm);
374 398
375 pm_runtime_put_sync(mcpdm->dev); 399 pm_runtime_put_sync(mcpdm->dev);
@@ -380,8 +404,9 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
380 } 404 }
381 405
382 /* Configure McPDM threshold values */ 406 /* Configure McPDM threshold values */
383 mcpdm->dn_threshold = 2; 407 mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2;
384 mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3; 408 mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold =
409 MCPDM_UP_THRES_MAX - 3;
385 return ret; 410 return ret;
386} 411}
387 412
@@ -389,7 +414,6 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
389{ 414{
390 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); 415 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
391 416
392 free_irq(mcpdm->irq, (void *)mcpdm);
393 pm_runtime_disable(mcpdm->dev); 417 pm_runtime_disable(mcpdm->dev);
394 418
395 return 0; 419 return 0;
@@ -420,6 +444,10 @@ static struct snd_soc_dai_driver omap_mcpdm_dai = {
420 .ops = &omap_mcpdm_dai_ops, 444 .ops = &omap_mcpdm_dai_ops,
421}; 445};
422 446
447static const struct snd_soc_component_driver omap_mcpdm_component = {
448 .name = "omap-mcpdm",
449};
450
423void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd, 451void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd,
424 u8 rx1, u8 rx2) 452 u8 rx1, u8 rx2)
425{ 453{
@@ -446,33 +474,30 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
446 if (res == NULL) 474 if (res == NULL)
447 return -ENOMEM; 475 return -ENOMEM;
448 476
449 omap_mcpdm_dai_dma_params[0].port_addr = res->start + MCPDM_REG_DN_DATA; 477 mcpdm->dma_data[0].addr = res->start + MCPDM_REG_DN_DATA;
450 omap_mcpdm_dai_dma_params[1].port_addr = res->start + MCPDM_REG_UP_DATA; 478 mcpdm->dma_data[1].addr = res->start + MCPDM_REG_UP_DATA;
451 479
452 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link"); 480 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link");
453 if (!res) 481 if (!res)
454 return -ENODEV; 482 return -ENODEV;
455 483
456 omap_mcpdm_dai_dma_params[0].dma_req = res->start; 484 mcpdm->dma_req[0] = res->start;
485 mcpdm->dma_data[0].filter_data = &mcpdm->dma_req[0];
457 486
458 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link"); 487 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link");
459 if (!res) 488 if (!res)
460 return -ENODEV; 489 return -ENODEV;
461 490
462 omap_mcpdm_dai_dma_params[1].dma_req = res->start; 491 mcpdm->dma_req[1] = res->start;
492 mcpdm->dma_data[1].filter_data = &mcpdm->dma_req[1];
463 493
464 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); 494 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
465 if (res == NULL) 495 if (res == NULL)
466 return -ENOMEM; 496 return -ENOMEM;
467 497
468 if (!devm_request_mem_region(&pdev->dev, res->start, 498 mcpdm->io_base = devm_ioremap_resource(&pdev->dev, res);
469 resource_size(res), "McPDM")) 499 if (IS_ERR(mcpdm->io_base))
470 return -EBUSY; 500 return PTR_ERR(mcpdm->io_base);
471
472 mcpdm->io_base = devm_ioremap(&pdev->dev, res->start,
473 resource_size(res));
474 if (!mcpdm->io_base)
475 return -ENOMEM;
476 501
477 mcpdm->irq = platform_get_irq(pdev, 0); 502 mcpdm->irq = platform_get_irq(pdev, 0);
478 if (mcpdm->irq < 0) 503 if (mcpdm->irq < 0)
@@ -480,12 +505,13 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
480 505
481 mcpdm->dev = &pdev->dev; 506 mcpdm->dev = &pdev->dev;
482 507
483 return snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); 508 return snd_soc_register_component(&pdev->dev, &omap_mcpdm_component,
509 &omap_mcpdm_dai, 1);
484} 510}
485 511
486static int asoc_mcpdm_remove(struct platform_device *pdev) 512static int asoc_mcpdm_remove(struct platform_device *pdev)
487{ 513{
488 snd_soc_unregister_dai(&pdev->dev); 514 snd_soc_unregister_component(&pdev->dev);
489 return 0; 515 return 0;
490} 516}
491 517
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index c722c2ef9665..c8e272f9c2de 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -32,8 +32,6 @@
32#include <sound/dmaengine_pcm.h> 32#include <sound/dmaengine_pcm.h>
33#include <sound/soc.h> 33#include <sound/soc.h>
34 34
35#include "omap-pcm.h"
36
37#ifdef CONFIG_ARCH_OMAP1 35#ifdef CONFIG_ARCH_OMAP1
38#define pcm_omap1510() cpu_is_omap1510() 36#define pcm_omap1510() cpu_is_omap1510()
39#else 37#else
@@ -56,25 +54,6 @@ static const struct snd_pcm_hardware omap_pcm_hardware = {
56 .buffer_bytes_max = 128 * 1024, 54 .buffer_bytes_max = 128 * 1024,
57}; 55};
58 56
59static int omap_pcm_get_dma_buswidth(int num_bits)
60{
61 int buswidth;
62
63 switch (num_bits) {
64 case 16:
65 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
66 break;
67 case 32:
68 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
69 break;
70 default:
71 buswidth = -EINVAL;
72 break;
73 }
74 return buswidth;
75}
76
77
78/* this may get called several times by oss emulation */ 57/* this may get called several times by oss emulation */
79static int omap_pcm_hw_params(struct snd_pcm_substream *substream, 58static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
80 struct snd_pcm_hw_params *params) 59 struct snd_pcm_hw_params *params)
@@ -105,20 +84,9 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
105 if (err) 84 if (err)
106 return err; 85 return err;
107 86
108 /* Override the *_dma addr_width if requested by the DAI driver */ 87 snd_dmaengine_pcm_set_config_from_dai_data(substream,
109 if (dma_data->data_type) { 88 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
110 int buswidth = omap_pcm_get_dma_buswidth(dma_data->data_type); 89 &config);
111
112 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
113 config.dst_addr_width = buswidth;
114 else
115 config.src_addr_width = buswidth;
116 }
117
118 config.src_addr = dma_data->port_addr;
119 config.dst_addr = dma_data->port_addr;
120 config.src_maxburst = dma_data->packet_size;
121 config.dst_maxburst = dma_data->packet_size;
122 90
123 return dmaengine_slave_config(chan, &config); 91 return dmaengine_slave_config(chan, &config);
124} 92}
@@ -129,37 +97,6 @@ static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
129 return 0; 97 return 0;
130} 98}
131 99
132static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
133{
134 struct snd_soc_pcm_runtime *rtd = substream->private_data;
135 struct omap_pcm_dma_data *dma_data;
136 int ret = 0;
137
138 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
139
140 switch (cmd) {
141 case SNDRV_PCM_TRIGGER_START:
142 case SNDRV_PCM_TRIGGER_RESUME:
143 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
144 /* Configure McBSP internal buffer usage */
145 if (dma_data->set_threshold)
146 dma_data->set_threshold(substream);
147 break;
148
149 case SNDRV_PCM_TRIGGER_STOP:
150 case SNDRV_PCM_TRIGGER_SUSPEND:
151 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
152 break;
153 default:
154 ret = -EINVAL;
155 }
156
157 if (ret == 0)
158 ret = snd_dmaengine_pcm_trigger(substream, cmd);
159
160 return ret;
161}
162
163static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) 100static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
164{ 101{
165 snd_pcm_uframes_t offset; 102 snd_pcm_uframes_t offset;
@@ -175,20 +112,14 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
175static int omap_pcm_open(struct snd_pcm_substream *substream) 112static int omap_pcm_open(struct snd_pcm_substream *substream)
176{ 113{
177 struct snd_soc_pcm_runtime *rtd = substream->private_data; 114 struct snd_soc_pcm_runtime *rtd = substream->private_data;
178 struct omap_pcm_dma_data *dma_data; 115 struct snd_dmaengine_dai_dma_data *dma_data;
179 116
180 snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware); 117 snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
181 118
182 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 119 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
183 120
184 return snd_dmaengine_pcm_open(substream, omap_dma_filter_fn, 121 return snd_dmaengine_pcm_open(substream, omap_dma_filter_fn,
185 &dma_data->dma_req); 122 dma_data->filter_data);
186}
187
188static int omap_pcm_close(struct snd_pcm_substream *substream)
189{
190 snd_dmaengine_pcm_close(substream);
191 return 0;
192} 123}
193 124
194static int omap_pcm_mmap(struct snd_pcm_substream *substream, 125static int omap_pcm_mmap(struct snd_pcm_substream *substream,
@@ -204,11 +135,11 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream,
204 135
205static struct snd_pcm_ops omap_pcm_ops = { 136static struct snd_pcm_ops omap_pcm_ops = {
206 .open = omap_pcm_open, 137 .open = omap_pcm_open,
207 .close = omap_pcm_close, 138 .close = snd_dmaengine_pcm_close,
208 .ioctl = snd_pcm_lib_ioctl, 139 .ioctl = snd_pcm_lib_ioctl,
209 .hw_params = omap_pcm_hw_params, 140 .hw_params = omap_pcm_hw_params,
210 .hw_free = omap_pcm_hw_free, 141 .hw_free = omap_pcm_hw_free,
211 .trigger = omap_pcm_trigger, 142 .trigger = snd_dmaengine_pcm_trigger,
212 .pointer = omap_pcm_pointer, 143 .pointer = omap_pcm_pointer,
213 .mmap = omap_pcm_mmap, 144 .mmap = omap_pcm_mmap,
214}; 145};
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
deleted file mode 100644
index cabe74c4068b..000000000000
--- a/sound/soc/omap/omap-pcm.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * omap-pcm.h
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 *
6 * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __OMAP_PCM_H__
26#define __OMAP_PCM_H__
27
28struct snd_pcm_substream;
29
30struct omap_pcm_dma_data {
31 char *name; /* stream identifier */
32 int dma_req; /* DMA request line */
33 unsigned long port_addr; /* transmit/receive register */
34 void (*set_threshold)(struct snd_pcm_substream *substream);
35 int data_type; /* 8, 16, 32 (bits) or 0 to let omap-pcm
36 * to decide the sDMA data type */
37 int packet_size; /* packet size only in PACKET mode */
38};
39
40#endif
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
index fd98509d0f49..2a9324f794d8 100644
--- a/sound/soc/omap/omap-twl4030.c
+++ b/sound/soc/omap/omap-twl4030.c
@@ -43,7 +43,6 @@
43#include <sound/jack.h> 43#include <sound/jack.h>
44 44
45#include "omap-mcbsp.h" 45#include "omap-mcbsp.h"
46#include "omap-pcm.h"
47 46
48struct omap_twl4030 { 47struct omap_twl4030 {
49 int jack_detect; /* board can detect jack events */ 48 int jack_detect; /* board can detect jack events */
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 805512f2555a..cf604a2faa18 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -34,7 +34,6 @@
34#include <linux/platform_data/asoc-ti-mcbsp.h> 34#include <linux/platform_data/asoc-ti-mcbsp.h>
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38 37
39#define OMAP3_PANDORA_DAC_POWER_GPIO 118 38#define OMAP3_PANDORA_DAC_POWER_GPIO 118
40#define OMAP3_PANDORA_AMP_POWER_GPIO 14 39#define OMAP3_PANDORA_AMP_POWER_GPIO 14
@@ -80,12 +79,18 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream,
80static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, 79static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w,
81 struct snd_kcontrol *k, int event) 80 struct snd_kcontrol *k, int event)
82{ 81{
82 int ret;
83
83 /* 84 /*
84 * The PCM1773 DAC datasheet requires 1ms delay between switching 85 * The PCM1773 DAC datasheet requires 1ms delay between switching
85 * VCC power on/off and /PD pin high/low 86 * VCC power on/off and /PD pin high/low
86 */ 87 */
87 if (SND_SOC_DAPM_EVENT_ON(event)) { 88 if (SND_SOC_DAPM_EVENT_ON(event)) {
88 regulator_enable(omap3pandora_dac_reg); 89 ret = regulator_enable(omap3pandora_dac_reg);
90 if (ret) {
91 dev_err(w->dapm->dev, "Failed to power DAC: %d\n", ret);
92 return ret;
93 }
89 mdelay(1); 94 mdelay(1);
90 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1); 95 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
91 } else { 96 } else {
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index 06ef8d67ed1c..d03e57da7708 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -33,7 +33,6 @@
33#include <linux/platform_data/asoc-ti-mcbsp.h> 33#include <linux/platform_data/asoc-ti-mcbsp.h>
34 34
35#include "omap-mcbsp.h" 35#include "omap-mcbsp.h"
36#include "omap-pcm.h"
37#include "../codecs/tlv320aic23.h" 36#include "../codecs/tlv320aic23.h"
38 37
39#define CODEC_CLOCK 12000000 38#define CODEC_CLOCK 12000000
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 3cd525748975..249cd230ad8f 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -37,7 +37,6 @@
37#include <asm/mach-types.h> 37#include <asm/mach-types.h>
38 38
39#include "omap-mcbsp.h" 39#include "omap-mcbsp.h"
40#include "omap-pcm.h"
41 40
42#define RX51_TVOUT_SEL_GPIO 40 41#define RX51_TVOUT_SEL_GPIO 40
43#define RX51_JACK_DETECT_GPIO 177 42#define RX51_JACK_DETECT_GPIO 177
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
index 190eb0bccf5f..6c3980252bf6 100644
--- a/sound/soc/pxa/mmp-pcm.c
+++ b/sound/soc/pxa/mmp-pcm.c
@@ -118,9 +118,8 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream)
118 struct snd_soc_pcm_runtime *rtd = substream->private_data; 118 struct snd_soc_pcm_runtime *rtd = substream->private_data;
119 struct platform_device *pdev = to_platform_device(rtd->platform->dev); 119 struct platform_device *pdev = to_platform_device(rtd->platform->dev);
120 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 120 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
121 struct mmp_dma_data *dma_data; 121 struct mmp_dma_data dma_data;
122 struct resource *r; 122 struct resource *r;
123 int ret;
124 123
125 r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream); 124 r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream);
126 if (!r) 125 if (!r)
@@ -128,33 +127,11 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream)
128 127
129 snd_soc_set_runtime_hwparams(substream, 128 snd_soc_set_runtime_hwparams(substream,
130 &mmp_pcm_hardware[substream->stream]); 129 &mmp_pcm_hardware[substream->stream]);
131 dma_data = devm_kzalloc(&pdev->dev,
132 sizeof(struct mmp_dma_data), GFP_KERNEL);
133 if (dma_data == NULL)
134 return -ENOMEM;
135 130
136 dma_data->dma_res = r; 131 dma_data.dma_res = r;
137 dma_data->ssp_id = cpu_dai->id; 132 dma_data.ssp_id = cpu_dai->id;
138 133
139 ret = snd_dmaengine_pcm_open(substream, filter, dma_data); 134 return snd_dmaengine_pcm_open(substream, filter, &dma_data);
140 if (ret) {
141 devm_kfree(&pdev->dev, dma_data);
142 return ret;
143 }
144
145 snd_dmaengine_pcm_set_data(substream, dma_data);
146 return 0;
147}
148
149static int mmp_pcm_close(struct snd_pcm_substream *substream)
150{
151 struct mmp_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
152 struct snd_soc_pcm_runtime *rtd = substream->private_data;
153 struct platform_device *pdev = to_platform_device(rtd->platform->dev);
154
155 snd_dmaengine_pcm_close(substream);
156 devm_kfree(&pdev->dev, dma_data);
157 return 0;
158} 135}
159 136
160static int mmp_pcm_mmap(struct snd_pcm_substream *substream, 137static int mmp_pcm_mmap(struct snd_pcm_substream *substream,
@@ -171,7 +148,7 @@ static int mmp_pcm_mmap(struct snd_pcm_substream *substream,
171 148
172struct snd_pcm_ops mmp_pcm_ops = { 149struct snd_pcm_ops mmp_pcm_ops = {
173 .open = mmp_pcm_open, 150 .open = mmp_pcm_open,
174 .close = mmp_pcm_close, 151 .close = snd_dmaengine_pcm_close,
175 .ioctl = snd_pcm_lib_ioctl, 152 .ioctl = snd_pcm_lib_ioctl,
176 .hw_params = mmp_pcm_hw_params, 153 .hw_params = mmp_pcm_hw_params,
177 .trigger = snd_dmaengine_pcm_trigger, 154 .trigger = snd_dmaengine_pcm_trigger,
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
index 9140c4abafbc..a64779980177 100644
--- a/sound/soc/pxa/mmp-sspa.c
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -405,6 +405,10 @@ struct snd_soc_dai_driver mmp_sspa_dai = {
405 .ops = &mmp_sspa_dai_ops, 405 .ops = &mmp_sspa_dai_ops,
406}; 406};
407 407
408static const struct snd_soc_component_driver mmp_sspa_component = {
409 .name = "mmp-sspa",
410};
411
408static int asoc_mmp_sspa_probe(struct platform_device *pdev) 412static int asoc_mmp_sspa_probe(struct platform_device *pdev)
409{ 413{
410 struct sspa_priv *priv; 414 struct sspa_priv *priv;
@@ -450,7 +454,8 @@ static int asoc_mmp_sspa_probe(struct platform_device *pdev)
450 priv->dai_fmt = (unsigned int) -1; 454 priv->dai_fmt = (unsigned int) -1;
451 platform_set_drvdata(pdev, priv); 455 platform_set_drvdata(pdev, priv);
452 456
453 return snd_soc_register_dai(&pdev->dev, &mmp_sspa_dai); 457 return snd_soc_register_component(&pdev->dev, &mmp_sspa_component,
458 &mmp_sspa_dai, 1);
454} 459}
455 460
456static int asoc_mmp_sspa_remove(struct platform_device *pdev) 461static int asoc_mmp_sspa_remove(struct platform_device *pdev)
@@ -460,7 +465,7 @@ static int asoc_mmp_sspa_remove(struct platform_device *pdev)
460 clk_disable(priv->audio_clk); 465 clk_disable(priv->audio_clk);
461 clk_put(priv->audio_clk); 466 clk_put(priv->audio_clk);
462 clk_put(priv->sysclk); 467 clk_put(priv->sysclk);
463 snd_soc_unregister_dai(&pdev->dev); 468 snd_soc_unregister_component(&pdev->dev);
464 return 0; 469 return 0;
465} 470}
466 471
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index d3eb0c2eec77..6f4dd7543e82 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -794,14 +794,19 @@ static struct snd_soc_dai_driver pxa_ssp_dai = {
794 .ops = &pxa_ssp_dai_ops, 794 .ops = &pxa_ssp_dai_ops,
795}; 795};
796 796
797static const struct snd_soc_component_driver pxa_ssp_component = {
798 .name = "pxa-ssp",
799};
800
797static int asoc_ssp_probe(struct platform_device *pdev) 801static int asoc_ssp_probe(struct platform_device *pdev)
798{ 802{
799 return snd_soc_register_dai(&pdev->dev, &pxa_ssp_dai); 803 return snd_soc_register_component(&pdev->dev, &pxa_ssp_component,
804 &pxa_ssp_dai, 1);
800} 805}
801 806
802static int asoc_ssp_remove(struct platform_device *pdev) 807static int asoc_ssp_remove(struct platform_device *pdev)
803{ 808{
804 snd_soc_unregister_dai(&pdev->dev); 809 snd_soc_unregister_component(&pdev->dev);
805 return 0; 810 return 0;
806} 811}
807 812
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 4b0a009bd683..57ea8e6c5488 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -47,6 +47,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
47 .warm_reset = pxa2xx_ac97_warm_reset, 47 .warm_reset = pxa2xx_ac97_warm_reset,
48 .reset = pxa2xx_ac97_cold_reset, 48 .reset = pxa2xx_ac97_cold_reset,
49}; 49};
50EXPORT_SYMBOL_GPL(soc_ac97_ops);
50 51
51static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { 52static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
52 .name = "AC97 PCM Stereo out", 53 .name = "AC97 PCM Stereo out",
@@ -232,7 +233,9 @@ static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = {
232}, 233},
233}; 234};
234 235
235EXPORT_SYMBOL_GPL(soc_ac97_ops); 236static const struct snd_soc_component_driver pxa_ac97_component = {
237 .name = "pxa-ac97",
238};
236 239
237static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) 240static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
238{ 241{
@@ -245,13 +248,13 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
245 * driver to do interesting things with the clocking to get us up 248 * driver to do interesting things with the clocking to get us up
246 * and running. 249 * and running.
247 */ 250 */
248 return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai_driver, 251 return snd_soc_register_component(&pdev->dev, &pxa_ac97_component,
249 ARRAY_SIZE(pxa_ac97_dai_driver)); 252 pxa_ac97_dai_driver, ARRAY_SIZE(pxa_ac97_dai_driver));
250} 253}
251 254
252static int pxa2xx_ac97_dev_remove(struct platform_device *pdev) 255static int pxa2xx_ac97_dev_remove(struct platform_device *pdev)
253{ 256{
254 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai_driver)); 257 snd_soc_unregister_component(&pdev->dev);
255 return 0; 258 return 0;
256} 259}
257 260
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 6b1a06f67564..f7ca71664112 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -360,14 +360,19 @@ static struct snd_soc_dai_driver pxa_i2s_dai = {
360 .symmetric_rates = 1, 360 .symmetric_rates = 1,
361}; 361};
362 362
363static const struct snd_soc_component_driver pxa_i2s_component = {
364 .name = "pxa-i2s",
365};
366
363static int pxa2xx_i2s_drv_probe(struct platform_device *pdev) 367static int pxa2xx_i2s_drv_probe(struct platform_device *pdev)
364{ 368{
365 return snd_soc_register_dai(&pdev->dev, &pxa_i2s_dai); 369 return snd_soc_register_component(&pdev->dev, &pxa_i2s_component,
370 &pxa_i2s_dai, 1);
366} 371}
367 372
368static int pxa2xx_i2s_drv_remove(struct platform_device *pdev) 373static int pxa2xx_i2s_drv_remove(struct platform_device *pdev)
369{ 374{
370 snd_soc_unregister_dai(&pdev->dev); 375 snd_soc_unregister_component(&pdev->dev);
371 return 0; 376 return 0;
372} 377}
373 378
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index fee4d477a49c..73bb99f0109a 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -436,6 +436,10 @@ static struct snd_soc_dai_driver s6000_i2s_dai = {
436 .ops = &s6000_i2s_dai_ops, 436 .ops = &s6000_i2s_dai_ops,
437}; 437};
438 438
439static const struct snd_soc_component_driver s6000_i2s_component = {
440 .name = "s6000-i2s",
441};
442
439static int s6000_i2s_probe(struct platform_device *pdev) 443static int s6000_i2s_probe(struct platform_device *pdev)
440{ 444{
441 struct s6000_i2s_dev *dev; 445 struct s6000_i2s_dev *dev;
@@ -543,7 +547,8 @@ static int s6000_i2s_probe(struct platform_device *pdev)
543 S6_I2S_INT_UNDERRUN | 547 S6_I2S_INT_UNDERRUN |
544 S6_I2S_INT_OVERRUN); 548 S6_I2S_INT_OVERRUN);
545 549
546 ret = snd_soc_register_dai(&pdev->dev, &s6000_i2s_dai); 550 ret = snd_soc_register_component(&pdev->dev, &s6000_i2s_component,
551 &s6000_i2s_dai, 1);
547 if (ret) 552 if (ret)
548 goto err_release_dev; 553 goto err_release_dev;
549 554
@@ -572,7 +577,7 @@ static void s6000_i2s_remove(struct platform_device *pdev)
572 struct resource *region; 577 struct resource *region;
573 void __iomem *mmio = dev->scbbase; 578 void __iomem *mmio = dev->scbbase;
574 579
575 snd_soc_unregister_dai(&pdev->dev); 580 snd_soc_unregister_component(&pdev->dev);
576 581
577 s6000_i2s_stop_channel(dev, 0); 582 s6000_i2s_stop_channel(dev, 0);
578 s6000_i2s_stop_channel(dev, 1); 583 s6000_i2s_stop_channel(dev, 1);
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 90e7e6653233..475fb0d8b3c6 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -35,11 +35,10 @@ config SND_SAMSUNG_I2S
35 tristate 35 tristate
36 36
37config SND_SOC_SAMSUNG_NEO1973_WM8753 37config SND_SOC_SAMSUNG_NEO1973_WM8753
38 tristate "Audio support for Openmoko Neo1973 Smartphones (GTA01/GTA02)" 38 tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)"
39 depends on SND_SOC_SAMSUNG && (MACH_NEO1973_GTA01 || MACH_NEO1973_GTA02) 39 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02
40 select SND_S3C24XX_I2S 40 select SND_S3C24XX_I2S
41 select SND_SOC_WM8753 41 select SND_SOC_WM8753
42 select SND_SOC_LM4857 if MACH_NEO1973_GTA01
43 select SND_SOC_DFBMCS320 42 select SND_SOC_DFBMCS320
44 help 43 help
45 Say Y here to enable audio support for the Openmoko Neo1973 44 Say Y here to enable audio support for the Openmoko Neo1973
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 0df3c5644cfa..cb88ead98917 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -20,7 +20,7 @@
20#include <sound/soc.h> 20#include <sound/soc.h>
21 21
22#include <mach/dma.h> 22#include <mach/dma.h>
23#include <plat/regs-ac97.h> 23#include "regs-ac97.h"
24#include <linux/platform_data/asoc-s3c.h> 24#include <linux/platform_data/asoc-s3c.h>
25 25
26#include "dma.h" 26#include "dma.h"
@@ -370,6 +370,10 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = {
370 }, 370 },
371}; 371};
372 372
373static const struct snd_soc_component_driver s3c_ac97_component = {
374 .name = "s3c-ac97",
375};
376
373static int s3c_ac97_probe(struct platform_device *pdev) 377static int s3c_ac97_probe(struct platform_device *pdev)
374{ 378{
375 struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; 379 struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res;
@@ -457,8 +461,8 @@ static int s3c_ac97_probe(struct platform_device *pdev)
457 goto err4; 461 goto err4;
458 } 462 }
459 463
460 ret = snd_soc_register_dais(&pdev->dev, s3c_ac97_dai, 464 ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component,
461 ARRAY_SIZE(s3c_ac97_dai)); 465 s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
462 if (ret) 466 if (ret)
463 goto err5; 467 goto err5;
464 468
@@ -470,7 +474,7 @@ static int s3c_ac97_probe(struct platform_device *pdev)
470 474
471 return 0; 475 return 0;
472err6: 476err6:
473 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); 477 snd_soc_unregister_component(&pdev->dev);
474err5: 478err5:
475 free_irq(irq_res->start, NULL); 479 free_irq(irq_res->start, NULL);
476err4: 480err4:
@@ -490,7 +494,7 @@ static int s3c_ac97_remove(struct platform_device *pdev)
490 struct resource *mem_res, *irq_res; 494 struct resource *mem_res, *irq_res;
491 495
492 asoc_dma_platform_unregister(&pdev->dev); 496 asoc_dma_platform_unregister(&pdev->dev);
493 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); 497 snd_soc_unregister_component(&pdev->dev);
494 498
495 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 499 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
496 if (irq_res) 500 if (irq_res)
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index d37ede58e0a8..415ad81999c4 100644
--- a/sound/soc/samsung/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -218,6 +218,10 @@ static struct snd_soc_dai_driver voice_dai = {
218 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 218 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
219}; 219};
220 220
221static const struct snd_soc_component_driver voice_component = {
222 .name = "goni-voice",
223};
224
221static struct snd_soc_ops goni_voice_ops = { 225static struct snd_soc_ops goni_voice_ops = {
222 .hw_params = goni_voice_hw_params, 226 .hw_params = goni_voice_hw_params,
223}; 227};
@@ -270,7 +274,8 @@ static int __init goni_init(void)
270 return -ENOMEM; 274 return -ENOMEM;
271 275
272 /* register voice DAI here */ 276 /* register voice DAI here */
273 ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai); 277 ret = snd_soc_register_component(&goni_snd_device->dev, &voice_component,
278 &voice_dai, 1);
274 if (ret) { 279 if (ret) {
275 platform_device_put(goni_snd_device); 280 platform_device_put(goni_snd_device);
276 return ret; 281 return ret;
@@ -280,7 +285,7 @@ static int __init goni_init(void)
280 ret = platform_device_add(goni_snd_device); 285 ret = platform_device_add(goni_snd_device);
281 286
282 if (ret) { 287 if (ret) {
283 snd_soc_unregister_dai(&goni_snd_device->dev); 288 snd_soc_unregister_component(&goni_snd_device->dev);
284 platform_device_put(goni_snd_device); 289 platform_device_put(goni_snd_device);
285 } 290 }
286 291
@@ -289,7 +294,7 @@ static int __init goni_init(void)
289 294
290static void __exit goni_exit(void) 295static void __exit goni_exit(void)
291{ 296{
292 snd_soc_unregister_dai(&goni_snd_device->dev); 297 snd_soc_unregister_component(&goni_snd_device->dev);
293 platform_device_unregister(goni_snd_device); 298 platform_device_unregister(goni_snd_device);
294} 299}
295 300
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index 15a3817aa5c8..fa91376e323d 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -20,7 +20,7 @@
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/jack.h> 21#include <sound/jack.h>
22 22
23#include <plat/regs-iis.h> 23#include "regs-iis.h"
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25 25
26#include "s3c24xx-i2s.h" 26#include "s3c24xx-i2s.h"
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index d7231e336a7c..82ebb1a51479 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -963,6 +963,10 @@ static const struct snd_soc_dai_ops samsung_i2s_dai_ops = {
963 .delay = i2s_delay, 963 .delay = i2s_delay,
964}; 964};
965 965
966static const struct snd_soc_component_driver samsung_i2s_component = {
967 .name = "samsung-i2s",
968};
969
966#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 970#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000
967 971
968#define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ 972#define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
@@ -972,6 +976,7 @@ static const struct snd_soc_dai_ops samsung_i2s_dai_ops = {
972static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) 976static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
973{ 977{
974 struct i2s_dai *i2s; 978 struct i2s_dai *i2s;
979 int ret;
975 980
976 i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL); 981 i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL);
977 if (i2s == NULL) 982 if (i2s == NULL)
@@ -996,15 +1001,17 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
996 i2s->i2s_dai_drv.capture.channels_max = 2; 1001 i2s->i2s_dai_drv.capture.channels_max = 2;
997 i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; 1002 i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES;
998 i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; 1003 i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
1004 dev_set_drvdata(&i2s->pdev->dev, i2s);
999 } else { /* Create a new platform_device for Secondary */ 1005 } else { /* Create a new platform_device for Secondary */
1000 i2s->pdev = platform_device_register_resndata(NULL, 1006 i2s->pdev = platform_device_alloc("samsung-i2s-sec", -1);
1001 "samsung-i2s-sec", -1, NULL, 0, NULL, 0);
1002 if (IS_ERR(i2s->pdev)) 1007 if (IS_ERR(i2s->pdev))
1003 return NULL; 1008 return NULL;
1004 }
1005 1009
1006 /* Pre-assign snd_soc_dai_set_drvdata */ 1010 platform_set_drvdata(i2s->pdev, i2s);
1007 dev_set_drvdata(&i2s->pdev->dev, i2s); 1011 ret = platform_device_add(i2s->pdev);
1012 if (ret < 0)
1013 return NULL;
1014 }
1008 1015
1009 return i2s; 1016 return i2s;
1010} 1017}
@@ -1107,8 +1114,13 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1107 1114
1108 if (samsung_dai_type == TYPE_SEC) { 1115 if (samsung_dai_type == TYPE_SEC) {
1109 sec_dai = dev_get_drvdata(&pdev->dev); 1116 sec_dai = dev_get_drvdata(&pdev->dev);
1110 snd_soc_register_dai(&sec_dai->pdev->dev, 1117 if (!sec_dai) {
1111 &sec_dai->i2s_dai_drv); 1118 dev_err(&pdev->dev, "Unable to get drvdata\n");
1119 return -EFAULT;
1120 }
1121 snd_soc_register_component(&sec_dai->pdev->dev,
1122 &samsung_i2s_component,
1123 &sec_dai->i2s_dai_drv, 1);
1112 asoc_dma_platform_register(&pdev->dev); 1124 asoc_dma_platform_register(&pdev->dev);
1113 return 0; 1125 return 0;
1114 } 1126 }
@@ -1237,7 +1249,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1237 } 1249 }
1238 } 1250 }
1239 1251
1240 snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv); 1252 snd_soc_register_component(&pri_dai->pdev->dev, &samsung_i2s_component,
1253 &pri_dai->i2s_dai_drv, 1);
1241 1254
1242 pm_runtime_enable(&pdev->dev); 1255 pm_runtime_enable(&pdev->dev);
1243 1256
@@ -1276,7 +1289,7 @@ static int samsung_i2s_remove(struct platform_device *pdev)
1276 i2s->sec_dai = NULL; 1289 i2s->sec_dai = NULL;
1277 1290
1278 asoc_dma_platform_unregister(&pdev->dev); 1291 asoc_dma_platform_unregister(&pdev->dev);
1279 snd_soc_unregister_dai(&pdev->dev); 1292 snd_soc_unregister_component(&pdev->dev);
1280 1293
1281 return 0; 1294 return 0;
1282} 1295}
@@ -1291,7 +1304,7 @@ static struct platform_device_id samsung_i2s_driver_ids[] = {
1291 }, 1304 },
1292 {}, 1305 {},
1293}; 1306};
1294MODULE_DEVICE_TABLE(platform, samsung-i2s-driver-ids); 1307MODULE_DEVICE_TABLE(platform, samsung_i2s_driver_ids);
1295 1308
1296#ifdef CONFIG_OF 1309#ifdef CONFIG_OF
1297static struct samsung_i2s_dai_data samsung_i2s_dai_data_array[] = { 1310static struct samsung_i2s_dai_data samsung_i2s_dai_data_array[] = {
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c
index a07950b0c8ce..6e5fed30aa27 100644
--- a/sound/soc/samsung/idma.c
+++ b/sound/soc/samsung/idma.c
@@ -68,6 +68,8 @@ static struct idma_info {
68 dma_addr_t lp_tx_addr; 68 dma_addr_t lp_tx_addr;
69} idma; 69} idma;
70 70
71static int idma_irq;
72
71static void idma_getpos(dma_addr_t *src) 73static void idma_getpos(dma_addr_t *src)
72{ 74{
73 *src = idma.lp_tx_addr + 75 *src = idma.lp_tx_addr +
@@ -305,7 +307,7 @@ static int idma_open(struct snd_pcm_substream *substream)
305 if (prtd == NULL) 307 if (prtd == NULL)
306 return -ENOMEM; 308 return -ENOMEM;
307 309
308 ret = request_irq(IRQ_I2S0, iis_irq, 0, "i2s", prtd); 310 ret = request_irq(idma_irq, iis_irq, 0, "i2s", prtd);
309 if (ret < 0) { 311 if (ret < 0) {
310 pr_err("fail to claim i2s irq , ret = %d\n", ret); 312 pr_err("fail to claim i2s irq , ret = %d\n", ret);
311 kfree(prtd); 313 kfree(prtd);
@@ -324,7 +326,7 @@ static int idma_close(struct snd_pcm_substream *substream)
324 struct snd_pcm_runtime *runtime = substream->runtime; 326 struct snd_pcm_runtime *runtime = substream->runtime;
325 struct idma_ctrl *prtd = runtime->private_data; 327 struct idma_ctrl *prtd = runtime->private_data;
326 328
327 free_irq(IRQ_I2S0, prtd); 329 free_irq(idma_irq, prtd);
328 330
329 if (!prtd) 331 if (!prtd)
330 pr_err("idma_close called with prtd == NULL\n"); 332 pr_err("idma_close called with prtd == NULL\n");
@@ -409,6 +411,7 @@ void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr)
409 idma.regs = regs; 411 idma.regs = regs;
410 idma.lp_tx_addr = addr; 412 idma.lp_tx_addr = addr;
411} 413}
414EXPORT_SYMBOL_GPL(idma_reg_addr_init);
412 415
413static struct snd_soc_platform_driver asoc_idma_platform = { 416static struct snd_soc_platform_driver asoc_idma_platform = {
414 .ops = &idma_ops, 417 .ops = &idma_ops,
@@ -418,6 +421,10 @@ static struct snd_soc_platform_driver asoc_idma_platform = {
418 421
419static int asoc_idma_platform_probe(struct platform_device *pdev) 422static int asoc_idma_platform_probe(struct platform_device *pdev)
420{ 423{
424 idma_irq = platform_get_irq(pdev, 0);
425 if (idma_irq < 0)
426 return idma_irq;
427
421 return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform); 428 return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform);
422} 429}
423 430
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index a301d8cfaa34..e591c386917a 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -21,8 +21,7 @@
21#include <sound/soc.h> 21#include <sound/soc.h>
22 22
23#include <asm/mach-types.h> 23#include <asm/mach-types.h>
24#include <plat/regs-iis.h> 24#include "regs-iis.h"
25#include <mach/gta02.h>
26 25
27#include "../codecs/wm8753.h" 26#include "../codecs/wm8753.h"
28#include "s3c24xx-i2s.h" 27#include "s3c24xx-i2s.h"
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 13bab79ad93d..1566afe9ef52 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -490,6 +490,10 @@ static struct snd_soc_dai_driver s3c_pcm_dai[] = {
490 }, 490 },
491}; 491};
492 492
493static const struct snd_soc_component_driver s3c_pcm_component = {
494 .name = "s3c-pcm",
495};
496
493static int s3c_pcm_dev_probe(struct platform_device *pdev) 497static int s3c_pcm_dev_probe(struct platform_device *pdev)
494{ 498{
495 struct s3c_pcm_info *pcm; 499 struct s3c_pcm_info *pcm;
@@ -583,7 +587,8 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
583 587
584 pm_runtime_enable(&pdev->dev); 588 pm_runtime_enable(&pdev->dev);
585 589
586 ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]); 590 ret = snd_soc_register_component(&pdev->dev, &s3c_pcm_component,
591 &s3c_pcm_dai[pdev->id], 1);
587 if (ret != 0) { 592 if (ret != 0) {
588 dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret); 593 dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret);
589 goto err5; 594 goto err5;
@@ -598,7 +603,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
598 return 0; 603 return 0;
599 604
600err6: 605err6:
601 snd_soc_unregister_dai(&pdev->dev); 606 snd_soc_unregister_component(&pdev->dev);
602err5: 607err5:
603 clk_disable_unprepare(pcm->pclk); 608 clk_disable_unprepare(pcm->pclk);
604 clk_put(pcm->pclk); 609 clk_put(pcm->pclk);
@@ -619,7 +624,7 @@ static int s3c_pcm_dev_remove(struct platform_device *pdev)
619 struct resource *mem_res; 624 struct resource *mem_res;
620 625
621 asoc_dma_platform_unregister(&pdev->dev); 626 asoc_dma_platform_unregister(&pdev->dev);
622 snd_soc_unregister_dai(&pdev->dev); 627 snd_soc_unregister_component(&pdev->dev);
623 628
624 pm_runtime_disable(&pdev->dev); 629 pm_runtime_disable(&pdev->dev);
625 630
diff --git a/sound/soc/samsung/regs-ac97.h b/sound/soc/samsung/regs-ac97.h
new file mode 100644
index 000000000000..c3878f7acb83
--- /dev/null
+++ b/sound/soc/samsung/regs-ac97.h
@@ -0,0 +1,67 @@
1/* arch/arm/mach-s3c2410/include/mach/regs-ac97.h
2 *
3 * Copyright (c) 2006 Simtec Electronics <linux@simtec.co.uk>
4 * http://www.simtec.co.uk/products/SWLINUX/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * S3C2440 AC97 Controller
11*/
12
13#ifndef __ASM_ARCH_REGS_AC97_H
14#define __ASM_ARCH_REGS_AC97_H __FILE__
15
16#define S3C_AC97_GLBCTRL (0x00)
17
18#define S3C_AC97_GLBCTRL_CODECREADYIE (1<<22)
19#define S3C_AC97_GLBCTRL_PCMOUTURIE (1<<21)
20#define S3C_AC97_GLBCTRL_PCMINORIE (1<<20)
21#define S3C_AC97_GLBCTRL_MICINORIE (1<<19)
22#define S3C_AC97_GLBCTRL_PCMOUTTIE (1<<18)
23#define S3C_AC97_GLBCTRL_PCMINTIE (1<<17)
24#define S3C_AC97_GLBCTRL_MICINTIE (1<<16)
25#define S3C_AC97_GLBCTRL_PCMOUTTM_OFF (0<<12)
26#define S3C_AC97_GLBCTRL_PCMOUTTM_PIO (1<<12)
27#define S3C_AC97_GLBCTRL_PCMOUTTM_DMA (2<<12)
28#define S3C_AC97_GLBCTRL_PCMOUTTM_MASK (3<<12)
29#define S3C_AC97_GLBCTRL_PCMINTM_OFF (0<<10)
30#define S3C_AC97_GLBCTRL_PCMINTM_PIO (1<<10)
31#define S3C_AC97_GLBCTRL_PCMINTM_DMA (2<<10)
32#define S3C_AC97_GLBCTRL_PCMINTM_MASK (3<<10)
33#define S3C_AC97_GLBCTRL_MICINTM_OFF (0<<8)
34#define S3C_AC97_GLBCTRL_MICINTM_PIO (1<<8)
35#define S3C_AC97_GLBCTRL_MICINTM_DMA (2<<8)
36#define S3C_AC97_GLBCTRL_MICINTM_MASK (3<<8)
37#define S3C_AC97_GLBCTRL_TRANSFERDATAENABLE (1<<3)
38#define S3C_AC97_GLBCTRL_ACLINKON (1<<2)
39#define S3C_AC97_GLBCTRL_WARMRESET (1<<1)
40#define S3C_AC97_GLBCTRL_COLDRESET (1<<0)
41
42#define S3C_AC97_GLBSTAT (0x04)
43
44#define S3C_AC97_GLBSTAT_CODECREADY (1<<22)
45#define S3C_AC97_GLBSTAT_PCMOUTUR (1<<21)
46#define S3C_AC97_GLBSTAT_PCMINORI (1<<20)
47#define S3C_AC97_GLBSTAT_MICINORI (1<<19)
48#define S3C_AC97_GLBSTAT_PCMOUTTI (1<<18)
49#define S3C_AC97_GLBSTAT_PCMINTI (1<<17)
50#define S3C_AC97_GLBSTAT_MICINTI (1<<16)
51#define S3C_AC97_GLBSTAT_MAINSTATE_IDLE (0<<0)
52#define S3C_AC97_GLBSTAT_MAINSTATE_INIT (1<<0)
53#define S3C_AC97_GLBSTAT_MAINSTATE_READY (2<<0)
54#define S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE (3<<0)
55#define S3C_AC97_GLBSTAT_MAINSTATE_LP (4<<0)
56#define S3C_AC97_GLBSTAT_MAINSTATE_WARM (5<<0)
57
58#define S3C_AC97_CODEC_CMD (0x08)
59
60#define S3C_AC97_CODEC_CMD_READ (1<<23)
61
62#define S3C_AC97_STAT (0x0c)
63#define S3C_AC97_PCM_ADDR (0x10)
64#define S3C_AC97_PCM_DATA (0x18)
65#define S3C_AC97_MIC_DATA (0x1C)
66
67#endif /* __ASM_ARCH_REGS_AC97_H */
diff --git a/sound/soc/samsung/regs-iis.h b/sound/soc/samsung/regs-iis.h
new file mode 100644
index 000000000000..a18d35e7a735
--- /dev/null
+++ b/sound/soc/samsung/regs-iis.h
@@ -0,0 +1,70 @@
1/* arch/arm/plat-samsung/include/plat/regs-iis.h
2 *
3 * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
4 * http://www.simtec.co.uk/products/SWLINUX/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * S3C2410 IIS register definition
11*/
12
13#ifndef __ASM_ARCH_REGS_IIS_H
14#define __ASM_ARCH_REGS_IIS_H
15
16#define S3C2410_IISCON (0x00)
17
18#define S3C2410_IISCON_LRINDEX (1 << 8)
19#define S3C2410_IISCON_TXFIFORDY (1 << 7)
20#define S3C2410_IISCON_RXFIFORDY (1 << 6)
21#define S3C2410_IISCON_TXDMAEN (1 << 5)
22#define S3C2410_IISCON_RXDMAEN (1 << 4)
23#define S3C2410_IISCON_TXIDLE (1 << 3)
24#define S3C2410_IISCON_RXIDLE (1 << 2)
25#define S3C2410_IISCON_PSCEN (1 << 1)
26#define S3C2410_IISCON_IISEN (1 << 0)
27
28#define S3C2410_IISMOD (0x04)
29
30#define S3C2440_IISMOD_MPLL (1 << 9)
31#define S3C2410_IISMOD_SLAVE (1 << 8)
32#define S3C2410_IISMOD_NOXFER (0 << 6)
33#define S3C2410_IISMOD_RXMODE (1 << 6)
34#define S3C2410_IISMOD_TXMODE (2 << 6)
35#define S3C2410_IISMOD_TXRXMODE (3 << 6)
36#define S3C2410_IISMOD_LR_LLOW (0 << 5)
37#define S3C2410_IISMOD_LR_RLOW (1 << 5)
38#define S3C2410_IISMOD_IIS (0 << 4)
39#define S3C2410_IISMOD_MSB (1 << 4)
40#define S3C2410_IISMOD_8BIT (0 << 3)
41#define S3C2410_IISMOD_16BIT (1 << 3)
42#define S3C2410_IISMOD_BITMASK (1 << 3)
43#define S3C2410_IISMOD_256FS (0 << 2)
44#define S3C2410_IISMOD_384FS (1 << 2)
45#define S3C2410_IISMOD_16FS (0 << 0)
46#define S3C2410_IISMOD_32FS (1 << 0)
47#define S3C2410_IISMOD_48FS (2 << 0)
48#define S3C2410_IISMOD_FS_MASK (3 << 0)
49
50#define S3C2410_IISPSR (0x08)
51
52#define S3C2410_IISPSR_INTMASK (31 << 5)
53#define S3C2410_IISPSR_INTSHIFT (5)
54#define S3C2410_IISPSR_EXTMASK (31 << 0)
55#define S3C2410_IISPSR_EXTSHFIT (0)
56
57#define S3C2410_IISFCON (0x0c)
58
59#define S3C2410_IISFCON_TXDMA (1 << 15)
60#define S3C2410_IISFCON_RXDMA (1 << 14)
61#define S3C2410_IISFCON_TXENABLE (1 << 13)
62#define S3C2410_IISFCON_RXENABLE (1 << 12)
63#define S3C2410_IISFCON_TXMASK (0x3f << 6)
64#define S3C2410_IISFCON_TXSHIFT (6)
65#define S3C2410_IISFCON_RXMASK (0x3f)
66#define S3C2410_IISFCON_RXSHIFT (0)
67
68#define S3C2410_IISFIFO (0x10)
69
70#endif /* __ASM_ARCH_REGS_IIS_H */
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index a5826ea9cad6..704460a37005 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -24,7 +24,7 @@
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/jack.h> 25#include <sound/jack.h>
26 26
27#include <plat/regs-iis.h> 27#include "regs-iis.h"
28#include <asm/mach-types.h> 28#include <asm/mach-types.h>
29 29
30#include "s3c24xx-i2s.h" 30#include "s3c24xx-i2s.h"
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index 7a73380b3560..20e98d1dded2 100644
--- a/sound/soc/samsung/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -731,8 +731,9 @@ static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
731#define s3c2412_i2s_resume NULL 731#define s3c2412_i2s_resume NULL
732#endif 732#endif
733 733
734int s3c_i2sv2_register_dai(struct device *dev, int id, 734int s3c_i2sv2_register_component(struct device *dev, int id,
735 struct snd_soc_dai_driver *drv) 735 struct snd_soc_component_driver *cmp_drv,
736 struct snd_soc_dai_driver *dai_drv)
736{ 737{
737 struct snd_soc_dai_ops *ops = drv->ops; 738 struct snd_soc_dai_ops *ops = drv->ops;
738 739
@@ -750,8 +751,8 @@ int s3c_i2sv2_register_dai(struct device *dev, int id,
750 drv->suspend = s3c2412_i2s_suspend; 751 drv->suspend = s3c2412_i2s_suspend;
751 drv->resume = s3c2412_i2s_resume; 752 drv->resume = s3c2412_i2s_resume;
752 753
753 return snd_soc_register_dai(dev, drv); 754 return snd_soc_register_component(dev, cmp_drv, dai_drv, 1);
754} 755}
755EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai); 756EXPORT_SYMBOL_GPL(s3c_i2sv2_register_component);
756 757
757MODULE_LICENSE("GPL"); 758MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h
index f8297d9bb8a3..90abab364b49 100644
--- a/sound/soc/samsung/s3c-i2s-v2.h
+++ b/sound/soc/samsung/s3c-i2s-v2.h
@@ -92,7 +92,7 @@ extern int s3c_i2sv2_probe(struct snd_soc_dai *dai,
92 unsigned long base); 92 unsigned long base);
93 93
94/** 94/**
95 * s3c_i2sv2_register_dai - register dai with soc core 95 * s3c_i2sv2_register_component - register component and dai with soc core
96 * @dev: DAI device 96 * @dev: DAI device
97 * @id: DAI ID 97 * @id: DAI ID
98 * @drv: The driver structure to register 98 * @drv: The driver structure to register
@@ -100,7 +100,8 @@ extern int s3c_i2sv2_probe(struct snd_soc_dai *dai,
100 * Fill in any missing fields and then register the given dai with the 100 * Fill in any missing fields and then register the given dai with the
101 * soc core. 101 * soc core.
102 */ 102 */
103extern int s3c_i2sv2_register_dai(struct device *dev, int id, 103extern int s3c_i2sv2_register_component(struct device *dev, int id,
104 struct snd_soc_dai_driver *drv); 104 struct snd_soc_component_driver *cmp_drv,
105 struct snd_soc_dai_driver *dai_drv);
105 106
106#endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */ 107#endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 221337716393..47e23864ea72 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -160,11 +160,17 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = {
160 .ops = &s3c2412_i2s_dai_ops, 160 .ops = &s3c2412_i2s_dai_ops,
161}; 161};
162 162
163static const struct snd_soc_component_driver s3c2412_i2s_component = {
164 .name = "s3c2412-i2s",
165};
166
163static int s3c2412_iis_dev_probe(struct platform_device *pdev) 167static int s3c2412_iis_dev_probe(struct platform_device *pdev)
164{ 168{
165 int ret = 0; 169 int ret = 0;
166 170
167 ret = s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); 171 ret = s3c_i2sv2_register_component(&pdev->dev, -1,
172 &s3c2412_i2s_component,
173 &s3c2412_i2s_dai);
168 if (ret) { 174 if (ret) {
169 pr_err("failed to register the dai\n"); 175 pr_err("failed to register the dai\n");
170 return ret; 176 return ret;
@@ -178,14 +184,14 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
178 184
179 return 0; 185 return 0;
180err: 186err:
181 snd_soc_unregister_dai(&pdev->dev); 187 snd_soc_unregister_component(&pdev->dev);
182 return ret; 188 return ret;
183} 189}
184 190
185static int s3c2412_iis_dev_remove(struct platform_device *pdev) 191static int s3c2412_iis_dev_remove(struct platform_device *pdev)
186{ 192{
187 asoc_dma_platform_unregister(&pdev->dev); 193 asoc_dma_platform_unregister(&pdev->dev);
188 snd_soc_unregister_dai(&pdev->dev); 194 snd_soc_unregister_component(&pdev->dev);
189 return 0; 195 return 0;
190} 196}
191 197
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 13f6dd1ceb00..8b3414551a62 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -24,7 +24,7 @@
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25 25
26#include <mach/dma.h> 26#include <mach/dma.h>
27#include <plat/regs-iis.h> 27#include "regs-iis.h"
28 28
29#include "dma.h" 29#include "dma.h"
30#include "s3c24xx-i2s.h" 30#include "s3c24xx-i2s.h"
@@ -465,11 +465,16 @@ static struct snd_soc_dai_driver s3c24xx_i2s_dai = {
465 .ops = &s3c24xx_i2s_dai_ops, 465 .ops = &s3c24xx_i2s_dai_ops,
466}; 466};
467 467
468static const struct snd_soc_component_driver s3c24xx_i2s_component = {
469 .name = "s3c24xx-i2s",
470};
471
468static int s3c24xx_iis_dev_probe(struct platform_device *pdev) 472static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
469{ 473{
470 int ret = 0; 474 int ret = 0;
471 475
472 ret = snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai); 476 ret = snd_soc_register_component(&pdev->dev, &s3c24xx_i2s_component,
477 &s3c24xx_i2s_dai, 1);
473 if (ret) { 478 if (ret) {
474 pr_err("failed to register the dai\n"); 479 pr_err("failed to register the dai\n");
475 return ret; 480 return ret;
@@ -483,14 +488,14 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
483 488
484 return 0; 489 return 0;
485err: 490err:
486 snd_soc_unregister_dai(&pdev->dev); 491 snd_soc_unregister_component(&pdev->dev);
487 return ret; 492 return ret;
488} 493}
489 494
490static int s3c24xx_iis_dev_remove(struct platform_device *pdev) 495static int s3c24xx_iis_dev_remove(struct platform_device *pdev)
491{ 496{
492 asoc_dma_platform_unregister(&pdev->dev); 497 asoc_dma_platform_unregister(&pdev->dev);
493 snd_soc_unregister_dai(&pdev->dev); 498 snd_soc_unregister_component(&pdev->dev);
494 return 0; 499 return 0;
495} 500}
496 501
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index 333e1b7f06c7..1b7b52b0af97 100644
--- a/sound/soc/samsung/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -18,7 +18,7 @@
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/s3c24xx_uda134x.h> 19#include <sound/s3c24xx_uda134x.h>
20 20
21#include <plat/regs-iis.h> 21#include "regs-iis.h"
22 22
23#include "s3c24xx-i2s.h" 23#include "s3c24xx-i2s.h"
24 24
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index 5008e5bd6ed8..2e5ebb2f1982 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -357,6 +357,10 @@ static struct snd_soc_dai_driver samsung_spdif_dai = {
357 .resume = spdif_resume, 357 .resume = spdif_resume,
358}; 358};
359 359
360static const struct snd_soc_component_driver samsung_spdif_component = {
361 .name = "samsung-spdif",
362};
363
360static int spdif_probe(struct platform_device *pdev) 364static int spdif_probe(struct platform_device *pdev)
361{ 365{
362 struct s3c_audio_pdata *spdif_pdata; 366 struct s3c_audio_pdata *spdif_pdata;
@@ -424,7 +428,8 @@ static int spdif_probe(struct platform_device *pdev)
424 428
425 dev_set_drvdata(&pdev->dev, spdif); 429 dev_set_drvdata(&pdev->dev, spdif);
426 430
427 ret = snd_soc_register_dai(&pdev->dev, &samsung_spdif_dai); 431 ret = snd_soc_register_component(&pdev->dev, &samsung_spdif_component,
432 &samsung_spdif_dai, 1);
428 if (ret != 0) { 433 if (ret != 0) {
429 dev_err(&pdev->dev, "fail to register dai\n"); 434 dev_err(&pdev->dev, "fail to register dai\n");
430 goto err4; 435 goto err4;
@@ -445,7 +450,7 @@ static int spdif_probe(struct platform_device *pdev)
445 450
446 return 0; 451 return 0;
447err5: 452err5:
448 snd_soc_unregister_dai(&pdev->dev); 453 snd_soc_unregister_component(&pdev->dev);
449err4: 454err4:
450 iounmap(spdif->regs); 455 iounmap(spdif->regs);
451err3: 456err3:
@@ -466,7 +471,7 @@ static int spdif_remove(struct platform_device *pdev)
466 struct resource *mem_res; 471 struct resource *mem_res;
467 472
468 asoc_dma_platform_unregister(&pdev->dev); 473 asoc_dma_platform_unregister(&pdev->dev);
469 snd_soc_unregister_dai(&pdev->dev); 474 snd_soc_unregister_component(&pdev->dev);
470 475
471 iounmap(spdif->regs); 476 iounmap(spdif->regs);
472 477
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index 19eff8fc4fdd..1a8b03e4b41b 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -342,8 +342,8 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd)
342 return 0; 342 return 0;
343} 343}
344 344
345static struct snd_soc_platform sh7760_soc_platform = { 345static struct snd_soc_platform_driver sh7760_soc_platform = {
346 .pcm_ops = &camelot_pcm_ops, 346 .ops = &camelot_pcm_ops,
347 .pcm_new = camelot_pcm_new, 347 .pcm_new = camelot_pcm_new,
348 .pcm_free = camelot_pcm_free, 348 .pcm_free = camelot_pcm_free,
349}; 349};
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index c724026a246f..f830c41f97dd 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -296,7 +296,6 @@ struct fsi_core {
296 296
297struct fsi_master { 297struct fsi_master {
298 void __iomem *base; 298 void __iomem *base;
299 int irq;
300 struct fsi_priv fsia; 299 struct fsi_priv fsia;
301 struct fsi_priv fsib; 300 struct fsi_priv fsib;
302 const struct fsi_core *core; 301 const struct fsi_core *core;
@@ -1886,6 +1885,10 @@ static struct snd_soc_platform_driver fsi_soc_platform = {
1886 .pcm_free = fsi_pcm_free, 1885 .pcm_free = fsi_pcm_free,
1887}; 1886};
1888 1887
1888static const struct snd_soc_component_driver fsi_soc_component = {
1889 .name = "fsi",
1890};
1891
1889/* 1892/*
1890 * platform function 1893 * platform function
1891 */ 1894 */
@@ -2002,7 +2005,6 @@ static int fsi_probe(struct platform_device *pdev)
2002 } 2005 }
2003 2006
2004 /* master setting */ 2007 /* master setting */
2005 master->irq = irq;
2006 master->core = core; 2008 master->core = core;
2007 spin_lock_init(&master->lock); 2009 spin_lock_init(&master->lock);
2008 2010
@@ -2046,10 +2048,10 @@ static int fsi_probe(struct platform_device *pdev)
2046 goto exit_fsib; 2048 goto exit_fsib;
2047 } 2049 }
2048 2050
2049 ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, 2051 ret = snd_soc_register_component(&pdev->dev, &fsi_soc_component,
2050 ARRAY_SIZE(fsi_soc_dai)); 2052 fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
2051 if (ret < 0) { 2053 if (ret < 0) {
2052 dev_err(&pdev->dev, "cannot snd dai register\n"); 2054 dev_err(&pdev->dev, "cannot snd component register\n");
2053 goto exit_snd_soc; 2055 goto exit_snd_soc;
2054 } 2056 }
2055 2057
@@ -2074,7 +2076,7 @@ static int fsi_remove(struct platform_device *pdev)
2074 2076
2075 pm_runtime_disable(&pdev->dev); 2077 pm_runtime_disable(&pdev->dev);
2076 2078
2077 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); 2079 snd_soc_unregister_component(&pdev->dev);
2078 snd_soc_unregister_platform(&pdev->dev); 2080 snd_soc_unregister_platform(&pdev->dev);
2079 2081
2080 fsi_stream_remove(&master->fsia); 2082 fsi_stream_remove(&master->fsia);
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index 4cc2d64ef476..af19f77b7bf0 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -310,15 +310,19 @@ static struct snd_soc_dai_driver sh4_hac_dai[] = {
310#endif 310#endif
311}; 311};
312 312
313static const struct snd_soc_component_driver sh4_hac_component = {
314 .name = "sh4-hac",
315};
316
313static int hac_soc_platform_probe(struct platform_device *pdev) 317static int hac_soc_platform_probe(struct platform_device *pdev)
314{ 318{
315 return snd_soc_register_dais(&pdev->dev, sh4_hac_dai, 319 return snd_soc_register_component(&pdev->dev, &sh4_hac_component,
316 ARRAY_SIZE(sh4_hac_dai)); 320 sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
317} 321}
318 322
319static int hac_soc_platform_remove(struct platform_device *pdev) 323static int hac_soc_platform_remove(struct platform_device *pdev)
320{ 324{
321 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_hac_dai)); 325 snd_soc_unregister_component(&pdev->dev);
322 return 0; 326 return 0;
323} 327}
324 328
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
index 8526e1edaf45..5014a884afee 100644
--- a/sound/soc/sh/migor.c
+++ b/sound/soc/sh/migor.c
@@ -153,7 +153,7 @@ static int migor_dai_init(struct snd_soc_pcm_runtime *rtd)
153static struct snd_soc_dai_link migor_dai = { 153static struct snd_soc_dai_link migor_dai = {
154 .name = "wm8978", 154 .name = "wm8978",
155 .stream_name = "WM8978", 155 .stream_name = "WM8978",
156 .cpu_dai_name = "siu-i2s-dai", 156 .cpu_dai_name = "siu-pcm-audio",
157 .codec_dai_name = "wm8978-hifi", 157 .codec_dai_name = "wm8978-hifi",
158 .platform_name = "siu-pcm-audio", 158 .platform_name = "siu-pcm-audio",
159 .codec_name = "wm8978.0-001a", 159 .codec_name = "wm8978.0-001a",
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index 34facdc9e4ac..9dc24ffa892a 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -726,6 +726,10 @@ static struct snd_soc_dai_driver siu_i2s_dai = {
726 .ops = &siu_dai_ops, 726 .ops = &siu_dai_ops,
727}; 727};
728 728
729static const struct snd_soc_component_driver siu_i2s_component = {
730 .name = "siu-i2s",
731};
732
729static int siu_probe(struct platform_device *pdev) 733static int siu_probe(struct platform_device *pdev)
730{ 734{
731 const struct firmware *fw_entry; 735 const struct firmware *fw_entry;
@@ -783,7 +787,8 @@ static int siu_probe(struct platform_device *pdev)
783 dev_set_drvdata(&pdev->dev, info); 787 dev_set_drvdata(&pdev->dev, info);
784 788
785 /* register using ARRAY version so we can keep dai name */ 789 /* register using ARRAY version so we can keep dai name */
786 ret = snd_soc_register_dais(&pdev->dev, &siu_i2s_dai, 1); 790 ret = snd_soc_register_component(&pdev->dev, &siu_i2s_component,
791 &siu_i2s_dai, 1);
787 if (ret < 0) 792 if (ret < 0)
788 goto edaiinit; 793 goto edaiinit;
789 794
@@ -796,7 +801,7 @@ static int siu_probe(struct platform_device *pdev)
796 return ret; 801 return ret;
797 802
798esocregp: 803esocregp:
799 snd_soc_unregister_dai(&pdev->dev); 804 snd_soc_unregister_component(&pdev->dev);
800edaiinit: 805edaiinit:
801 iounmap(info->reg); 806 iounmap(info->reg);
802emapreg: 807emapreg:
@@ -823,7 +828,7 @@ static int siu_remove(struct platform_device *pdev)
823 pm_runtime_disable(&pdev->dev); 828 pm_runtime_disable(&pdev->dev);
824 829
825 snd_soc_unregister_platform(&pdev->dev); 830 snd_soc_unregister_platform(&pdev->dev);
826 snd_soc_unregister_dai(&pdev->dev); 831 snd_soc_unregister_component(&pdev->dev);
827 832
828 iounmap(info->reg); 833 iounmap(info->reg);
829 iounmap(info->yram); 834 iounmap(info->yram);
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index c8e73a703934..e889405ebd38 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -379,15 +379,19 @@ static struct snd_soc_dai_driver sh4_ssi_dai[] = {
379#endif 379#endif
380}; 380};
381 381
382static const struct snd_soc_component_driver sh4_ssi_component = {
383 .name = "sh4-ssi",
384};
385
382static int sh4_soc_dai_probe(struct platform_device *pdev) 386static int sh4_soc_dai_probe(struct platform_device *pdev)
383{ 387{
384 return snd_soc_register_dais(&pdev->dev, sh4_ssi_dai, 388 return snd_soc_register_component(&pdev->dev, &sh4_ssi_component,
385 ARRAY_SIZE(sh4_ssi_dai)); 389 sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
386} 390}
387 391
388static int sh4_soc_dai_remove(struct platform_device *pdev) 392static int sh4_soc_dai_remove(struct platform_device *pdev)
389{ 393{
390 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai)); 394 snd_soc_unregister_component(&pdev->dev);
391 return 0; 395 return 0;
392} 396}
393 397
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index b5b3db71e253..29093a306ea2 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -211,19 +211,27 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
211 if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) { 211 if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
212 ret = platform->driver->compr_ops->set_params(cstream, params); 212 ret = platform->driver->compr_ops->set_params(cstream, params);
213 if (ret < 0) 213 if (ret < 0)
214 goto out; 214 goto err;
215 } 215 }
216 216
217 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) { 217 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
218 ret = rtd->dai_link->compr_ops->set_params(cstream); 218 ret = rtd->dai_link->compr_ops->set_params(cstream);
219 if (ret < 0) 219 if (ret < 0)
220 goto out; 220 goto err;
221 } 221 }
222 222
223 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, 223 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
224 SND_SOC_DAPM_STREAM_START); 224 SND_SOC_DAPM_STREAM_START);
225 225
226out: 226 /* cancel any delayed stream shutdown that is pending */
227 rtd->pop_wait = 0;
228 mutex_unlock(&rtd->pcm_mutex);
229
230 cancel_delayed_work_sync(&rtd->delayed_work);
231
232 return ret;
233
234err:
227 mutex_unlock(&rtd->pcm_mutex); 235 mutex_unlock(&rtd->pcm_mutex);
228 return ret; 236 return ret;
229} 237}
@@ -322,11 +330,38 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
322 return ret; 330 return ret;
323} 331}
324 332
333static int sst_compr_set_metadata(struct snd_compr_stream *cstream,
334 struct snd_compr_metadata *metadata)
335{
336 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
337 struct snd_soc_platform *platform = rtd->platform;
338 int ret = 0;
339
340 if (platform->driver->compr_ops && platform->driver->compr_ops->set_metadata)
341 ret = platform->driver->compr_ops->set_metadata(cstream, metadata);
342
343 return ret;
344}
345
346static int sst_compr_get_metadata(struct snd_compr_stream *cstream,
347 struct snd_compr_metadata *metadata)
348{
349 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
350 struct snd_soc_platform *platform = rtd->platform;
351 int ret = 0;
352
353 if (platform->driver->compr_ops && platform->driver->compr_ops->get_metadata)
354 ret = platform->driver->compr_ops->get_metadata(cstream, metadata);
355
356 return ret;
357}
325/* ASoC Compress operations */ 358/* ASoC Compress operations */
326static struct snd_compr_ops soc_compr_ops = { 359static struct snd_compr_ops soc_compr_ops = {
327 .open = soc_compr_open, 360 .open = soc_compr_open,
328 .free = soc_compr_free, 361 .free = soc_compr_free,
329 .set_params = soc_compr_set_params, 362 .set_params = soc_compr_set_params,
363 .set_metadata = sst_compr_set_metadata,
364 .get_metadata = sst_compr_get_metadata,
330 .get_params = soc_compr_get_params, 365 .get_params = soc_compr_get_params,
331 .trigger = soc_compr_trigger, 366 .trigger = soc_compr_trigger,
332 .pointer = soc_compr_pointer, 367 .pointer = soc_compr_pointer,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b7e84a7cd9ee..7bf21a1035ea 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -58,6 +58,7 @@ static DEFINE_MUTEX(client_mutex);
58static LIST_HEAD(dai_list); 58static LIST_HEAD(dai_list);
59static LIST_HEAD(platform_list); 59static LIST_HEAD(platform_list);
60static LIST_HEAD(codec_list); 60static LIST_HEAD(codec_list);
61static LIST_HEAD(component_list);
61 62
62/* 63/*
63 * This is a timeout to do a DAPM powerdown after a stream is closed(). 64 * This is a timeout to do a DAPM powerdown after a stream is closed().
@@ -2963,7 +2964,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
2963 val = val << shift; 2964 val = val << shift;
2964 2965
2965 ret = snd_soc_update_bits_locked(codec, reg, val_mask, val); 2966 ret = snd_soc_update_bits_locked(codec, reg, val_mask, val);
2966 if (ret != 0) 2967 if (ret < 0)
2967 return ret; 2968 return ret;
2968 2969
2969 if (snd_soc_volsw_is_stereo(mc)) { 2970 if (snd_soc_volsw_is_stereo(mc)) {
@@ -3140,7 +3141,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
3140 if (params->mask) { 3141 if (params->mask) {
3141 ret = regmap_read(codec->control_data, params->base, &val); 3142 ret = regmap_read(codec->control_data, params->base, &val);
3142 if (ret != 0) 3143 if (ret != 0)
3143 return ret; 3144 goto out;
3144 3145
3145 val &= params->mask; 3146 val &= params->mask;
3146 3147
@@ -3158,13 +3159,15 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
3158 ((u32 *)data)[0] |= cpu_to_be32(val); 3159 ((u32 *)data)[0] |= cpu_to_be32(val);
3159 break; 3160 break;
3160 default: 3161 default:
3161 return -EINVAL; 3162 ret = -EINVAL;
3163 goto out;
3162 } 3164 }
3163 } 3165 }
3164 3166
3165 ret = regmap_raw_write(codec->control_data, params->base, 3167 ret = regmap_raw_write(codec->control_data, params->base,
3166 data, len); 3168 data, len);
3167 3169
3170out:
3168 kfree(data); 3171 kfree(data);
3169 3172
3170 return ret; 3173 return ret;
@@ -3738,7 +3741,7 @@ static inline char *fmt_multiple_name(struct device *dev,
3738 * 3741 *
3739 * @dai: DAI to register 3742 * @dai: DAI to register
3740 */ 3743 */
3741int snd_soc_register_dai(struct device *dev, 3744static int snd_soc_register_dai(struct device *dev,
3742 struct snd_soc_dai_driver *dai_drv) 3745 struct snd_soc_dai_driver *dai_drv)
3743{ 3746{
3744 struct snd_soc_codec *codec; 3747 struct snd_soc_codec *codec;
@@ -3785,14 +3788,13 @@ int snd_soc_register_dai(struct device *dev,
3785 3788
3786 return 0; 3789 return 0;
3787} 3790}
3788EXPORT_SYMBOL_GPL(snd_soc_register_dai);
3789 3791
3790/** 3792/**
3791 * snd_soc_unregister_dai - Unregister a DAI from the ASoC core 3793 * snd_soc_unregister_dai - Unregister a DAI from the ASoC core
3792 * 3794 *
3793 * @dai: DAI to unregister 3795 * @dai: DAI to unregister
3794 */ 3796 */
3795void snd_soc_unregister_dai(struct device *dev) 3797static void snd_soc_unregister_dai(struct device *dev)
3796{ 3798{
3797 struct snd_soc_dai *dai; 3799 struct snd_soc_dai *dai;
3798 3800
@@ -3811,7 +3813,6 @@ found:
3811 kfree(dai->name); 3813 kfree(dai->name);
3812 kfree(dai); 3814 kfree(dai);
3813} 3815}
3814EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
3815 3816
3816/** 3817/**
3817 * snd_soc_register_dais - Register multiple DAIs with the ASoC core 3818 * snd_soc_register_dais - Register multiple DAIs with the ASoC core
@@ -3819,7 +3820,7 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
3819 * @dai: Array of DAIs to register 3820 * @dai: Array of DAIs to register
3820 * @count: Number of DAIs 3821 * @count: Number of DAIs
3821 */ 3822 */
3822int snd_soc_register_dais(struct device *dev, 3823static int snd_soc_register_dais(struct device *dev,
3823 struct snd_soc_dai_driver *dai_drv, size_t count) 3824 struct snd_soc_dai_driver *dai_drv, size_t count)
3824{ 3825{
3825 struct snd_soc_codec *codec; 3826 struct snd_soc_codec *codec;
@@ -3883,7 +3884,6 @@ err:
3883 3884
3884 return ret; 3885 return ret;
3885} 3886}
3886EXPORT_SYMBOL_GPL(snd_soc_register_dais);
3887 3887
3888/** 3888/**
3889 * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core 3889 * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core
@@ -3891,14 +3891,13 @@ EXPORT_SYMBOL_GPL(snd_soc_register_dais);
3891 * @dai: Array of DAIs to unregister 3891 * @dai: Array of DAIs to unregister
3892 * @count: Number of DAIs 3892 * @count: Number of DAIs
3893 */ 3893 */
3894void snd_soc_unregister_dais(struct device *dev, size_t count) 3894static void snd_soc_unregister_dais(struct device *dev, size_t count)
3895{ 3895{
3896 int i; 3896 int i;
3897 3897
3898 for (i = 0; i < count; i++) 3898 for (i = 0; i < count; i++)
3899 snd_soc_unregister_dai(dev); 3899 snd_soc_unregister_dai(dev);
3900} 3900}
3901EXPORT_SYMBOL_GPL(snd_soc_unregister_dais);
3902 3901
3903/** 3902/**
3904 * snd_soc_register_platform - Register a platform with the ASoC core 3903 * snd_soc_register_platform - Register a platform with the ASoC core
@@ -3906,7 +3905,7 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_dais);
3906 * @platform: platform to register 3905 * @platform: platform to register
3907 */ 3906 */
3908int snd_soc_register_platform(struct device *dev, 3907int snd_soc_register_platform(struct device *dev,
3909 struct snd_soc_platform_driver *platform_drv) 3908 const struct snd_soc_platform_driver *platform_drv)
3910{ 3909{
3911 struct snd_soc_platform *platform; 3910 struct snd_soc_platform *platform;
3912 3911
@@ -4022,8 +4021,8 @@ int snd_soc_register_codec(struct device *dev,
4022 /* create CODEC component name */ 4021 /* create CODEC component name */
4023 codec->name = fmt_single_name(dev, &codec->id); 4022 codec->name = fmt_single_name(dev, &codec->id);
4024 if (codec->name == NULL) { 4023 if (codec->name == NULL) {
4025 kfree(codec); 4024 ret = -ENOMEM;
4026 return -ENOMEM; 4025 goto fail_codec;
4027 } 4026 }
4028 4027
4029 if (codec_drv->compress_type) 4028 if (codec_drv->compress_type)
@@ -4062,7 +4061,7 @@ int snd_soc_register_codec(struct device *dev,
4062 reg_size, GFP_KERNEL); 4061 reg_size, GFP_KERNEL);
4063 if (!codec->reg_def_copy) { 4062 if (!codec->reg_def_copy) {
4064 ret = -ENOMEM; 4063 ret = -ENOMEM;
4065 goto fail; 4064 goto fail_codec_name;
4066 } 4065 }
4067 } 4066 }
4068 } 4067 }
@@ -4086,18 +4085,22 @@ int snd_soc_register_codec(struct device *dev,
4086 mutex_unlock(&client_mutex); 4085 mutex_unlock(&client_mutex);
4087 4086
4088 /* register any DAIs */ 4087 /* register any DAIs */
4089 if (num_dai) { 4088 ret = snd_soc_register_dais(dev, dai_drv, num_dai);
4090 ret = snd_soc_register_dais(dev, dai_drv, num_dai); 4089 if (ret < 0) {
4091 if (ret < 0) 4090 dev_err(codec->dev, "ASoC: Failed to regster DAIs: %d\n", ret);
4092 dev_err(codec->dev, "ASoC: Failed to regster" 4091 goto fail_codec_name;
4093 " DAIs: %d\n", ret);
4094 } 4092 }
4095 4093
4096 dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n", codec->name); 4094 dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n", codec->name);
4097 return 0; 4095 return 0;
4098 4096
4099fail: 4097fail_codec_name:
4098 mutex_lock(&client_mutex);
4099 list_del(&codec->list);
4100 mutex_unlock(&client_mutex);
4101
4100 kfree(codec->name); 4102 kfree(codec->name);
4103fail_codec:
4101 kfree(codec); 4104 kfree(codec);
4102 return ret; 4105 return ret;
4103} 4106}
@@ -4111,7 +4114,6 @@ EXPORT_SYMBOL_GPL(snd_soc_register_codec);
4111void snd_soc_unregister_codec(struct device *dev) 4114void snd_soc_unregister_codec(struct device *dev)
4112{ 4115{
4113 struct snd_soc_codec *codec; 4116 struct snd_soc_codec *codec;
4114 int i;
4115 4117
4116 list_for_each_entry(codec, &codec_list, list) { 4118 list_for_each_entry(codec, &codec_list, list) {
4117 if (dev == codec->dev) 4119 if (dev == codec->dev)
@@ -4120,9 +4122,7 @@ void snd_soc_unregister_codec(struct device *dev)
4120 return; 4122 return;
4121 4123
4122found: 4124found:
4123 if (codec->num_dai) 4125 snd_soc_unregister_dais(dev, codec->num_dai);
4124 for (i = 0; i < codec->num_dai; i++)
4125 snd_soc_unregister_dai(dev);
4126 4126
4127 mutex_lock(&client_mutex); 4127 mutex_lock(&client_mutex);
4128 list_del(&codec->list); 4128 list_del(&codec->list);
@@ -4137,6 +4137,92 @@ found:
4137} 4137}
4138EXPORT_SYMBOL_GPL(snd_soc_unregister_codec); 4138EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
4139 4139
4140
4141/**
4142 * snd_soc_register_component - Register a component with the ASoC core
4143 *
4144 */
4145int snd_soc_register_component(struct device *dev,
4146 const struct snd_soc_component_driver *cmpnt_drv,
4147 struct snd_soc_dai_driver *dai_drv,
4148 int num_dai)
4149{
4150 struct snd_soc_component *cmpnt;
4151 int ret;
4152
4153 dev_dbg(dev, "component register %s\n", dev_name(dev));
4154
4155 cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL);
4156 if (!cmpnt) {
4157 dev_err(dev, "ASoC: Failed to allocate memory\n");
4158 return -ENOMEM;
4159 }
4160
4161 cmpnt->name = fmt_single_name(dev, &cmpnt->id);
4162 if (!cmpnt->name) {
4163 dev_err(dev, "ASoC: Failed to simplifying name\n");
4164 return -ENOMEM;
4165 }
4166
4167 cmpnt->dev = dev;
4168 cmpnt->driver = cmpnt_drv;
4169 cmpnt->num_dai = num_dai;
4170
4171 /*
4172 * snd_soc_register_dai() uses fmt_single_name(), and
4173 * snd_soc_register_dais() uses fmt_multiple_name()
4174 * for dai->name which is used for name based matching
4175 */
4176 if (1 == num_dai)
4177 ret = snd_soc_register_dai(dev, dai_drv);
4178 else
4179 ret = snd_soc_register_dais(dev, dai_drv, num_dai);
4180 if (ret < 0) {
4181 dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
4182 goto error_component_name;
4183 }
4184
4185 mutex_lock(&client_mutex);
4186 list_add(&cmpnt->list, &component_list);
4187 mutex_unlock(&client_mutex);
4188
4189 dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name);
4190
4191 return ret;
4192
4193error_component_name:
4194 kfree(cmpnt->name);
4195
4196 return ret;
4197}
4198EXPORT_SYMBOL_GPL(snd_soc_register_component);
4199
4200/**
4201 * snd_soc_unregister_component - Unregister a component from the ASoC core
4202 *
4203 */
4204void snd_soc_unregister_component(struct device *dev)
4205{
4206 struct snd_soc_component *cmpnt;
4207
4208 list_for_each_entry(cmpnt, &component_list, list) {
4209 if (dev == cmpnt->dev)
4210 goto found;
4211 }
4212 return;
4213
4214found:
4215 snd_soc_unregister_dais(dev, cmpnt->num_dai);
4216
4217 mutex_lock(&client_mutex);
4218 list_del(&cmpnt->list);
4219 mutex_unlock(&client_mutex);
4220
4221 dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name);
4222 kfree(cmpnt->name);
4223}
4224EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
4225
4140/* Retrieve a card's name from device tree */ 4226/* Retrieve a card's name from device tree */
4141int snd_soc_of_parse_card_name(struct snd_soc_card *card, 4227int snd_soc_of_parse_card_name(struct snd_soc_card *card,
4142 const char *propname) 4228 const char *propname)
@@ -4197,7 +4283,6 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
4197 dev_err(card->dev, 4283 dev_err(card->dev,
4198 "ASoC: Property '%s' index %d could not be read: %d\n", 4284 "ASoC: Property '%s' index %d could not be read: %d\n",
4199 propname, 2 * i, ret); 4285 propname, 2 * i, ret);
4200 kfree(routes);
4201 return -EINVAL; 4286 return -EINVAL;
4202 } 4287 }
4203 ret = of_property_read_string_index(np, propname, 4288 ret = of_property_read_string_index(np, propname,
@@ -4206,7 +4291,6 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
4206 dev_err(card->dev, 4291 dev_err(card->dev,
4207 "ASoC: Property '%s' index %d could not be read: %d\n", 4292 "ASoC: Property '%s' index %d could not be read: %d\n",
4208 propname, (2 * i) + 1, ret); 4293 propname, (2 * i) + 1, ret);
4209 kfree(routes);
4210 return -EINVAL; 4294 return -EINVAL;
4211 } 4295 }
4212 } 4296 }
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1d6a9b3ceb27..21779a6a781a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -504,17 +504,27 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
504 return 0; 504 return 0;
505} 505}
506 506
507/* create new dapm mixer control */ 507/*
508static int dapm_new_mixer(struct snd_soc_dapm_widget *w) 508 * Determine if a kcontrol is shared. If it is, look it up. If it isn't,
509 * create it. Either way, add the widget into the control's widget list
510 */
511static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
512 int kci, struct snd_soc_dapm_path *path)
509{ 513{
510 struct snd_soc_dapm_context *dapm = w->dapm; 514 struct snd_soc_dapm_context *dapm = w->dapm;
511 int i, ret = 0;
512 size_t name_len, prefix_len;
513 struct snd_soc_dapm_path *path;
514 struct snd_card *card = dapm->card->snd_card; 515 struct snd_card *card = dapm->card->snd_card;
515 const char *prefix; 516 const char *prefix;
517 size_t prefix_len;
518 int shared;
519 struct snd_kcontrol *kcontrol;
516 struct snd_soc_dapm_widget_list *wlist; 520 struct snd_soc_dapm_widget_list *wlist;
521 int wlistentries;
517 size_t wlistsize; 522 size_t wlistsize;
523 bool wname_in_long_name, kcname_in_long_name;
524 size_t name_len;
525 char *long_name;
526 const char *name;
527 int ret;
518 528
519 if (dapm->codec) 529 if (dapm->codec)
520 prefix = dapm->codec->name_prefix; 530 prefix = dapm->codec->name_prefix;
@@ -526,103 +536,141 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
526 else 536 else
527 prefix_len = 0; 537 prefix_len = 0;
528 538
529 /* add kcontrol */ 539 shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci],
530 for (i = 0; i < w->num_kcontrols; i++) { 540 &kcontrol);
531 541
532 /* match name */ 542 if (kcontrol) {
533 list_for_each_entry(path, &w->sources, list_sink) { 543 wlist = kcontrol->private_data;
544 wlistentries = wlist->num_widgets + 1;
545 } else {
546 wlist = NULL;
547 wlistentries = 1;
548 }
534 549
535 /* mixer/mux paths name must match control name */ 550 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
536 if (path->name != (char *)w->kcontrol_news[i].name) 551 wlistentries * sizeof(struct snd_soc_dapm_widget *);
537 continue; 552 wlist = krealloc(wlist, wlistsize, GFP_KERNEL);
553 if (wlist == NULL) {
554 dev_err(dapm->dev, "ASoC: can't allocate widget list for %s\n",
555 w->name);
556 return -ENOMEM;
557 }
558 wlist->num_widgets = wlistentries;
559 wlist->widgets[wlistentries - 1] = w;
538 560
539 if (w->kcontrols[i]) { 561 if (!kcontrol) {
540 path->kcontrol = w->kcontrols[i]; 562 if (shared) {
541 continue; 563 wname_in_long_name = false;
564 kcname_in_long_name = true;
565 } else {
566 switch (w->id) {
567 case snd_soc_dapm_switch:
568 case snd_soc_dapm_mixer:
569 wname_in_long_name = true;
570 kcname_in_long_name = true;
571 break;
572 case snd_soc_dapm_mixer_named_ctl:
573 wname_in_long_name = false;
574 kcname_in_long_name = true;
575 break;
576 case snd_soc_dapm_mux:
577 case snd_soc_dapm_virt_mux:
578 case snd_soc_dapm_value_mux:
579 wname_in_long_name = true;
580 kcname_in_long_name = false;
581 break;
582 default:
583 kfree(wlist);
584 return -EINVAL;
542 } 585 }
586 }
587
588 if (wname_in_long_name && kcname_in_long_name) {
589 name_len = strlen(w->name) - prefix_len + 1 +
590 strlen(w->kcontrol_news[kci].name) + 1;
543 591
544 wlistsize = sizeof(struct snd_soc_dapm_widget_list) + 592 long_name = kmalloc(name_len, GFP_KERNEL);
545 sizeof(struct snd_soc_dapm_widget *), 593 if (long_name == NULL) {
546 wlist = kzalloc(wlistsize, GFP_KERNEL); 594 kfree(wlist);
547 if (wlist == NULL) {
548 dev_err(dapm->dev,
549 "ASoC: can't allocate widget list for %s\n",
550 w->name);
551 return -ENOMEM; 595 return -ENOMEM;
552 } 596 }
553 wlist->num_widgets = 1; 597
554 wlist->widgets[0] = w; 598 /*
555 599 * The control will get a prefix from the control
556 /* add dapm control with long name. 600 * creation process but we're also using the same
557 * for dapm_mixer this is the concatenation of the 601 * prefix for widgets so cut the prefix off the
558 * mixer and kcontrol name. 602 * front of the widget name.
559 * for dapm_mixer_named_ctl this is simply the
560 * kcontrol name.
561 */ 603 */
562 name_len = strlen(w->kcontrol_news[i].name) + 1; 604 snprintf(long_name, name_len, "%s %s",
563 if (w->id != snd_soc_dapm_mixer_named_ctl) 605 w->name + prefix_len,
564 name_len += 1 + strlen(w->name); 606 w->kcontrol_news[kci].name);
607 long_name[name_len - 1] = '\0';
608
609 name = long_name;
610 } else if (wname_in_long_name) {
611 long_name = NULL;
612 name = w->name + prefix_len;
613 } else {
614 long_name = NULL;
615 name = w->kcontrol_news[kci].name;
616 }
565 617
566 path->long_name = kmalloc(name_len, GFP_KERNEL); 618 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], wlist, name,
619 prefix);
620 ret = snd_ctl_add(card, kcontrol);
621 if (ret < 0) {
622 dev_err(dapm->dev,
623 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n",
624 w->name, name, ret);
625 kfree(wlist);
626 kfree(long_name);
627 return ret;
628 }
567 629
568 if (path->long_name == NULL) { 630 path->long_name = long_name;
569 kfree(wlist); 631 }
570 return -ENOMEM;
571 }
572 632
573 switch (w->id) { 633 kcontrol->private_data = wlist;
574 default: 634 w->kcontrols[kci] = kcontrol;
575 /* The control will get a prefix from 635 path->kcontrol = kcontrol;
576 * the control creation process but
577 * we're also using the same prefix
578 * for widgets so cut the prefix off
579 * the front of the widget name.
580 */
581 snprintf((char *)path->long_name, name_len,
582 "%s %s", w->name + prefix_len,
583 w->kcontrol_news[i].name);
584 break;
585 case snd_soc_dapm_mixer_named_ctl:
586 snprintf((char *)path->long_name, name_len,
587 "%s", w->kcontrol_news[i].name);
588 break;
589 }
590 636
591 ((char *)path->long_name)[name_len - 1] = '\0'; 637 return 0;
638}
592 639
593 path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i], 640/* create new dapm mixer control */
594 wlist, path->long_name, 641static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
595 prefix); 642{
596 ret = snd_ctl_add(card, path->kcontrol); 643 int i, ret;
597 if (ret < 0) { 644 struct snd_soc_dapm_path *path;
598 dev_err(dapm->dev, "ASoC: failed to add widget" 645
599 " %s dapm kcontrol %s: %d\n", 646 /* add kcontrol */
600 w->name, path->long_name, ret); 647 for (i = 0; i < w->num_kcontrols; i++) {
601 kfree(wlist); 648 /* match name */
602 kfree(path->long_name); 649 list_for_each_entry(path, &w->sources, list_sink) {
603 path->long_name = NULL; 650 /* mixer/mux paths name must match control name */
604 return ret; 651 if (path->name != (char *)w->kcontrol_news[i].name)
652 continue;
653
654 if (w->kcontrols[i]) {
655 path->kcontrol = w->kcontrols[i];
656 continue;
605 } 657 }
606 w->kcontrols[i] = path->kcontrol; 658
659 ret = dapm_create_or_share_mixmux_kcontrol(w, i, path);
660 if (ret < 0)
661 return ret;
607 } 662 }
608 } 663 }
609 return ret; 664
665 return 0;
610} 666}
611 667
612/* create new dapm mux control */ 668/* create new dapm mux control */
613static int dapm_new_mux(struct snd_soc_dapm_widget *w) 669static int dapm_new_mux(struct snd_soc_dapm_widget *w)
614{ 670{
615 struct snd_soc_dapm_context *dapm = w->dapm; 671 struct snd_soc_dapm_context *dapm = w->dapm;
616 struct snd_soc_dapm_path *path = NULL; 672 struct snd_soc_dapm_path *path;
617 struct snd_kcontrol *kcontrol;
618 struct snd_card *card = dapm->card->snd_card;
619 const char *prefix;
620 size_t prefix_len;
621 int ret; 673 int ret;
622 struct snd_soc_dapm_widget_list *wlist;
623 int shared, wlistentries;
624 size_t wlistsize;
625 const char *name;
626 674
627 if (w->num_kcontrols != 1) { 675 if (w->num_kcontrols != 1) {
628 dev_err(dapm->dev, 676 dev_err(dapm->dev,
@@ -631,65 +679,19 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
631 return -EINVAL; 679 return -EINVAL;
632 } 680 }
633 681
634 shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[0], 682 path = list_first_entry(&w->sources, struct snd_soc_dapm_path,
635 &kcontrol); 683 list_sink);
636 if (kcontrol) { 684 if (!path) {
637 wlist = kcontrol->private_data; 685 dev_err(dapm->dev, "ASoC: mux %s has no paths\n", w->name);
638 wlistentries = wlist->num_widgets + 1; 686 return -EINVAL;
639 } else {
640 wlist = NULL;
641 wlistentries = 1;
642 }
643 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
644 wlistentries * sizeof(struct snd_soc_dapm_widget *),
645 wlist = krealloc(wlist, wlistsize, GFP_KERNEL);
646 if (wlist == NULL) {
647 dev_err(dapm->dev,
648 "ASoC: can't allocate widget list for %s\n", w->name);
649 return -ENOMEM;
650 }
651 wlist->num_widgets = wlistentries;
652 wlist->widgets[wlistentries - 1] = w;
653
654 if (!kcontrol) {
655 if (dapm->codec)
656 prefix = dapm->codec->name_prefix;
657 else
658 prefix = NULL;
659
660 if (shared) {
661 name = w->kcontrol_news[0].name;
662 prefix_len = 0;
663 } else {
664 name = w->name;
665 if (prefix)
666 prefix_len = strlen(prefix) + 1;
667 else
668 prefix_len = 0;
669 }
670
671 /*
672 * The control will get a prefix from the control creation
673 * process but we're also using the same prefix for widgets so
674 * cut the prefix off the front of the widget name.
675 */
676 kcontrol = snd_soc_cnew(&w->kcontrol_news[0], wlist,
677 name + prefix_len, prefix);
678 ret = snd_ctl_add(card, kcontrol);
679 if (ret < 0) {
680 dev_err(dapm->dev, "ASoC: failed to add kcontrol %s: %d\n",
681 w->name, ret);
682 kfree(wlist);
683 return ret;
684 }
685 } 687 }
686 688
687 kcontrol->private_data = wlist; 689 ret = dapm_create_or_share_mixmux_kcontrol(w, 0, path);
688 690 if (ret < 0)
689 w->kcontrols[0] = kcontrol; 691 return ret;
690 692
691 list_for_each_entry(path, &w->sources, list_sink) 693 list_for_each_entry(path, &w->sources, list_sink)
692 path->kcontrol = kcontrol; 694 path->kcontrol = w->kcontrols[0];
693 695
694 return 0; 696 return 0;
695} 697}
@@ -705,14 +707,33 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w)
705} 707}
706 708
707/* reset 'walked' bit for each dapm path */ 709/* reset 'walked' bit for each dapm path */
708static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm) 710static void dapm_clear_walk_output(struct snd_soc_dapm_context *dapm,
711 struct list_head *sink)
709{ 712{
710 struct snd_soc_dapm_path *p; 713 struct snd_soc_dapm_path *p;
711 714
712 list_for_each_entry(p, &dapm->card->paths, list) 715 list_for_each_entry(p, sink, list_source) {
713 p->walked = 0; 716 if (p->walked) {
717 p->walked = 0;
718 dapm_clear_walk_output(dapm, &p->sink->sinks);
719 }
720 }
721}
722
723static void dapm_clear_walk_input(struct snd_soc_dapm_context *dapm,
724 struct list_head *source)
725{
726 struct snd_soc_dapm_path *p;
727
728 list_for_each_entry(p, source, list_sink) {
729 if (p->walked) {
730 p->walked = 0;
731 dapm_clear_walk_input(dapm, &p->source->sources);
732 }
733 }
714} 734}
715 735
736
716/* We implement power down on suspend by checking the power state of 737/* We implement power down on suspend by checking the power state of
717 * the ALSA card - when we are suspending the ALSA state for the card 738 * the ALSA card - when we are suspending the ALSA state for the card
718 * is set to D3. 739 * is set to D3.
@@ -831,6 +852,9 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
831 if (path->weak) 852 if (path->weak)
832 continue; 853 continue;
833 854
855 if (path->walking)
856 return 1;
857
834 if (path->walked) 858 if (path->walked)
835 continue; 859 continue;
836 860
@@ -838,6 +862,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
838 862
839 if (path->sink && path->connect) { 863 if (path->sink && path->connect) {
840 path->walked = 1; 864 path->walked = 1;
865 path->walking = 1;
841 866
842 /* do we need to add this widget to the list ? */ 867 /* do we need to add this widget to the list ? */
843 if (list) { 868 if (list) {
@@ -847,11 +872,14 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
847 dev_err(widget->dapm->dev, 872 dev_err(widget->dapm->dev,
848 "ASoC: could not add widget %s\n", 873 "ASoC: could not add widget %s\n",
849 widget->name); 874 widget->name);
875 path->walking = 0;
850 return con; 876 return con;
851 } 877 }
852 } 878 }
853 879
854 con += is_connected_output_ep(path->sink, list); 880 con += is_connected_output_ep(path->sink, list);
881
882 path->walking = 0;
855 } 883 }
856 } 884 }
857 885
@@ -931,6 +959,9 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
931 if (path->weak) 959 if (path->weak)
932 continue; 960 continue;
933 961
962 if (path->walking)
963 return 1;
964
934 if (path->walked) 965 if (path->walked)
935 continue; 966 continue;
936 967
@@ -938,6 +969,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
938 969
939 if (path->source && path->connect) { 970 if (path->source && path->connect) {
940 path->walked = 1; 971 path->walked = 1;
972 path->walking = 1;
941 973
942 /* do we need to add this widget to the list ? */ 974 /* do we need to add this widget to the list ? */
943 if (list) { 975 if (list) {
@@ -947,11 +979,14 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
947 dev_err(widget->dapm->dev, 979 dev_err(widget->dapm->dev,
948 "ASoC: could not add widget %s\n", 980 "ASoC: could not add widget %s\n",
949 widget->name); 981 widget->name);
982 path->walking = 0;
950 return con; 983 return con;
951 } 984 }
952 } 985 }
953 986
954 con += is_connected_input_ep(path->source, list); 987 con += is_connected_input_ep(path->source, list);
988
989 path->walking = 0;
955 } 990 }
956 } 991 }
957 992
@@ -981,13 +1016,17 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
981 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 1016 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
982 dapm_reset(card); 1017 dapm_reset(card);
983 1018
984 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1019 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
985 paths = is_connected_output_ep(dai->playback_widget, list); 1020 paths = is_connected_output_ep(dai->playback_widget, list);
986 else 1021 dapm_clear_walk_output(&card->dapm,
1022 &dai->playback_widget->sinks);
1023 } else {
987 paths = is_connected_input_ep(dai->capture_widget, list); 1024 paths = is_connected_input_ep(dai->capture_widget, list);
1025 dapm_clear_walk_input(&card->dapm,
1026 &dai->capture_widget->sources);
1027 }
988 1028
989 trace_snd_soc_dapm_connected(paths, stream); 1029 trace_snd_soc_dapm_connected(paths, stream);
990 dapm_clear_walk(&card->dapm);
991 mutex_unlock(&card->dapm_mutex); 1030 mutex_unlock(&card->dapm_mutex);
992 1031
993 return paths; 1032 return paths;
@@ -1090,9 +1129,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
1090 DAPM_UPDATE_STAT(w, power_checks); 1129 DAPM_UPDATE_STAT(w, power_checks);
1091 1130
1092 in = is_connected_input_ep(w, NULL); 1131 in = is_connected_input_ep(w, NULL);
1093 dapm_clear_walk(w->dapm); 1132 dapm_clear_walk_input(w->dapm, &w->sources);
1094 out = is_connected_output_ep(w, NULL); 1133 out = is_connected_output_ep(w, NULL);
1095 dapm_clear_walk(w->dapm); 1134 dapm_clear_walk_output(w->dapm, &w->sinks);
1096 return out != 0 && in != 0; 1135 return out != 0 && in != 0;
1097} 1136}
1098 1137
@@ -1115,7 +1154,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
1115 1154
1116 if (w->active) { 1155 if (w->active) {
1117 in = is_connected_input_ep(w, NULL); 1156 in = is_connected_input_ep(w, NULL);
1118 dapm_clear_walk(w->dapm); 1157 dapm_clear_walk_input(w->dapm, &w->sources);
1119 return in != 0; 1158 return in != 0;
1120 } else { 1159 } else {
1121 return dapm_generic_check_power(w); 1160 return dapm_generic_check_power(w);
@@ -1131,7 +1170,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
1131 1170
1132 if (w->active) { 1171 if (w->active) {
1133 out = is_connected_output_ep(w, NULL); 1172 out = is_connected_output_ep(w, NULL);
1134 dapm_clear_walk(w->dapm); 1173 dapm_clear_walk_output(w->dapm, &w->sinks);
1135 return out != 0; 1174 return out != 0;
1136 } else { 1175 } else {
1137 return dapm_generic_check_power(w); 1176 return dapm_generic_check_power(w);
@@ -1163,8 +1202,6 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
1163 return 1; 1202 return 1;
1164 } 1203 }
1165 1204
1166 dapm_clear_walk(w->dapm);
1167
1168 return 0; 1205 return 0;
1169} 1206}
1170 1207
@@ -1745,9 +1782,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1745 return -ENOMEM; 1782 return -ENOMEM;
1746 1783
1747 in = is_connected_input_ep(w, NULL); 1784 in = is_connected_input_ep(w, NULL);
1748 dapm_clear_walk(w->dapm); 1785 dapm_clear_walk_input(w->dapm, &w->sources);
1749 out = is_connected_output_ep(w, NULL); 1786 out = is_connected_output_ep(w, NULL);
1750 dapm_clear_walk(w->dapm); 1787 dapm_clear_walk_output(w->dapm, &w->sinks);
1751 1788
1752 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", 1789 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
1753 w->name, w->power ? "On" : "Off", 1790 w->name, w->power ? "On" : "Off",
@@ -3123,7 +3160,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3123 break; 3160 break;
3124 } 3161 }
3125 3162
3126 dapm->n_widgets++;
3127 w->dapm = dapm; 3163 w->dapm = dapm;
3128 w->codec = dapm->codec; 3164 w->codec = dapm->codec;
3129 w->platform = dapm->platform; 3165 w->platform = dapm->platform;
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
index 111b7d921e89..a9a300acb506 100644
--- a/sound/soc/soc-dmaengine-pcm.c
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -33,8 +33,6 @@ struct dmaengine_pcm_runtime_data {
33 dma_cookie_t cookie; 33 dma_cookie_t cookie;
34 34
35 unsigned int pos; 35 unsigned int pos;
36
37 void *data;
38}; 36};
39 37
40static inline struct dmaengine_pcm_runtime_data *substream_to_prtd( 38static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
@@ -43,33 +41,6 @@ static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
43 return substream->runtime->private_data; 41 return substream->runtime->private_data;
44} 42}
45 43
46/**
47 * snd_dmaengine_pcm_set_data - Set dmaengine substream private data
48 * @substream: PCM substream
49 * @data: Data to set
50 */
51void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data)
52{
53 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
54
55 prtd->data = data;
56}
57EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_data);
58
59/**
60 * snd_dmaengine_pcm_get_data - Get dmaeinge substream private data
61 * @substream: PCM substream
62 *
63 * Returns the data previously set with snd_dmaengine_pcm_set_data
64 */
65void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream)
66{
67 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
68
69 return prtd->data;
70}
71EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_data);
72
73struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) 44struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
74{ 45{
75 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); 46 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
@@ -118,10 +89,49 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
118 slave_config->src_addr_width = buswidth; 89 slave_config->src_addr_width = buswidth;
119 } 90 }
120 91
92 slave_config->device_fc = false;
93
121 return 0; 94 return 0;
122} 95}
123EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); 96EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config);
124 97
98/**
99 * snd_dmaengine_pcm_set_config_from_dai_data() - Initializes a dma slave config
100 * using DAI DMA data.
101 * @substream: PCM substream
102 * @dma_data: DAI DMA data
103 * @slave_config: DMA slave configuration
104 *
105 * Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width and
106 * slave_id fields of the DMA slave config from the same fields of the DAI DMA
107 * data struct. The src and dst fields will be initialized depending on the
108 * direction of the substream. If the substream is a playback stream the dst
109 * fields will be initialized, if it is a capture stream the src fields will be
110 * initialized. The {dst,src}_addr_width field will only be initialized if the
111 * addr_width field of the DAI DMA data struct is not equal to
112 * DMA_SLAVE_BUSWIDTH_UNDEFINED.
113 */
114void snd_dmaengine_pcm_set_config_from_dai_data(
115 const struct snd_pcm_substream *substream,
116 const struct snd_dmaengine_dai_dma_data *dma_data,
117 struct dma_slave_config *slave_config)
118{
119 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
120 slave_config->dst_addr = dma_data->addr;
121 slave_config->dst_maxburst = dma_data->maxburst;
122 if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
123 slave_config->dst_addr_width = dma_data->addr_width;
124 } else {
125 slave_config->src_addr = dma_data->addr;
126 slave_config->src_maxburst = dma_data->maxburst;
127 if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
128 slave_config->src_addr_width = dma_data->addr_width;
129 }
130
131 slave_config->slave_id = dma_data->slave_id;
132}
133EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);
134
125static void dmaengine_pcm_dma_complete(void *arg) 135static void dmaengine_pcm_dma_complete(void *arg)
126{ 136{
127 struct snd_pcm_substream *substream = arg; 137 struct snd_pcm_substream *substream = arg;
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 29183ef2b93d..8ca9ecc5ac57 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -158,10 +158,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
158 return -EINVAL; 158 return -EINVAL;
159 } 159 }
160 160
161 if (IS_ERR(codec->control_data)) 161 return PTR_RET(codec->control_data);
162 return PTR_ERR(codec->control_data);
163
164 return 0;
165} 162}
166EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); 163EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
167#else 164#else
diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c
index c7c4b20395bb..14d57e89bcba 100644
--- a/sound/soc/spear/spdif_in.c
+++ b/sound/soc/spear/spdif_in.c
@@ -170,6 +170,10 @@ struct snd_soc_dai_driver spdif_in_dai = {
170 .ops = &spdif_in_dai_ops, 170 .ops = &spdif_in_dai_ops,
171}; 171};
172 172
173static const struct snd_soc_component_driver spdif_in_component = {
174 .name = "spdif-in",
175};
176
173static irqreturn_t spdif_in_irq(int irq, void *arg) 177static irqreturn_t spdif_in_irq(int irq, void *arg)
174{ 178{
175 struct spdif_in_dev *host = (struct spdif_in_dev *)arg; 179 struct spdif_in_dev *host = (struct spdif_in_dev *)arg;
@@ -258,7 +262,8 @@ static int spdif_in_probe(struct platform_device *pdev)
258 return ret; 262 return ret;
259 } 263 }
260 264
261 ret = snd_soc_register_dai(&pdev->dev, &spdif_in_dai); 265 ret = snd_soc_register_component(&pdev->dev, &spdif_in_component,
266 &spdif_in_dai, 1);
262 if (ret != 0) { 267 if (ret != 0) {
263 clk_put(host->clk); 268 clk_put(host->clk);
264 return ret; 269 return ret;
@@ -271,7 +276,7 @@ static int spdif_in_remove(struct platform_device *pdev)
271{ 276{
272 struct spdif_in_dev *host = dev_get_drvdata(&pdev->dev); 277 struct spdif_in_dev *host = dev_get_drvdata(&pdev->dev);
273 278
274 snd_soc_unregister_dai(&pdev->dev); 279 snd_soc_unregister_component(&pdev->dev);
275 dev_set_drvdata(&pdev->dev, NULL); 280 dev_set_drvdata(&pdev->dev, NULL);
276 281
277 clk_put(host->clk); 282 clk_put(host->clk);
diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c
index 5eac4cda2fd7..1e3c3dda3598 100644
--- a/sound/soc/spear/spdif_out.c
+++ b/sound/soc/spear/spdif_out.c
@@ -270,6 +270,10 @@ static struct snd_soc_dai_driver spdif_out_dai = {
270 .ops = &spdif_out_dai_ops, 270 .ops = &spdif_out_dai_ops,
271}; 271};
272 272
273static const struct snd_soc_component_driver spdif_out_component = {
274 .name = "spdif-out",
275};
276
273static int spdif_out_probe(struct platform_device *pdev) 277static int spdif_out_probe(struct platform_device *pdev)
274{ 278{
275 struct spdif_out_dev *host; 279 struct spdif_out_dev *host;
@@ -314,7 +318,8 @@ static int spdif_out_probe(struct platform_device *pdev)
314 318
315 dev_set_drvdata(&pdev->dev, host); 319 dev_set_drvdata(&pdev->dev, host);
316 320
317 ret = snd_soc_register_dai(&pdev->dev, &spdif_out_dai); 321 ret = snd_soc_register_component(&pdev->dev, &spdif_out_component,
322 &spdif_out_dai, 1);
318 if (ret != 0) { 323 if (ret != 0) {
319 clk_put(host->clk); 324 clk_put(host->clk);
320 return ret; 325 return ret;
@@ -327,7 +332,7 @@ static int spdif_out_remove(struct platform_device *pdev)
327{ 332{
328 struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev); 333 struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev);
329 334
330 snd_soc_unregister_dai(&pdev->dev); 335 snd_soc_unregister_component(&pdev->dev);
331 dev_set_drvdata(&pdev->dev, NULL); 336 dev_set_drvdata(&pdev->dev, NULL);
332 337
333 clk_put(host->clk); 338 clk_put(host->clk);
diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c
index 69803919b838..bfbcc1fcfe6f 100644
--- a/sound/soc/spear/spear_pcm.c
+++ b/sound/soc/spear/spear_pcm.c
@@ -64,21 +64,7 @@ static int spear_pcm_open(struct snd_pcm_substream *substream)
64 if (ret) 64 if (ret)
65 return ret; 65 return ret;
66 66
67 ret = snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data); 67 return snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data)
68 if (ret)
69 return ret;
70
71 snd_dmaengine_pcm_set_data(substream, dma_data);
72
73 return 0;
74}
75
76static int spear_pcm_close(struct snd_pcm_substream *substream)
77{
78
79 snd_dmaengine_pcm_close(substream);
80
81 return 0;
82} 68}
83 69
84static int spear_pcm_mmap(struct snd_pcm_substream *substream, 70static int spear_pcm_mmap(struct snd_pcm_substream *substream,
@@ -93,7 +79,7 @@ static int spear_pcm_mmap(struct snd_pcm_substream *substream,
93 79
94static struct snd_pcm_ops spear_pcm_ops = { 80static struct snd_pcm_ops spear_pcm_ops = {
95 .open = spear_pcm_open, 81 .open = spear_pcm_open,
96 .close = spear_pcm_close, 82 .close = snd_dmaengine_pcm_close,
97 .ioctl = snd_pcm_lib_ioctl, 83 .ioctl = snd_pcm_lib_ioctl,
98 .hw_params = spear_pcm_hw_params, 84 .hw_params = spear_pcm_hw_params,
99 .hw_free = spear_pcm_hw_free, 85 .hw_free = spear_pcm_hw_free,
@@ -149,9 +135,9 @@ static void spear_pcm_free(struct snd_pcm *pcm)
149 135
150static u64 spear_pcm_dmamask = DMA_BIT_MASK(32); 136static u64 spear_pcm_dmamask = DMA_BIT_MASK(32);
151 137
152static int spear_pcm_new(struct snd_card *card, 138static int spear_pcm_new(struct snd_soc_pcm_runtime *rtd)
153 struct snd_soc_dai *dai, struct snd_pcm *pcm)
154{ 139{
140 struct snd_card *card = rtd->card->snd_card;
155 int ret; 141 int ret;
156 142
157 if (!card->dev->dma_mask) 143 if (!card->dev->dma_mask)
@@ -159,16 +145,16 @@ static int spear_pcm_new(struct snd_card *card,
159 if (!card->dev->coherent_dma_mask) 145 if (!card->dev->coherent_dma_mask)
160 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 146 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
161 147
162 if (dai->driver->playback.channels_min) { 148 if (rtd->cpu_dai->driver->playback.channels_min) {
163 ret = spear_pcm_preallocate_dma_buffer(pcm, 149 ret = spear_pcm_preallocate_dma_buffer(rtd->pcm,
164 SNDRV_PCM_STREAM_PLAYBACK, 150 SNDRV_PCM_STREAM_PLAYBACK,
165 spear_pcm_hardware.buffer_bytes_max); 151 spear_pcm_hardware.buffer_bytes_max);
166 if (ret) 152 if (ret)
167 return ret; 153 return ret;
168 } 154 }
169 155
170 if (dai->driver->capture.channels_min) { 156 if (rtd->cpu_dai->driver->capture.channels_min) {
171 ret = spear_pcm_preallocate_dma_buffer(pcm, 157 ret = spear_pcm_preallocate_dma_buffer(rtd->pcm,
172 SNDRV_PCM_STREAM_CAPTURE, 158 SNDRV_PCM_STREAM_CAPTURE,
173 spear_pcm_hardware.buffer_bytes_max); 159 spear_pcm_hardware.buffer_bytes_max);
174 if (ret) 160 if (ret)
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index 336dcdd3e8a4..2f70ea7f6618 100644
--- a/sound/soc/tegra/tegra20_ac97.c
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -35,6 +35,7 @@
35#include <sound/pcm.h> 35#include <sound/pcm.h>
36#include <sound/pcm_params.h> 36#include <sound/pcm_params.h>
37#include <sound/soc.h> 37#include <sound/soc.h>
38#include <sound/dmaengine_pcm.h>
38 39
39#include "tegra_asoc_utils.h" 40#include "tegra_asoc_utils.h"
40#include "tegra20_ac97.h" 41#include "tegra20_ac97.h"
@@ -248,6 +249,10 @@ static struct snd_soc_dai_driver tegra20_ac97_dai = {
248 .ops = &tegra20_ac97_dai_ops, 249 .ops = &tegra20_ac97_dai_ops,
249}; 250};
250 251
252static const struct snd_soc_component_driver tegra20_ac97_component = {
253 .name = DRV_NAME,
254};
255
251static bool tegra20_ac97_wr_rd_reg(struct device *dev, unsigned int reg) 256static bool tegra20_ac97_wr_rd_reg(struct device *dev, unsigned int reg)
252{ 257{
253 switch (reg) { 258 switch (reg) {
@@ -389,16 +394,17 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
389 } 394 }
390 395
391 ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1; 396 ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1;
392 ac97->capture_dma_data.wrap = 4; 397 ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
393 ac97->capture_dma_data.width = 32; 398 ac97->capture_dma_data.maxburst = 4;
394 ac97->capture_dma_data.req_sel = of_dma[1]; 399 ac97->capture_dma_data.slave_id = of_dma[1];
395 400
396 ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1; 401 ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1;
397 ac97->playback_dma_data.wrap = 4; 402 ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
398 ac97->playback_dma_data.width = 32; 403 ac97->capture_dma_data.maxburst = 4;
399 ac97->playback_dma_data.req_sel = of_dma[1]; 404 ac97->capture_dma_data.slave_id = of_dma[0];
400 405
401 ret = snd_soc_register_dais(&pdev->dev, &tegra20_ac97_dai, 1); 406 ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component,
407 &tegra20_ac97_dai, 1);
402 if (ret) { 408 if (ret) {
403 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); 409 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
404 ret = -ENOMEM; 410 ret = -ENOMEM;
@@ -408,7 +414,7 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
408 ret = tegra_pcm_platform_register(&pdev->dev); 414 ret = tegra_pcm_platform_register(&pdev->dev);
409 if (ret) { 415 if (ret) {
410 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); 416 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
411 goto err_unregister_dai; 417 goto err_unregister_component;
412 } 418 }
413 419
414 ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev); 420 ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev);
@@ -434,8 +440,8 @@ err_asoc_utils_fini:
434 tegra_asoc_utils_fini(&ac97->util_data); 440 tegra_asoc_utils_fini(&ac97->util_data);
435err_unregister_pcm: 441err_unregister_pcm:
436 tegra_pcm_platform_unregister(&pdev->dev); 442 tegra_pcm_platform_unregister(&pdev->dev);
437err_unregister_dai: 443err_unregister_component:
438 snd_soc_unregister_dai(&pdev->dev); 444 snd_soc_unregister_component(&pdev->dev);
439err_clk_put: 445err_clk_put:
440 clk_put(ac97->clk_ac97); 446 clk_put(ac97->clk_ac97);
441err: 447err:
@@ -447,7 +453,7 @@ static int tegra20_ac97_platform_remove(struct platform_device *pdev)
447 struct tegra20_ac97 *ac97 = dev_get_drvdata(&pdev->dev); 453 struct tegra20_ac97 *ac97 = dev_get_drvdata(&pdev->dev);
448 454
449 tegra_pcm_platform_unregister(&pdev->dev); 455 tegra_pcm_platform_unregister(&pdev->dev);
450 snd_soc_unregister_dai(&pdev->dev); 456 snd_soc_unregister_component(&pdev->dev);
451 457
452 tegra_asoc_utils_fini(&ac97->util_data); 458 tegra_asoc_utils_fini(&ac97->util_data);
453 459
diff --git a/sound/soc/tegra/tegra20_ac97.h b/sound/soc/tegra/tegra20_ac97.h
index dddc6828004e..4acb3aaba29b 100644
--- a/sound/soc/tegra/tegra20_ac97.h
+++ b/sound/soc/tegra/tegra20_ac97.h
@@ -85,8 +85,8 @@
85 85
86struct tegra20_ac97 { 86struct tegra20_ac97 {
87 struct clk *clk_ac97; 87 struct clk *clk_ac97;
88 struct tegra_pcm_dma_params capture_dma_data; 88 struct snd_dmaengine_dai_dma_data capture_dma_data;
89 struct tegra_pcm_dma_params playback_dma_data; 89 struct snd_dmaengine_dai_dma_data playback_dma_data;
90 struct regmap *regmap; 90 struct regmap *regmap;
91 int reset_gpio; 91 int reset_gpio;
92 int sync_gpio; 92 int sync_gpio;
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index caa772de5a18..52af7f6fb37f 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -41,6 +41,7 @@
41#include <sound/pcm.h> 41#include <sound/pcm.h>
42#include <sound/pcm_params.h> 42#include <sound/pcm_params.h>
43#include <sound/soc.h> 43#include <sound/soc.h>
44#include <sound/dmaengine_pcm.h>
44 45
45#include "tegra20_i2s.h" 46#include "tegra20_i2s.h"
46 47
@@ -276,6 +277,10 @@ static const struct snd_soc_dai_driver tegra20_i2s_dai_template = {
276 .symmetric_rates = 1, 277 .symmetric_rates = 1,
277}; 278};
278 279
280static const struct snd_soc_component_driver tegra20_i2s_component = {
281 .name = DRV_NAME,
282};
283
279static bool tegra20_i2s_wr_rd_reg(struct device *dev, unsigned int reg) 284static bool tegra20_i2s_wr_rd_reg(struct device *dev, unsigned int reg)
280{ 285{
281 switch (reg) { 286 switch (reg) {
@@ -403,14 +408,14 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
403 } 408 }
404 409
405 i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2; 410 i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2;
406 i2s->capture_dma_data.wrap = 4; 411 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
407 i2s->capture_dma_data.width = 32; 412 i2s->capture_dma_data.maxburst = 4;
408 i2s->capture_dma_data.req_sel = dma_ch; 413 i2s->capture_dma_data.slave_id = dma_ch;
409 414
410 i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1; 415 i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1;
411 i2s->playback_dma_data.wrap = 4; 416 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
412 i2s->playback_dma_data.width = 32; 417 i2s->playback_dma_data.maxburst = 4;
413 i2s->playback_dma_data.req_sel = dma_ch; 418 i2s->playback_dma_data.slave_id = dma_ch;
414 419
415 pm_runtime_enable(&pdev->dev); 420 pm_runtime_enable(&pdev->dev);
416 if (!pm_runtime_enabled(&pdev->dev)) { 421 if (!pm_runtime_enabled(&pdev->dev)) {
@@ -419,7 +424,8 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
419 goto err_pm_disable; 424 goto err_pm_disable;
420 } 425 }
421 426
422 ret = snd_soc_register_dai(&pdev->dev, &i2s->dai); 427 ret = snd_soc_register_component(&pdev->dev, &tegra20_i2s_component,
428 &i2s->dai, 1);
423 if (ret) { 429 if (ret) {
424 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); 430 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
425 ret = -ENOMEM; 431 ret = -ENOMEM;
@@ -429,13 +435,13 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
429 ret = tegra_pcm_platform_register(&pdev->dev); 435 ret = tegra_pcm_platform_register(&pdev->dev);
430 if (ret) { 436 if (ret) {
431 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); 437 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
432 goto err_unregister_dai; 438 goto err_unregister_component;
433 } 439 }
434 440
435 return 0; 441 return 0;
436 442
437err_unregister_dai: 443err_unregister_component:
438 snd_soc_unregister_dai(&pdev->dev); 444 snd_soc_unregister_component(&pdev->dev);
439err_suspend: 445err_suspend:
440 if (!pm_runtime_status_suspended(&pdev->dev)) 446 if (!pm_runtime_status_suspended(&pdev->dev))
441 tegra20_i2s_runtime_suspend(&pdev->dev); 447 tegra20_i2s_runtime_suspend(&pdev->dev);
@@ -456,7 +462,7 @@ static int tegra20_i2s_platform_remove(struct platform_device *pdev)
456 tegra20_i2s_runtime_suspend(&pdev->dev); 462 tegra20_i2s_runtime_suspend(&pdev->dev);
457 463
458 tegra_pcm_platform_unregister(&pdev->dev); 464 tegra_pcm_platform_unregister(&pdev->dev);
459 snd_soc_unregister_dai(&pdev->dev); 465 snd_soc_unregister_component(&pdev->dev);
460 466
461 clk_put(i2s->clk_i2s); 467 clk_put(i2s->clk_i2s);
462 468
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h
index 729958713cd4..fa6c29cc12b9 100644
--- a/sound/soc/tegra/tegra20_i2s.h
+++ b/sound/soc/tegra/tegra20_i2s.h
@@ -155,8 +155,8 @@
155struct tegra20_i2s { 155struct tegra20_i2s {
156 struct snd_soc_dai_driver dai; 156 struct snd_soc_dai_driver dai;
157 struct clk *clk_i2s; 157 struct clk *clk_i2s;
158 struct tegra_pcm_dma_params capture_dma_data; 158 struct snd_dmaengine_dai_dma_data capture_dma_data;
159 struct tegra_pcm_dma_params playback_dma_data; 159 struct snd_dmaengine_dai_dma_data playback_dma_data;
160 struct regmap *regmap; 160 struct regmap *regmap;
161}; 161};
162 162
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index 04771d14d343..5eaa12cdc6eb 100644
--- a/sound/soc/tegra/tegra20_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -32,6 +32,7 @@
32#include <sound/pcm.h> 32#include <sound/pcm.h>
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/dmaengine_pcm.h>
35 36
36#include "tegra20_spdif.h" 37#include "tegra20_spdif.h"
37 38
@@ -182,6 +183,10 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = {
182 .ops = &tegra20_spdif_dai_ops, 183 .ops = &tegra20_spdif_dai_ops,
183}; 184};
184 185
186static const struct snd_soc_component_driver tegra20_spdif_component = {
187 .name = DRV_NAME,
188};
189
185static bool tegra20_spdif_wr_rd_reg(struct device *dev, unsigned int reg) 190static bool tegra20_spdif_wr_rd_reg(struct device *dev, unsigned int reg)
186{ 191{
187 switch (reg) { 192 switch (reg) {
@@ -318,9 +323,9 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev)
318 } 323 }
319 324
320 spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT; 325 spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT;
321 spdif->playback_dma_data.wrap = 4; 326 spdif->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
322 spdif->playback_dma_data.width = 32; 327 spdif->capture_dma_data.maxburst = 4;
323 spdif->playback_dma_data.req_sel = dmareq->start; 328 spdif->playback_dma_data.slave_id = dmareq->start;
324 329
325 pm_runtime_enable(&pdev->dev); 330 pm_runtime_enable(&pdev->dev);
326 if (!pm_runtime_enabled(&pdev->dev)) { 331 if (!pm_runtime_enabled(&pdev->dev)) {
@@ -329,7 +334,8 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev)
329 goto err_pm_disable; 334 goto err_pm_disable;
330 } 335 }
331 336
332 ret = snd_soc_register_dai(&pdev->dev, &tegra20_spdif_dai); 337 ret = snd_soc_register_component(&pdev->dev, &tegra20_spdif_component,
338 &tegra20_spdif_dai, 1);
333 if (ret) { 339 if (ret) {
334 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); 340 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
335 ret = -ENOMEM; 341 ret = -ENOMEM;
@@ -339,13 +345,13 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev)
339 ret = tegra_pcm_platform_register(&pdev->dev); 345 ret = tegra_pcm_platform_register(&pdev->dev);
340 if (ret) { 346 if (ret) {
341 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); 347 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
342 goto err_unregister_dai; 348 goto err_unregister_component;
343 } 349 }
344 350
345 return 0; 351 return 0;
346 352
347err_unregister_dai: 353err_unregister_component:
348 snd_soc_unregister_dai(&pdev->dev); 354 snd_soc_unregister_component(&pdev->dev);
349err_suspend: 355err_suspend:
350 if (!pm_runtime_status_suspended(&pdev->dev)) 356 if (!pm_runtime_status_suspended(&pdev->dev))
351 tegra20_spdif_runtime_suspend(&pdev->dev); 357 tegra20_spdif_runtime_suspend(&pdev->dev);
@@ -366,7 +372,7 @@ static int tegra20_spdif_platform_remove(struct platform_device *pdev)
366 tegra20_spdif_runtime_suspend(&pdev->dev); 372 tegra20_spdif_runtime_suspend(&pdev->dev);
367 373
368 tegra_pcm_platform_unregister(&pdev->dev); 374 tegra_pcm_platform_unregister(&pdev->dev);
369 snd_soc_unregister_dai(&pdev->dev); 375 snd_soc_unregister_component(&pdev->dev);
370 376
371 clk_put(spdif->clk_spdif_out); 377 clk_put(spdif->clk_spdif_out);
372 378
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h
index b48d699fd583..85a9aefcc287 100644
--- a/sound/soc/tegra/tegra20_spdif.h
+++ b/sound/soc/tegra/tegra20_spdif.h
@@ -462,8 +462,8 @@
462 462
463struct tegra20_spdif { 463struct tegra20_spdif {
464 struct clk *clk_spdif_out; 464 struct clk *clk_spdif_out;
465 struct tegra_pcm_dma_params capture_dma_data; 465 struct snd_dmaengine_dai_dma_data capture_dma_data;
466 struct tegra_pcm_dma_params playback_dma_data; 466 struct snd_dmaengine_dai_dma_data playback_dma_data;
467 struct regmap *regmap; 467 struct regmap *regmap;
468}; 468};
469 469
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index e5cfb4ac41ba..5e08f3e7e6cf 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -95,8 +95,8 @@ static int tegra30_ahub_runtime_resume(struct device *dev)
95} 95}
96 96
97int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, 97int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
98 unsigned long *fiforeg, 98 dma_addr_t *fiforeg,
99 unsigned long *reqsel) 99 unsigned int *reqsel)
100{ 100{
101 int channel; 101 int channel;
102 u32 reg, val; 102 u32 reg, val;
@@ -178,8 +178,8 @@ int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif)
178EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo); 178EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo);
179 179
180int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, 180int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
181 unsigned long *fiforeg, 181 dma_addr_t *fiforeg,
182 unsigned long *reqsel) 182 unsigned int *reqsel)
183{ 183{
184 int channel; 184 int channel;
185 u32 reg, val; 185 u32 reg, val;
diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h
index e690e2eecc92..b7d7c1a30302 100644
--- a/sound/soc/tegra/tegra30_ahub.h
+++ b/sound/soc/tegra/tegra30_ahub.h
@@ -451,15 +451,15 @@ enum tegra30_ahub_rxcif {
451}; 451};
452 452
453extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, 453extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
454 unsigned long *fiforeg, 454 dma_addr_t *fiforeg,
455 unsigned long *reqsel); 455 unsigned int *reqsel);
456extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif); 456extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
457extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif); 457extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
458extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif); 458extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif);
459 459
460extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, 460extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
461 unsigned long *fiforeg, 461 dma_addr_t *fiforeg,
462 unsigned long *reqsel); 462 unsigned int *reqsel);
463extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif); 463extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif);
464extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif); 464extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif);
465extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif); 465extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif);
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index f4e1ce82750a..31d092d83c71 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -38,6 +38,7 @@
38#include <sound/pcm.h> 38#include <sound/pcm.h>
39#include <sound/pcm_params.h> 39#include <sound/pcm_params.h>
40#include <sound/soc.h> 40#include <sound/soc.h>
41#include <sound/dmaengine_pcm.h>
41 42
42#include "tegra30_ahub.h" 43#include "tegra30_ahub.h"
43#include "tegra30_i2s.h" 44#include "tegra30_i2s.h"
@@ -80,17 +81,17 @@ static int tegra30_i2s_startup(struct snd_pcm_substream *substream,
80 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 81 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
81 ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif, 82 ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
82 &i2s->playback_dma_data.addr, 83 &i2s->playback_dma_data.addr,
83 &i2s->playback_dma_data.req_sel); 84 &i2s->playback_dma_data.slave_id);
84 i2s->playback_dma_data.wrap = 4; 85 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
85 i2s->playback_dma_data.width = 32; 86 i2s->playback_dma_data.maxburst = 4;
86 tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif, 87 tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
87 i2s->playback_fifo_cif); 88 i2s->playback_fifo_cif);
88 } else { 89 } else {
89 ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif, 90 ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
90 &i2s->capture_dma_data.addr, 91 &i2s->capture_dma_data.addr,
91 &i2s->capture_dma_data.req_sel); 92 &i2s->capture_dma_data.slave_id);
92 i2s->capture_dma_data.wrap = 4; 93 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
93 i2s->capture_dma_data.width = 32; 94 i2s->capture_dma_data.maxburst = 4;
94 tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif, 95 tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
95 i2s->capture_i2s_cif); 96 i2s->capture_i2s_cif);
96 } 97 }
@@ -336,6 +337,10 @@ static const struct snd_soc_dai_driver tegra30_i2s_dai_template = {
336 .symmetric_rates = 1, 337 .symmetric_rates = 1,
337}; 338};
338 339
340static const struct snd_soc_component_driver tegra30_i2s_component = {
341 .name = DRV_NAME,
342};
343
339static bool tegra30_i2s_wr_rd_reg(struct device *dev, unsigned int reg) 344static bool tegra30_i2s_wr_rd_reg(struct device *dev, unsigned int reg)
340{ 345{
341 switch (reg) { 346 switch (reg) {
@@ -464,7 +469,8 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
464 goto err_pm_disable; 469 goto err_pm_disable;
465 } 470 }
466 471
467 ret = snd_soc_register_dai(&pdev->dev, &i2s->dai); 472 ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component,
473 &i2s->dai, 1);
468 if (ret) { 474 if (ret) {
469 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); 475 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
470 ret = -ENOMEM; 476 ret = -ENOMEM;
@@ -474,13 +480,13 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
474 ret = tegra_pcm_platform_register(&pdev->dev); 480 ret = tegra_pcm_platform_register(&pdev->dev);
475 if (ret) { 481 if (ret) {
476 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); 482 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
477 goto err_unregister_dai; 483 goto err_unregister_component;
478 } 484 }
479 485
480 return 0; 486 return 0;
481 487
482err_unregister_dai: 488err_unregister_component:
483 snd_soc_unregister_dai(&pdev->dev); 489 snd_soc_unregister_component(&pdev->dev);
484err_suspend: 490err_suspend:
485 if (!pm_runtime_status_suspended(&pdev->dev)) 491 if (!pm_runtime_status_suspended(&pdev->dev))
486 tegra30_i2s_runtime_suspend(&pdev->dev); 492 tegra30_i2s_runtime_suspend(&pdev->dev);
@@ -501,7 +507,7 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
501 tegra30_i2s_runtime_suspend(&pdev->dev); 507 tegra30_i2s_runtime_suspend(&pdev->dev);
502 508
503 tegra_pcm_platform_unregister(&pdev->dev); 509 tegra_pcm_platform_unregister(&pdev->dev);
504 snd_soc_unregister_dai(&pdev->dev); 510 snd_soc_unregister_component(&pdev->dev);
505 511
506 clk_put(i2s->clk_i2s); 512 clk_put(i2s->clk_i2s);
507 513
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h
index a294d942b9f7..bea23afe3b9f 100644
--- a/sound/soc/tegra/tegra30_i2s.h
+++ b/sound/soc/tegra/tegra30_i2s.h
@@ -231,10 +231,10 @@ struct tegra30_i2s {
231 struct clk *clk_i2s; 231 struct clk *clk_i2s;
232 enum tegra30_ahub_txcif capture_i2s_cif; 232 enum tegra30_ahub_txcif capture_i2s_cif;
233 enum tegra30_ahub_rxcif capture_fifo_cif; 233 enum tegra30_ahub_rxcif capture_fifo_cif;
234 struct tegra_pcm_dma_params capture_dma_data; 234 struct snd_dmaengine_dai_dma_data capture_dma_data;
235 enum tegra30_ahub_rxcif playback_i2s_cif; 235 enum tegra30_ahub_rxcif playback_i2s_cif;
236 enum tegra30_ahub_txcif playback_fifo_cif; 236 enum tegra30_ahub_txcif playback_fifo_cif;
237 struct tegra_pcm_dma_params playback_dma_data; 237 struct snd_dmaengine_dai_dma_data playback_dma_data;
238 struct regmap *regmap; 238 struct regmap *regmap;
239}; 239};
240 240
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index c925ab0adeb6..6d1c70c3d753 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -43,8 +43,6 @@
43static const struct snd_pcm_hardware tegra_pcm_hardware = { 43static const struct snd_pcm_hardware tegra_pcm_hardware = {
44 .info = SNDRV_PCM_INFO_MMAP | 44 .info = SNDRV_PCM_INFO_MMAP |
45 SNDRV_PCM_INFO_MMAP_VALID | 45 SNDRV_PCM_INFO_MMAP_VALID |
46 SNDRV_PCM_INFO_PAUSE |
47 SNDRV_PCM_INFO_RESUME |
48 SNDRV_PCM_INFO_INTERLEAVED, 46 SNDRV_PCM_INFO_INTERLEAVED,
49 .formats = SNDRV_PCM_FMTBIT_S16_LE, 47 .formats = SNDRV_PCM_FMTBIT_S16_LE,
50 .channels_min = 2, 48 .channels_min = 2,
@@ -75,24 +73,15 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
75 return 0; 73 return 0;
76} 74}
77 75
78static int tegra_pcm_close(struct snd_pcm_substream *substream)
79{
80 snd_dmaengine_pcm_close(substream);
81 return 0;
82}
83
84static int tegra_pcm_hw_params(struct snd_pcm_substream *substream, 76static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
85 struct snd_pcm_hw_params *params) 77 struct snd_pcm_hw_params *params)
86{ 78{
87 struct snd_soc_pcm_runtime *rtd = substream->private_data; 79 struct snd_soc_pcm_runtime *rtd = substream->private_data;
88 struct device *dev = rtd->platform->dev; 80 struct device *dev = rtd->platform->dev;
89 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); 81 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
90 struct tegra_pcm_dma_params *dmap;
91 struct dma_slave_config slave_config; 82 struct dma_slave_config slave_config;
92 int ret; 83 int ret;
93 84
94 dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
95
96 ret = snd_hwparams_to_dma_slave_config(substream, params, 85 ret = snd_hwparams_to_dma_slave_config(substream, params,
97 &slave_config); 86 &slave_config);
98 if (ret) { 87 if (ret) {
@@ -100,16 +89,9 @@ static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
100 return ret; 89 return ret;
101 } 90 }
102 91
103 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 92 snd_dmaengine_pcm_set_config_from_dai_data(substream,
104 slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 93 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
105 slave_config.dst_addr = dmap->addr; 94 &slave_config);
106 slave_config.dst_maxburst = 4;
107 } else {
108 slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
109 slave_config.src_addr = dmap->addr;
110 slave_config.src_maxburst = 4;
111 }
112 slave_config.slave_id = dmap->req_sel;
113 95
114 ret = dmaengine_slave_config(chan, &slave_config); 96 ret = dmaengine_slave_config(chan, &slave_config);
115 if (ret < 0) { 97 if (ret < 0) {
@@ -127,26 +109,6 @@ static int tegra_pcm_hw_free(struct snd_pcm_substream *substream)
127 return 0; 109 return 0;
128} 110}
129 111
130static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
131{
132 switch (cmd) {
133 case SNDRV_PCM_TRIGGER_START:
134 case SNDRV_PCM_TRIGGER_RESUME:
135 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
136 return snd_dmaengine_pcm_trigger(substream,
137 SNDRV_PCM_TRIGGER_START);
138
139 case SNDRV_PCM_TRIGGER_STOP:
140 case SNDRV_PCM_TRIGGER_SUSPEND:
141 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
142 return snd_dmaengine_pcm_trigger(substream,
143 SNDRV_PCM_TRIGGER_STOP);
144 default:
145 return -EINVAL;
146 }
147 return 0;
148}
149
150static int tegra_pcm_mmap(struct snd_pcm_substream *substream, 112static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
151 struct vm_area_struct *vma) 113 struct vm_area_struct *vma)
152{ 114{
@@ -160,11 +122,11 @@ static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
160 122
161static struct snd_pcm_ops tegra_pcm_ops = { 123static struct snd_pcm_ops tegra_pcm_ops = {
162 .open = tegra_pcm_open, 124 .open = tegra_pcm_open,
163 .close = tegra_pcm_close, 125 .close = snd_dmaengine_pcm_close,
164 .ioctl = snd_pcm_lib_ioctl, 126 .ioctl = snd_pcm_lib_ioctl,
165 .hw_params = tegra_pcm_hw_params, 127 .hw_params = tegra_pcm_hw_params,
166 .hw_free = tegra_pcm_hw_free, 128 .hw_free = tegra_pcm_hw_free,
167 .trigger = tegra_pcm_trigger, 129 .trigger = snd_dmaengine_pcm_trigger,
168 .pointer = snd_dmaengine_pcm_pointer, 130 .pointer = snd_dmaengine_pcm_pointer,
169 .mmap = tegra_pcm_mmap, 131 .mmap = tegra_pcm_mmap,
170}; 132};
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
index bc8b46af928e..68ad901714a9 100644
--- a/sound/soc/tegra/tegra_pcm.h
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -31,13 +31,6 @@
31#ifndef __TEGRA_PCM_H__ 31#ifndef __TEGRA_PCM_H__
32#define __TEGRA_PCM_H__ 32#define __TEGRA_PCM_H__
33 33
34struct tegra_pcm_dma_params {
35 unsigned long addr;
36 unsigned long wrap;
37 unsigned long width;
38 unsigned long req_sel;
39};
40
41int tegra_pcm_platform_register(struct device *dev); 34int tegra_pcm_platform_register(struct device *dev);
42void tegra_pcm_platform_unregister(struct device *dev); 35void tegra_pcm_platform_unregister(struct device *dev);
43 36
diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c
index 68d42403d9b5..6839f88167d0 100644
--- a/sound/soc/tegra/tegra_wm9712.c
+++ b/sound/soc/tegra/tegra_wm9712.c
@@ -55,7 +55,7 @@ static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd)
55static struct snd_soc_dai_link tegra_wm9712_dai = { 55static struct snd_soc_dai_link tegra_wm9712_dai = {
56 .name = "AC97 HiFi", 56 .name = "AC97 HiFi",
57 .stream_name = "AC97 HiFi", 57 .stream_name = "AC97 HiFi",
58 .cpu_dai_name = "tegra-ac97-pcm", 58 .cpu_dai_name = "tegra20-ac97",
59 .codec_dai_name = "wm9712-hifi", 59 .codec_dai_name = "wm9712-hifi",
60 .codec_name = "wm9712-codec", 60 .codec_name = "wm9712-codec",
61 .init = tegra_wm9712_init, 61 .init = tegra_wm9712_init,
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 16ab69635e2e..8a2840304d28 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -170,6 +170,10 @@ static struct snd_soc_dai_driver txx9aclc_ac97_dai = {
170 }, 170 },
171}; 171};
172 172
173static const struct snd_soc_component_driver txx9aclc_ac97_component = {
174 .name = "txx9aclc-ac97",
175};
176
173static int txx9aclc_ac97_dev_probe(struct platform_device *pdev) 177static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
174{ 178{
175 struct txx9aclc_plat_drvdata *drvdata; 179 struct txx9aclc_plat_drvdata *drvdata;
@@ -205,12 +209,13 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
205 if (err < 0) 209 if (err < 0)
206 return err; 210 return err;
207 211
208 return snd_soc_register_dai(&pdev->dev, &txx9aclc_ac97_dai); 212 return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component,
213 &txx9aclc_ac97_dai, 1);
209} 214}
210 215
211static int txx9aclc_ac97_dev_remove(struct platform_device *pdev) 216static int txx9aclc_ac97_dev_remove(struct platform_device *pdev)
212{ 217{
213 snd_soc_unregister_dai(&pdev->dev); 218 snd_soc_unregister_component(&pdev->dev);
214 return 0; 219 return 0;
215} 220}
216 221
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 94a3e5705aaa..f1e8a5ecb00b 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -768,6 +768,11 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = {
768 }, 768 },
769}; 769};
770 770
771static const struct snd_soc_component_driver ux500_msp_component = {
772 .name = "ux500-msp",
773};
774
775
771static int ux500_msp_drv_probe(struct platform_device *pdev) 776static int ux500_msp_drv_probe(struct platform_device *pdev)
772{ 777{
773 struct ux500_msp_i2s_drvdata *drvdata; 778 struct ux500_msp_i2s_drvdata *drvdata;
@@ -825,8 +830,8 @@ static int ux500_msp_drv_probe(struct platform_device *pdev)
825 } 830 }
826 dev_set_drvdata(&pdev->dev, drvdata); 831 dev_set_drvdata(&pdev->dev, drvdata);
827 832
828 ret = snd_soc_register_dai(&pdev->dev, 833 ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component,
829 &ux500_msp_dai_drv[drvdata->msp->id]); 834 &ux500_msp_dai_drv[drvdata->msp->id], 1);
830 if (ret < 0) { 835 if (ret < 0) {
831 dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n", 836 dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n",
832 __func__, drvdata->msp->id); 837 __func__, drvdata->msp->id);
@@ -844,7 +849,7 @@ static int ux500_msp_drv_probe(struct platform_device *pdev)
844 return 0; 849 return 0;
845 850
846err_reg_plat: 851err_reg_plat:
847 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); 852 snd_soc_unregister_component(&pdev->dev);
848err_init_msp: 853err_init_msp:
849 clk_put(drvdata->clk); 854 clk_put(drvdata->clk);
850err_clk: 855err_clk:
@@ -861,7 +866,7 @@ static int ux500_msp_drv_remove(struct platform_device *pdev)
861 866
862 ux500_pcm_unregister_platform(pdev); 867 ux500_pcm_unregister_platform(pdev);
863 868
864 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); 869 snd_soc_unregister_component(&pdev->dev);
865 870
866 devm_regulator_put(drvdata->reg_vape); 871 devm_regulator_put(drvdata->reg_vape);
867 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); 872 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s");
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index 846fa82a58d0..09b5364e5095 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -28,28 +28,19 @@
28#include "ux500_msp_i2s.h" 28#include "ux500_msp_i2s.h"
29#include "ux500_pcm.h" 29#include "ux500_pcm.h"
30 30
31static struct snd_pcm_hardware ux500_pcm_hw_playback = { 31#define UX500_PLATFORM_MIN_RATE 8000
32 .info = SNDRV_PCM_INFO_INTERLEAVED | 32#define UX500_PLATFORM_MAX_RATE 48000
33 SNDRV_PCM_INFO_MMAP | 33
34 SNDRV_PCM_INFO_RESUME | 34#define UX500_PLATFORM_MIN_CHANNELS 1
35 SNDRV_PCM_INFO_PAUSE, 35#define UX500_PLATFORM_MAX_CHANNELS 8
36 .formats = SNDRV_PCM_FMTBIT_S16_LE |
37 SNDRV_PCM_FMTBIT_U16_LE |
38 SNDRV_PCM_FMTBIT_S16_BE |
39 SNDRV_PCM_FMTBIT_U16_BE,
40 .rates = SNDRV_PCM_RATE_KNOT,
41 .rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK,
42 .rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK,
43 .channels_min = UX500_PLATFORM_MIN_CHANNELS,
44 .channels_max = UX500_PLATFORM_MAX_CHANNELS,
45 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
46 .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
47 .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
48 .periods_min = UX500_PLATFORM_PERIODS_MIN,
49 .periods_max = UX500_PLATFORM_PERIODS_MAX,
50};
51 36
52static struct snd_pcm_hardware ux500_pcm_hw_capture = { 37#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
38#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
39#define UX500_PLATFORM_PERIODS_MIN 2
40#define UX500_PLATFORM_PERIODS_MAX 48
41#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
42
43static struct snd_pcm_hardware ux500_pcm_hw = {
53 .info = SNDRV_PCM_INFO_INTERLEAVED | 44 .info = SNDRV_PCM_INFO_INTERLEAVED |
54 SNDRV_PCM_INFO_MMAP | 45 SNDRV_PCM_INFO_MMAP |
55 SNDRV_PCM_INFO_RESUME | 46 SNDRV_PCM_INFO_RESUME |
@@ -59,8 +50,8 @@ static struct snd_pcm_hardware ux500_pcm_hw_capture = {
59 SNDRV_PCM_FMTBIT_S16_BE | 50 SNDRV_PCM_FMTBIT_S16_BE |
60 SNDRV_PCM_FMTBIT_U16_BE, 51 SNDRV_PCM_FMTBIT_U16_BE,
61 .rates = SNDRV_PCM_RATE_KNOT, 52 .rates = SNDRV_PCM_RATE_KNOT,
62 .rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE, 53 .rate_min = UX500_PLATFORM_MIN_RATE,
63 .rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE, 54 .rate_max = UX500_PLATFORM_MAX_RATE,
64 .channels_min = UX500_PLATFORM_MIN_CHANNELS, 55 .channels_min = UX500_PLATFORM_MIN_CHANNELS,
65 .channels_max = UX500_PLATFORM_MAX_CHANNELS, 56 .channels_max = UX500_PLATFORM_MAX_CHANNELS,
66 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, 57 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
@@ -90,8 +81,6 @@ static void ux500_pcm_dma_hw_free(struct device *dev,
90 81
91static int ux500_pcm_open(struct snd_pcm_substream *substream) 82static int ux500_pcm_open(struct snd_pcm_substream *substream)
92{ 83{
93 int stream_id = substream->pstr->stream;
94 struct snd_pcm_runtime *runtime = substream->runtime;
95 struct snd_soc_pcm_runtime *rtd = substream->private_data; 84 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct snd_soc_dai *dai = rtd->cpu_dai; 85 struct snd_soc_dai *dai = rtd->cpu_dai;
97 struct device *dev = dai->dev; 86 struct device *dev = dai->dev;
@@ -104,26 +93,7 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream)
104 snd_pcm_stream_str(substream)); 93 snd_pcm_stream_str(substream));
105 94
106 dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__); 95 dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__);
107 if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) 96 snd_soc_set_runtime_hwparams(substream, &ux500_pcm_hw);
108 snd_soc_set_runtime_hwparams(substream,
109 &ux500_pcm_hw_playback);
110 else
111 snd_soc_set_runtime_hwparams(substream,
112 &ux500_pcm_hw_capture);
113
114 /* ensure that buffer size is a multiple of period size */
115 ret = snd_pcm_hw_constraint_integer(runtime,
116 SNDRV_PCM_HW_PARAM_PERIODS);
117 if (ret < 0) {
118 dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n",
119 __func__, ret);
120 return ret;
121 }
122
123 dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__,
124 snd_pcm_stream_str(substream));
125 runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
126 ux500_pcm_hw_playback : ux500_pcm_hw_capture;
127 97
128 mem_data_width = STEDMA40_HALFWORD_WIDTH; 98 mem_data_width = STEDMA40_HALFWORD_WIDTH;
129 99
@@ -164,20 +134,6 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream)
164 return ret; 134 return ret;
165 } 135 }
166 136
167 snd_dmaengine_pcm_set_data(substream, dma_cfg);
168
169 return 0;
170}
171
172static int ux500_pcm_close(struct snd_pcm_substream *substream)
173{
174 struct snd_soc_pcm_runtime *rtd = substream->private_data;
175 struct snd_soc_dai *dai = rtd->cpu_dai;
176
177 dev_dbg(dai->dev, "%s: Enter\n", __func__);
178
179 snd_dmaengine_pcm_close(substream);
180
181 return 0; 137 return 0;
182} 138}
183 139
@@ -255,7 +211,7 @@ static int ux500_pcm_mmap(struct snd_pcm_substream *substream,
255 211
256static struct snd_pcm_ops ux500_pcm_ops = { 212static struct snd_pcm_ops ux500_pcm_ops = {
257 .open = ux500_pcm_open, 213 .open = ux500_pcm_open,
258 .close = ux500_pcm_close, 214 .close = snd_dmaengine_pcm_close,
259 .ioctl = snd_pcm_lib_ioctl, 215 .ioctl = snd_pcm_lib_ioctl,
260 .hw_params = ux500_pcm_hw_params, 216 .hw_params = ux500_pcm_hw_params,
261 .hw_free = ux500_pcm_hw_free, 217 .hw_free = ux500_pcm_hw_free,
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h
index 76d344476afc..d76e1aff6458 100644
--- a/sound/soc/ux500/ux500_pcm.h
+++ b/sound/soc/ux500/ux500_pcm.h
@@ -18,20 +18,6 @@
18 18
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20 20
21#define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000
22#define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000
23#define UX500_PLATFORM_MIN_RATE_CAPTURE 8000
24#define UX500_PLATFORM_MAX_RATE_CAPTURE 48000
25
26#define UX500_PLATFORM_MIN_CHANNELS 1
27#define UX500_PLATFORM_MAX_CHANNELS 8
28
29#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
30#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
31#define UX500_PLATFORM_PERIODS_MIN 2
32#define UX500_PLATFORM_PERIODS_MAX 48
33#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
34
35int ux500_pcm_register_platform(struct platform_device *pdev); 21int ux500_pcm_register_platform(struct platform_device *pdev);
36int ux500_pcm_unregister_platform(struct platform_device *pdev); 22int ux500_pcm_unregister_platform(struct platform_device *pdev);
37 23
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 5e634a2eb282..9e2703a25156 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -253,7 +253,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
253{ 253{
254 struct usb_device *dev = chip->dev; 254 struct usb_device *dev = chip->dev;
255 unsigned char data[4]; 255 unsigned char data[4];
256 int err, crate; 256 int err, cur_rate, prev_rate;
257 int clock = snd_usb_clock_find_source(chip, fmt->clock); 257 int clock = snd_usb_clock_find_source(chip, fmt->clock);
258 258
259 if (clock < 0) 259 if (clock < 0)
@@ -266,6 +266,19 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
266 return -ENXIO; 266 return -ENXIO;
267 } 267 }
268 268
269 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
270 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
271 UAC2_CS_CONTROL_SAM_FREQ << 8,
272 snd_usb_ctrl_intf(chip) | (clock << 8),
273 data, sizeof(data));
274 if (err < 0) {
275 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
276 dev->devnum, iface, fmt->altsetting);
277 prev_rate = 0;
278 } else {
279 prev_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
280 }
281
269 data[0] = rate; 282 data[0] = rate;
270 data[1] = rate >> 8; 283 data[1] = rate >> 8;
271 data[2] = rate >> 16; 284 data[2] = rate >> 16;
@@ -280,19 +293,31 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
280 return err; 293 return err;
281 } 294 }
282 295
283 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, 296 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
284 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 297 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
285 UAC2_CS_CONTROL_SAM_FREQ << 8, 298 UAC2_CS_CONTROL_SAM_FREQ << 8,
286 snd_usb_ctrl_intf(chip) | (clock << 8), 299 snd_usb_ctrl_intf(chip) | (clock << 8),
287 data, sizeof(data))) < 0) { 300 data, sizeof(data));
301 if (err < 0) {
288 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", 302 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
289 dev->devnum, iface, fmt->altsetting); 303 dev->devnum, iface, fmt->altsetting);
290 return err; 304 cur_rate = 0;
305 } else {
306 cur_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
291 } 307 }
292 308
293 crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); 309 if (cur_rate != rate) {
294 if (crate != rate) 310 snd_printd(KERN_WARNING
295 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate); 311 "current rate %d is different from the runtime rate %d\n",
312 cur_rate, rate);
313 }
314
315 /* Some devices doesn't respond to sample rate changes while the
316 * interface is active. */
317 if (rate != prev_rate) {
318 usb_set_interface(dev, iface, 0);
319 usb_set_interface(dev, iface, fmt->altsetting);
320 }
296 321
297 return 0; 322 return 0;
298} 323}
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 638e7f738018..ca4739c3f650 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -715,8 +715,9 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
715 case UAC2_CLOCK_SELECTOR: { 715 case UAC2_CLOCK_SELECTOR: {
716 struct uac_selector_unit_descriptor *d = p1; 716 struct uac_selector_unit_descriptor *d = p1;
717 /* call recursively to retrieve the channel info */ 717 /* call recursively to retrieve the channel info */
718 if (check_input_term(state, d->baSourceID[0], term) < 0) 718 err = check_input_term(state, d->baSourceID[0], term);
719 return -ENODEV; 719 if (err < 0)
720 return err;
720 term->type = d->bDescriptorSubtype << 16; /* virtual type */ 721 term->type = d->bDescriptorSubtype << 16; /* virtual type */
721 term->id = id; 722 term->id = id;
722 term->name = uac_selector_unit_iSelector(d); 723 term->name = uac_selector_unit_iSelector(d);
@@ -725,7 +726,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
725 case UAC1_PROCESSING_UNIT: 726 case UAC1_PROCESSING_UNIT:
726 case UAC1_EXTENSION_UNIT: 727 case UAC1_EXTENSION_UNIT:
727 /* UAC2_PROCESSING_UNIT_V2 */ 728 /* UAC2_PROCESSING_UNIT_V2 */
728 /* UAC2_EFFECT_UNIT */ { 729 /* UAC2_EFFECT_UNIT */
730 case UAC2_EXTENSION_UNIT_V2: {
729 struct uac_processing_unit_descriptor *d = p1; 731 struct uac_processing_unit_descriptor *d = p1;
730 732
731 if (state->mixer->protocol == UAC_VERSION_2 && 733 if (state->mixer->protocol == UAC_VERSION_2 &&
@@ -1356,8 +1358,9 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1356 return err; 1358 return err;
1357 1359
1358 /* determine the input source type and name */ 1360 /* determine the input source type and name */
1359 if (check_input_term(state, hdr->bSourceID, &iterm) < 0) 1361 err = check_input_term(state, hdr->bSourceID, &iterm);
1360 return -EINVAL; 1362 if (err < 0)
1363 return err;
1361 1364
1362 master_bits = snd_usb_combine_bytes(bmaControls, csize); 1365 master_bits = snd_usb_combine_bytes(bmaControls, csize);
1363 /* master configuration quirks */ 1366 /* master configuration quirks */
@@ -2052,6 +2055,8 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
2052 return parse_audio_extension_unit(state, unitid, p1); 2055 return parse_audio_extension_unit(state, unitid, p1);
2053 else /* UAC_VERSION_2 */ 2056 else /* UAC_VERSION_2 */
2054 return parse_audio_processing_unit(state, unitid, p1); 2057 return parse_audio_processing_unit(state, unitid, p1);
2058 case UAC2_EXTENSION_UNIT_V2:
2059 return parse_audio_extension_unit(state, unitid, p1);
2055 default: 2060 default:
2056 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); 2061 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
2057 return -EINVAL; 2062 return -EINVAL;
@@ -2118,7 +2123,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
2118 state.oterm.type = le16_to_cpu(desc->wTerminalType); 2123 state.oterm.type = le16_to_cpu(desc->wTerminalType);
2119 state.oterm.name = desc->iTerminal; 2124 state.oterm.name = desc->iTerminal;
2120 err = parse_audio_unit(&state, desc->bSourceID); 2125 err = parse_audio_unit(&state, desc->bSourceID);
2121 if (err < 0) 2126 if (err < 0 && err != -EINVAL)
2122 return err; 2127 return err;
2123 } else { /* UAC_VERSION_2 */ 2128 } else { /* UAC_VERSION_2 */
2124 struct uac2_output_terminal_descriptor *desc = p; 2129 struct uac2_output_terminal_descriptor *desc = p;
@@ -2130,12 +2135,12 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
2130 state.oterm.type = le16_to_cpu(desc->wTerminalType); 2135 state.oterm.type = le16_to_cpu(desc->wTerminalType);
2131 state.oterm.name = desc->iTerminal; 2136 state.oterm.name = desc->iTerminal;
2132 err = parse_audio_unit(&state, desc->bSourceID); 2137 err = parse_audio_unit(&state, desc->bSourceID);
2133 if (err < 0) 2138 if (err < 0 && err != -EINVAL)
2134 return err; 2139 return err;
2135 2140
2136 /* for UAC2, use the same approach to also add the clock selectors */ 2141 /* for UAC2, use the same approach to also add the clock selectors */
2137 err = parse_audio_unit(&state, desc->bCSourceID); 2142 err = parse_audio_unit(&state, desc->bCSourceID);
2138 if (err < 0) 2143 if (err < 0 && err != -EINVAL)
2139 return err; 2144 return err;
2140 } 2145 }
2141 } 2146 }