aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2014-10-06 07:48:51 -0400
committerMark Brown <broonie@kernel.org>2014-10-06 07:48:51 -0400
commit5bcaca4b5bf2b05cc15a2c5bfb3d95fc49607e36 (patch)
tree1272753ff995b96c610c922f1963fb454f900311
parent832a94143c549bc750350c4e770f1f604e6aaffb (diff)
parentb2d9de549c30170eed5691d369cf16680e0ce03a (diff)
Merge remote-tracking branch 'asoc/topic/component' into asoc-next
-rw-r--r--include/sound/soc-dapm.h1
-rw-r--r--include/sound/soc.h94
-rw-r--r--sound/soc/codecs/wm8350.c2
-rw-r--r--sound/soc/codecs/wm8753.c2
-rw-r--r--sound/soc/codecs/wm8971.c2
-rw-r--r--sound/soc/intel/Makefile3
-rw-r--r--sound/soc/intel/sst-atom-controls.c39
-rw-r--r--sound/soc/intel/sst-atom-controls.h286
-rw-r--r--sound/soc/intel/sst-haswell-pcm.c56
-rw-r--r--sound/soc/intel/sst-mfld-platform-compress.c38
-rw-r--r--sound/soc/intel/sst-mfld-platform-pcm.c34
-rw-r--r--sound/soc/intel/sst-mfld-platform.h57
-rw-r--r--sound/soc/omap/rx51.c2
-rw-r--r--sound/soc/samsung/speyside.c6
-rw-r--r--sound/soc/soc-core.c622
-rw-r--r--sound/soc/soc-dapm.c3
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c4
-rw-r--r--sound/soc/soc-io.c28
18 files changed, 760 insertions, 519 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index aac04ff84eea..d60c61b4b341 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -593,7 +593,6 @@ struct snd_soc_dapm_context {
593 593
594 struct device *dev; /* from parent - for debug */ 594 struct device *dev; /* from parent - for debug */
595 struct snd_soc_component *component; /* parent component */ 595 struct snd_soc_component *component; /* parent component */
596 struct snd_soc_codec *codec; /* parent codec */
597 struct snd_soc_card *card; /* parent card */ 596 struct snd_soc_card *card; /* parent card */
598 597
599 /* used during DAPM updates */ 598 /* used during DAPM updates */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index c83a334dd00f..f1366ebca9c5 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -690,6 +690,17 @@ struct snd_soc_compr_ops {
690struct snd_soc_component_driver { 690struct snd_soc_component_driver {
691 const char *name; 691 const char *name;
692 692
693 /* Default control and setup, added after probe() is run */
694 const struct snd_kcontrol_new *controls;
695 unsigned int num_controls;
696 const struct snd_soc_dapm_widget *dapm_widgets;
697 unsigned int num_dapm_widgets;
698 const struct snd_soc_dapm_route *dapm_routes;
699 unsigned int num_dapm_routes;
700
701 int (*probe)(struct snd_soc_component *);
702 void (*remove)(struct snd_soc_component *);
703
693 /* DT */ 704 /* DT */
694 int (*of_xlate_dai_name)(struct snd_soc_component *component, 705 int (*of_xlate_dai_name)(struct snd_soc_component *component,
695 struct of_phandle_args *args, 706 struct of_phandle_args *args,
@@ -697,6 +708,10 @@ struct snd_soc_component_driver {
697 void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type, 708 void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type,
698 int subseq); 709 int subseq);
699 int (*stream_event)(struct snd_soc_component *, int event); 710 int (*stream_event)(struct snd_soc_component *, int event);
711
712 /* probe ordering - for components with runtime dependencies */
713 int probe_order;
714 int remove_order;
700}; 715};
701 716
702struct snd_soc_component { 717struct snd_soc_component {
@@ -710,6 +725,7 @@ struct snd_soc_component {
710 725
711 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ 726 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
712 unsigned int registered_as_component:1; 727 unsigned int registered_as_component:1;
728 unsigned int probed:1;
713 729
714 struct list_head list; 730 struct list_head list;
715 731
@@ -728,9 +744,35 @@ struct snd_soc_component {
728 744
729 struct mutex io_mutex; 745 struct mutex io_mutex;
730 746
747#ifdef CONFIG_DEBUG_FS
748 struct dentry *debugfs_root;
749#endif
750
751 /*
752 * DO NOT use any of the fields below in drivers, they are temporary and
753 * are going to be removed again soon. If you use them in driver code the
754 * driver will be marked as BROKEN when these fields are removed.
755 */
756
731 /* Don't use these, use snd_soc_component_get_dapm() */ 757 /* Don't use these, use snd_soc_component_get_dapm() */
732 struct snd_soc_dapm_context dapm; 758 struct snd_soc_dapm_context dapm;
733 struct snd_soc_dapm_context *dapm_ptr; 759 struct snd_soc_dapm_context *dapm_ptr;
760
761 const struct snd_kcontrol_new *controls;
762 unsigned int num_controls;
763 const struct snd_soc_dapm_widget *dapm_widgets;
764 unsigned int num_dapm_widgets;
765 const struct snd_soc_dapm_route *dapm_routes;
766 unsigned int num_dapm_routes;
767 struct snd_soc_codec *codec;
768
769 int (*probe)(struct snd_soc_component *);
770 void (*remove)(struct snd_soc_component *);
771
772#ifdef CONFIG_DEBUG_FS
773 void (*init_debugfs)(struct snd_soc_component *component);
774 const char *debugfs_prefix;
775#endif
734}; 776};
735 777
736/* SoC Audio Codec device */ 778/* SoC Audio Codec device */
@@ -746,11 +788,9 @@ struct snd_soc_codec {
746 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ 788 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
747 unsigned int cache_bypass:1; /* Suppress access to the cache */ 789 unsigned int cache_bypass:1; /* Suppress access to the cache */
748 unsigned int suspended:1; /* Codec is in suspend PM state */ 790 unsigned int suspended:1; /* Codec is in suspend PM state */
749 unsigned int probed:1; /* Codec has been probed */
750 unsigned int ac97_registered:1; /* Codec has been AC97 registered */ 791 unsigned int ac97_registered:1; /* Codec has been AC97 registered */
751 unsigned int ac97_created:1; /* Codec has been created by SoC */ 792 unsigned int ac97_created:1; /* Codec has been created by SoC */
752 unsigned int cache_init:1; /* codec cache has been initialized */ 793 unsigned int cache_init:1; /* codec cache has been initialized */
753 u32 cache_only; /* Suppress writes to hardware */
754 u32 cache_sync; /* Cache needs to be synced to hardware */ 794 u32 cache_sync; /* Cache needs to be synced to hardware */
755 795
756 /* codec IO */ 796 /* codec IO */
@@ -766,7 +806,6 @@ struct snd_soc_codec {
766 struct snd_soc_dapm_context dapm; 806 struct snd_soc_dapm_context dapm;
767 807
768#ifdef CONFIG_DEBUG_FS 808#ifdef CONFIG_DEBUG_FS
769 struct dentry *debugfs_codec_root;
770 struct dentry *debugfs_reg; 809 struct dentry *debugfs_reg;
771#endif 810#endif
772}; 811};
@@ -813,10 +852,6 @@ struct snd_soc_codec_driver {
813 enum snd_soc_dapm_type, int); 852 enum snd_soc_dapm_type, int);
814 853
815 bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */ 854 bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */
816
817 /* probe ordering - for components with runtime dependencies */
818 int probe_order;
819 int remove_order;
820}; 855};
821 856
822/* SoC platform interface */ 857/* SoC platform interface */
@@ -832,14 +867,6 @@ struct snd_soc_platform_driver {
832 int (*pcm_new)(struct snd_soc_pcm_runtime *); 867 int (*pcm_new)(struct snd_soc_pcm_runtime *);
833 void (*pcm_free)(struct snd_pcm *); 868 void (*pcm_free)(struct snd_pcm *);
834 869
835 /* Default control and setup, added after probe() is run */
836 const struct snd_kcontrol_new *controls;
837 int num_controls;
838 const struct snd_soc_dapm_widget *dapm_widgets;
839 int num_dapm_widgets;
840 const struct snd_soc_dapm_route *dapm_routes;
841 int num_dapm_routes;
842
843 /* 870 /*
844 * For platform caused delay reporting. 871 * For platform caused delay reporting.
845 * Optional. 872 * Optional.
@@ -853,13 +880,6 @@ struct snd_soc_platform_driver {
853 /* platform stream compress ops */ 880 /* platform stream compress ops */
854 const struct snd_compr_ops *compr_ops; 881 const struct snd_compr_ops *compr_ops;
855 882
856 /* probe ordering - for components with runtime dependencies */
857 int probe_order;
858 int remove_order;
859
860 /* platform IO - used for platform DAPM */
861 unsigned int (*read)(struct snd_soc_platform *, unsigned int);
862 int (*write)(struct snd_soc_platform *, unsigned int, unsigned int);
863 int (*bespoke_trigger)(struct snd_pcm_substream *, int); 883 int (*bespoke_trigger)(struct snd_pcm_substream *, int);
864}; 884};
865 885
@@ -874,15 +894,10 @@ struct snd_soc_platform {
874 const struct snd_soc_platform_driver *driver; 894 const struct snd_soc_platform_driver *driver;
875 895
876 unsigned int suspended:1; /* platform is suspended */ 896 unsigned int suspended:1; /* platform is suspended */
877 unsigned int probed:1;
878 897
879 struct list_head list; 898 struct list_head list;
880 899
881 struct snd_soc_component component; 900 struct snd_soc_component component;
882
883#ifdef CONFIG_DEBUG_FS
884 struct dentry *debugfs_platform_root;
885#endif
886}; 901};
887 902
888struct snd_soc_dai_link { 903struct snd_soc_dai_link {
@@ -994,7 +1009,7 @@ struct snd_soc_aux_dev {
994 const struct device_node *codec_of_node; 1009 const struct device_node *codec_of_node;
995 1010
996 /* codec/machine specific init - e.g. add machine controls */ 1011 /* codec/machine specific init - e.g. add machine controls */
997 int (*init)(struct snd_soc_dapm_context *dapm); 1012 int (*init)(struct snd_soc_component *component);
998}; 1013};
999 1014
1000/* SoC card */ 1015/* SoC card */
@@ -1112,6 +1127,7 @@ struct snd_soc_pcm_runtime {
1112 struct snd_soc_platform *platform; 1127 struct snd_soc_platform *platform;
1113 struct snd_soc_dai *codec_dai; 1128 struct snd_soc_dai *codec_dai;
1114 struct snd_soc_dai *cpu_dai; 1129 struct snd_soc_dai *cpu_dai;
1130 struct snd_soc_component *component; /* Only valid for AUX dev rtds */
1115 1131
1116 struct snd_soc_dai **codec_dais; 1132 struct snd_soc_dai **codec_dais;
1117 unsigned int num_codecs; 1133 unsigned int num_codecs;
@@ -1260,9 +1276,6 @@ void snd_soc_component_async_complete(struct snd_soc_component *component);
1260int snd_soc_component_test_bits(struct snd_soc_component *component, 1276int snd_soc_component_test_bits(struct snd_soc_component *component,
1261 unsigned int reg, unsigned int mask, unsigned int value); 1277 unsigned int reg, unsigned int mask, unsigned int value);
1262 1278
1263int snd_soc_component_init_io(struct snd_soc_component *component,
1264 struct regmap *regmap);
1265
1266/* device driver data */ 1279/* device driver data */
1267 1280
1268static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, 1281static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
@@ -1276,26 +1289,37 @@ static inline void *snd_soc_card_get_drvdata(struct snd_soc_card *card)
1276 return card->drvdata; 1289 return card->drvdata;
1277} 1290}
1278 1291
1292static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c,
1293 void *data)
1294{
1295 dev_set_drvdata(c->dev, data);
1296}
1297
1298static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
1299{
1300 return dev_get_drvdata(c->dev);
1301}
1302
1279static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec, 1303static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
1280 void *data) 1304 void *data)
1281{ 1305{
1282 dev_set_drvdata(codec->dev, data); 1306 snd_soc_component_set_drvdata(&codec->component, data);
1283} 1307}
1284 1308
1285static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec) 1309static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
1286{ 1310{
1287 return dev_get_drvdata(codec->dev); 1311 return snd_soc_component_get_drvdata(&codec->component);
1288} 1312}
1289 1313
1290static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform, 1314static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform,
1291 void *data) 1315 void *data)
1292{ 1316{
1293 dev_set_drvdata(platform->dev, data); 1317 snd_soc_component_set_drvdata(&platform->component, data);
1294} 1318}
1295 1319
1296static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform) 1320static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform)
1297{ 1321{
1298 return dev_get_drvdata(platform->dev); 1322 return snd_soc_component_get_drvdata(&platform->component);
1299} 1323}
1300 1324
1301static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd, 1325static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 3dfdcc4197fa..628ec774cf22 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -212,7 +212,7 @@ static void wm8350_pga_work(struct work_struct *work)
212{ 212{
213 struct snd_soc_dapm_context *dapm = 213 struct snd_soc_dapm_context *dapm =
214 container_of(work, struct snd_soc_dapm_context, delayed_work.work); 214 container_of(work, struct snd_soc_dapm_context, delayed_work.work);
215 struct snd_soc_codec *codec = dapm->codec; 215 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
216 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); 216 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
217 struct wm8350_output *out1 = &wm8350_data->out1, 217 struct wm8350_output *out1 = &wm8350_data->out1,
218 *out2 = &wm8350_data->out2; 218 *out2 = &wm8350_data->out2;
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index e54e097f4fcb..21ca3a94fc96 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1433,7 +1433,7 @@ static void wm8753_work(struct work_struct *work)
1433 struct snd_soc_dapm_context *dapm = 1433 struct snd_soc_dapm_context *dapm =
1434 container_of(work, struct snd_soc_dapm_context, 1434 container_of(work, struct snd_soc_dapm_context,
1435 delayed_work.work); 1435 delayed_work.work);
1436 struct snd_soc_codec *codec = dapm->codec; 1436 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
1437 wm8753_set_bias_level(codec, dapm->bias_level); 1437 wm8753_set_bias_level(codec, dapm->bias_level);
1438} 1438}
1439 1439
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 0499cd4cfb71..39ddb9b8834c 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -615,7 +615,7 @@ static void wm8971_work(struct work_struct *work)
615 struct snd_soc_dapm_context *dapm = 615 struct snd_soc_dapm_context *dapm =
616 container_of(work, struct snd_soc_dapm_context, 616 container_of(work, struct snd_soc_dapm_context,
617 delayed_work.work); 617 delayed_work.work);
618 struct snd_soc_codec *codec = dapm->codec; 618 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
619 wm8971_set_bias_level(codec, codec->dapm.bias_level); 619 wm8971_set_bias_level(codec, codec->dapm.bias_level);
620} 620}
621 621
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile
index 7acbfc43a0c6..f841786dad15 100644
--- a/sound/soc/intel/Makefile
+++ b/sound/soc/intel/Makefile
@@ -2,7 +2,8 @@
2snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o 2snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o
3snd-soc-sst-acpi-objs := sst-acpi.o 3snd-soc-sst-acpi-objs := sst-acpi.o
4 4
5snd-soc-sst-mfld-platform-objs := sst-mfld-platform-pcm.o sst-mfld-platform-compress.o 5snd-soc-sst-mfld-platform-objs := sst-mfld-platform-pcm.o \
6 sst-mfld-platform-compress.o sst-atom-controls.o
6snd-soc-mfld-machine-objs := mfld_machine.o 7snd-soc-mfld-machine-objs := mfld_machine.o
7 8
8obj-$(CONFIG_SND_SST_MFLD_PLATFORM) += snd-soc-sst-mfld-platform.o 9obj-$(CONFIG_SND_SST_MFLD_PLATFORM) += snd-soc-sst-mfld-platform.o
diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c
new file mode 100644
index 000000000000..ace3c4a59b14
--- /dev/null
+++ b/sound/soc/intel/sst-atom-controls.c
@@ -0,0 +1,39 @@
1/*
2 * sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld
3 *
4 * Copyright (C) 2013-14 Intel Corp
5 * Author: Omair Mohammed Abdullah <omair.m.abdullah@intel.com>
6 * Vinod Koul <vinod.koul@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 */
20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21
22#include <linux/slab.h>
23#include <sound/soc.h>
24#include <sound/tlv.h>
25#include "sst-mfld-platform.h"
26#include "sst-atom-controls.h"
27
28int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform)
29{
30 int ret = 0;
31 struct sst_data *drv = snd_soc_platform_get_drvdata(platform);
32
33 drv->byte_stream = devm_kzalloc(platform->dev,
34 SST_MAX_BIN_BYTES, GFP_KERNEL);
35 if (!drv->byte_stream)
36 return -ENOMEM;
37
38 return ret;
39}
diff --git a/sound/soc/intel/sst-atom-controls.h b/sound/soc/intel/sst-atom-controls.h
index 14063ab8c7c5..8554889c0694 100644
--- a/sound/soc/intel/sst-atom-controls.h
+++ b/sound/soc/intel/sst-atom-controls.h
@@ -1,4 +1,6 @@
1/* 1/*
2 * sst-atom-controls.h - Intel MID Platform driver header file
3 *
2 * Copyright (C) 2013-14 Intel Corp 4 * Copyright (C) 2013-14 Intel Corp
3 * Author: Ramesh Babu <ramesh.babu.koul@intel.com> 5 * Author: Ramesh Babu <ramesh.babu.koul@intel.com>
4 * Omair M Abdullah <omair.m.abdullah@intel.com> 6 * Omair M Abdullah <omair.m.abdullah@intel.com>
@@ -18,13 +20,293 @@
18 * 20 *
19 */ 21 */
20 22
21#ifndef __SST_CONTROLS_V2_H__ 23#ifndef __SST_ATOM_CONTROLS_H__
22#define __SST_CONTROLS_V2_H__ 24#define __SST_ATOM_CONTROLS_H__
23 25
24enum { 26enum {
25 MERR_DPCM_AUDIO = 0, 27 MERR_DPCM_AUDIO = 0,
26 MERR_DPCM_COMPR, 28 MERR_DPCM_COMPR,
27}; 29};
28 30
31/* define a bit for each mixer input */
32#define SST_MIX_IP(x) (x)
33
34#define SST_IP_CODEC0 SST_MIX_IP(2)
35#define SST_IP_CODEC1 SST_MIX_IP(3)
36#define SST_IP_LOOP0 SST_MIX_IP(4)
37#define SST_IP_LOOP1 SST_MIX_IP(5)
38#define SST_IP_LOOP2 SST_MIX_IP(6)
39#define SST_IP_PROBE SST_MIX_IP(7)
40#define SST_IP_VOIP SST_MIX_IP(12)
41#define SST_IP_PCM0 SST_MIX_IP(13)
42#define SST_IP_PCM1 SST_MIX_IP(14)
43#define SST_IP_MEDIA0 SST_MIX_IP(17)
44#define SST_IP_MEDIA1 SST_MIX_IP(18)
45#define SST_IP_MEDIA2 SST_MIX_IP(19)
46#define SST_IP_MEDIA3 SST_MIX_IP(20)
47
48#define SST_IP_LAST SST_IP_MEDIA3
49
50#define SST_SWM_INPUT_COUNT (SST_IP_LAST + 1)
51#define SST_CMD_SWM_MAX_INPUTS 6
52
53#define SST_PATH_ID_SHIFT 8
54#define SST_DEFAULT_LOCATION_ID 0xFFFF
55#define SST_DEFAULT_CELL_NBR 0xFF
56#define SST_DEFAULT_MODULE_ID 0xFFFF
57
58/*
59 * Audio DSP Path Ids. Specified by the audio DSP FW
60 */
61enum sst_path_index {
62 SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT),
63 SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT),
64
65 SST_PATH_INDEX_SPROT_LOOP_OUT = (0x04 << SST_PATH_ID_SHIFT),
66 SST_PATH_INDEX_MEDIA_LOOP1_OUT = (0x05 << SST_PATH_ID_SHIFT),
67 SST_PATH_INDEX_MEDIA_LOOP2_OUT = (0x06 << SST_PATH_ID_SHIFT),
68
69 SST_PATH_INDEX_VOIP_OUT = (0x0C << SST_PATH_ID_SHIFT),
70 SST_PATH_INDEX_PCM0_OUT = (0x0D << SST_PATH_ID_SHIFT),
71 SST_PATH_INDEX_PCM1_OUT = (0x0E << SST_PATH_ID_SHIFT),
72 SST_PATH_INDEX_PCM2_OUT = (0x0F << SST_PATH_ID_SHIFT),
73
74 SST_PATH_INDEX_MEDIA0_OUT = (0x12 << SST_PATH_ID_SHIFT),
75 SST_PATH_INDEX_MEDIA1_OUT = (0x13 << SST_PATH_ID_SHIFT),
76
77
78 /* Start of input paths */
79 SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT),
80 SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT),
81
82 SST_PATH_INDEX_SPROT_LOOP_IN = (0x84 << SST_PATH_ID_SHIFT),
83 SST_PATH_INDEX_MEDIA_LOOP1_IN = (0x85 << SST_PATH_ID_SHIFT),
84 SST_PATH_INDEX_MEDIA_LOOP2_IN = (0x86 << SST_PATH_ID_SHIFT),
85
86 SST_PATH_INDEX_VOIP_IN = (0x8C << SST_PATH_ID_SHIFT),
87
88 SST_PATH_INDEX_PCM0_IN = (0x8D << SST_PATH_ID_SHIFT),
89 SST_PATH_INDEX_PCM1_IN = (0x8E << SST_PATH_ID_SHIFT),
90
91 SST_PATH_INDEX_MEDIA0_IN = (0x8F << SST_PATH_ID_SHIFT),
92 SST_PATH_INDEX_MEDIA1_IN = (0x90 << SST_PATH_ID_SHIFT),
93 SST_PATH_INDEX_MEDIA2_IN = (0x91 << SST_PATH_ID_SHIFT),
94
95 SST_PATH_INDEX_MEDIA3_IN = (0x9C << SST_PATH_ID_SHIFT),
96
97 SST_PATH_INDEX_RESERVED = (0xFF << SST_PATH_ID_SHIFT),
98};
99
100/*
101 * path IDs
102 */
103enum sst_swm_inputs {
104 SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR),
105 SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR),
106 SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR),
107 SST_SWM_IN_MEDIA_LOOP1 = (SST_PATH_INDEX_MEDIA_LOOP1_IN | SST_DEFAULT_CELL_NBR),
108 SST_SWM_IN_MEDIA_LOOP2 = (SST_PATH_INDEX_MEDIA_LOOP2_IN | SST_DEFAULT_CELL_NBR),
109 SST_SWM_IN_VOIP = (SST_PATH_INDEX_VOIP_IN | SST_DEFAULT_CELL_NBR),
110 SST_SWM_IN_PCM0 = (SST_PATH_INDEX_PCM0_IN | SST_DEFAULT_CELL_NBR),
111 SST_SWM_IN_PCM1 = (SST_PATH_INDEX_PCM1_IN | SST_DEFAULT_CELL_NBR),
112 SST_SWM_IN_MEDIA0 = (SST_PATH_INDEX_MEDIA0_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
113 SST_SWM_IN_MEDIA1 = (SST_PATH_INDEX_MEDIA1_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
114 SST_SWM_IN_MEDIA2 = (SST_PATH_INDEX_MEDIA2_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
115 SST_SWM_IN_MEDIA3 = (SST_PATH_INDEX_MEDIA3_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
116 SST_SWM_IN_END = (SST_PATH_INDEX_RESERVED | SST_DEFAULT_CELL_NBR)
117};
118
119/*
120 * path IDs
121 */
122enum sst_swm_outputs {
123 SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR),
124 SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR),
125 SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR),
126 SST_SWM_OUT_MEDIA_LOOP1 = (SST_PATH_INDEX_MEDIA_LOOP1_OUT | SST_DEFAULT_CELL_NBR),
127 SST_SWM_OUT_MEDIA_LOOP2 = (SST_PATH_INDEX_MEDIA_LOOP2_OUT | SST_DEFAULT_CELL_NBR),
128 SST_SWM_OUT_VOIP = (SST_PATH_INDEX_VOIP_OUT | SST_DEFAULT_CELL_NBR),
129 SST_SWM_OUT_PCM0 = (SST_PATH_INDEX_PCM0_OUT | SST_DEFAULT_CELL_NBR),
130 SST_SWM_OUT_PCM1 = (SST_PATH_INDEX_PCM1_OUT | SST_DEFAULT_CELL_NBR),
131 SST_SWM_OUT_PCM2 = (SST_PATH_INDEX_PCM2_OUT | SST_DEFAULT_CELL_NBR),
132 SST_SWM_OUT_MEDIA0 = (SST_PATH_INDEX_MEDIA0_OUT | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
133 SST_SWM_OUT_MEDIA1 = (SST_PATH_INDEX_MEDIA1_OUT | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
134 SST_SWM_OUT_END = (SST_PATH_INDEX_RESERVED | SST_DEFAULT_CELL_NBR),
135};
136
137enum sst_ipc_msg {
138 SST_IPC_IA_CMD = 1,
139 SST_IPC_IA_SET_PARAMS,
140 SST_IPC_IA_GET_PARAMS,
141};
142
143enum sst_cmd_type {
144 SST_CMD_BYTES_SET = 1,
145 SST_CMD_BYTES_GET = 2,
146};
147
148enum sst_task {
149 SST_TASK_SBA = 1,
150 SST_TASK_MMX,
151};
152
153enum sst_type {
154 SST_TYPE_CMD = 1,
155 SST_TYPE_PARAMS,
156};
157
158enum sst_flag {
159 SST_FLAG_BLOCKED = 1,
160 SST_FLAG_NONBLOCK,
161};
162
163/*
164 * Enumeration for indexing the gain cells in VB_SET_GAIN DSP command
165 */
166enum sst_gain_index {
167 /* GAIN IDs for SB task start here */
168 SST_GAIN_INDEX_CODEC_OUT0,
169 SST_GAIN_INDEX_CODEC_OUT1,
170 SST_GAIN_INDEX_CODEC_IN0,
171 SST_GAIN_INDEX_CODEC_IN1,
172
173 SST_GAIN_INDEX_SPROT_LOOP_OUT,
174 SST_GAIN_INDEX_MEDIA_LOOP1_OUT,
175 SST_GAIN_INDEX_MEDIA_LOOP2_OUT,
176
177 SST_GAIN_INDEX_PCM0_IN_LEFT,
178 SST_GAIN_INDEX_PCM0_IN_RIGHT,
179
180 SST_GAIN_INDEX_PCM1_OUT_LEFT,
181 SST_GAIN_INDEX_PCM1_OUT_RIGHT,
182 SST_GAIN_INDEX_PCM1_IN_LEFT,
183 SST_GAIN_INDEX_PCM1_IN_RIGHT,
184 SST_GAIN_INDEX_PCM2_OUT_LEFT,
185
186 SST_GAIN_INDEX_PCM2_OUT_RIGHT,
187 SST_GAIN_INDEX_VOIP_OUT,
188 SST_GAIN_INDEX_VOIP_IN,
189
190 /* Gain IDs for MMX task start here */
191 SST_GAIN_INDEX_MEDIA0_IN_LEFT,
192 SST_GAIN_INDEX_MEDIA0_IN_RIGHT,
193 SST_GAIN_INDEX_MEDIA1_IN_LEFT,
194 SST_GAIN_INDEX_MEDIA1_IN_RIGHT,
195
196 SST_GAIN_INDEX_MEDIA2_IN_LEFT,
197 SST_GAIN_INDEX_MEDIA2_IN_RIGHT,
198
199 SST_GAIN_INDEX_GAIN_END
200};
201
202/*
203 * Audio DSP module IDs specified by FW spec
204 * TODO: Update with all modules
205 */
206enum sst_module_id {
207 SST_MODULE_ID_PCM = 0x0001,
208 SST_MODULE_ID_MP3 = 0x0002,
209 SST_MODULE_ID_MP24 = 0x0003,
210 SST_MODULE_ID_AAC = 0x0004,
211 SST_MODULE_ID_AACP = 0x0005,
212 SST_MODULE_ID_EAACP = 0x0006,
213 SST_MODULE_ID_WMA9 = 0x0007,
214 SST_MODULE_ID_WMA10 = 0x0008,
215 SST_MODULE_ID_WMA10P = 0x0009,
216 SST_MODULE_ID_RA = 0x000A,
217 SST_MODULE_ID_DDAC3 = 0x000B,
218 SST_MODULE_ID_TRUE_HD = 0x000C,
219 SST_MODULE_ID_HD_PLUS = 0x000D,
220
221 SST_MODULE_ID_SRC = 0x0064,
222 SST_MODULE_ID_DOWNMIX = 0x0066,
223 SST_MODULE_ID_GAIN_CELL = 0x0067,
224 SST_MODULE_ID_SPROT = 0x006D,
225 SST_MODULE_ID_BASS_BOOST = 0x006E,
226 SST_MODULE_ID_STEREO_WDNG = 0x006F,
227 SST_MODULE_ID_AV_REMOVAL = 0x0070,
228 SST_MODULE_ID_MIC_EQ = 0x0071,
229 SST_MODULE_ID_SPL = 0x0072,
230 SST_MODULE_ID_ALGO_VTSV = 0x0073,
231 SST_MODULE_ID_NR = 0x0076,
232 SST_MODULE_ID_BWX = 0x0077,
233 SST_MODULE_ID_DRP = 0x0078,
234 SST_MODULE_ID_MDRP = 0x0079,
235
236 SST_MODULE_ID_ANA = 0x007A,
237 SST_MODULE_ID_AEC = 0x007B,
238 SST_MODULE_ID_NR_SNS = 0x007C,
239 SST_MODULE_ID_SER = 0x007D,
240 SST_MODULE_ID_AGC = 0x007E,
241
242 SST_MODULE_ID_CNI = 0x007F,
243 SST_MODULE_ID_CONTEXT_ALGO_AWARE = 0x0080,
244 SST_MODULE_ID_FIR_24 = 0x0081,
245 SST_MODULE_ID_IIR_24 = 0x0082,
246
247 SST_MODULE_ID_ASRC = 0x0083,
248 SST_MODULE_ID_TONE_GEN = 0x0084,
249 SST_MODULE_ID_BMF = 0x0086,
250 SST_MODULE_ID_EDL = 0x0087,
251 SST_MODULE_ID_GLC = 0x0088,
252
253 SST_MODULE_ID_FIR_16 = 0x0089,
254 SST_MODULE_ID_IIR_16 = 0x008A,
255 SST_MODULE_ID_DNR = 0x008B,
256
257 SST_MODULE_ID_VIRTUALIZER = 0x008C,
258 SST_MODULE_ID_VISUALIZATION = 0x008D,
259 SST_MODULE_ID_LOUDNESS_OPTIMIZER = 0x008E,
260 SST_MODULE_ID_REVERBERATION = 0x008F,
261
262 SST_MODULE_ID_CNI_TX = 0x0090,
263 SST_MODULE_ID_REF_LINE = 0x0091,
264 SST_MODULE_ID_VOLUME = 0x0092,
265 SST_MODULE_ID_FILT_DCR = 0x0094,
266 SST_MODULE_ID_SLV = 0x009A,
267 SST_MODULE_ID_NLF = 0x009B,
268 SST_MODULE_ID_TNR = 0x009C,
269 SST_MODULE_ID_WNR = 0x009D,
270
271 SST_MODULE_ID_LOG = 0xFF00,
272
273 SST_MODULE_ID_TASK = 0xFFFF,
274};
275
276enum sst_cmd {
277 SBA_IDLE = 14,
278 SBA_VB_SET_SPEECH_PATH = 26,
279 MMX_SET_GAIN = 33,
280 SBA_VB_SET_GAIN = 33,
281 FBA_VB_RX_CNI = 35,
282 MMX_SET_GAIN_TIMECONST = 36,
283 SBA_VB_SET_TIMECONST = 36,
284 SBA_VB_START = 85,
285 SBA_SET_SWM = 114,
286 SBA_SET_MDRP = 116,
287 SBA_HW_SET_SSP = 117,
288 SBA_SET_MEDIA_LOOP_MAP = 118,
289 SBA_SET_MEDIA_PATH = 119,
290 MMX_SET_MEDIA_PATH = 119,
291 SBA_VB_LPRO = 126,
292 SBA_VB_SET_FIR = 128,
293 SBA_VB_SET_IIR = 129,
294 SBA_SET_SSP_SLOT_MAP = 130,
295};
296
297enum sst_dsp_switch {
298 SST_SWITCH_OFF = 0,
299 SST_SWITCH_ON = 3,
300};
301
302enum sst_path_switch {
303 SST_PATH_OFF = 0,
304 SST_PATH_ON = 1,
305};
306
307enum sst_swm_state {
308 SST_SWM_OFF = 0,
309 SST_SWM_ON = 3,
310};
29 311
30#endif 312#endif
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c
index 61bf6da4bb02..33fc5c3abf55 100644
--- a/sound/soc/intel/sst-haswell-pcm.c
+++ b/sound/soc/intel/sst-haswell-pcm.c
@@ -138,11 +138,10 @@ static inline unsigned int hsw_ipc_to_mixer(u32 value)
138static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, 138static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
139 struct snd_ctl_elem_value *ucontrol) 139 struct snd_ctl_elem_value *ucontrol)
140{ 140{
141 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); 141 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
142 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
142 struct soc_mixer_control *mc = 143 struct soc_mixer_control *mc =
143 (struct soc_mixer_control *)kcontrol->private_value; 144 (struct soc_mixer_control *)kcontrol->private_value;
144 struct hsw_priv_data *pdata =
145 snd_soc_platform_get_drvdata(platform);
146 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; 145 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
147 struct sst_hsw *hsw = pdata->hsw; 146 struct sst_hsw *hsw = pdata->hsw;
148 u32 volume; 147 u32 volume;
@@ -176,11 +175,10 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
176static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, 175static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
177 struct snd_ctl_elem_value *ucontrol) 176 struct snd_ctl_elem_value *ucontrol)
178{ 177{
179 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); 178 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
179 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
180 struct soc_mixer_control *mc = 180 struct soc_mixer_control *mc =
181 (struct soc_mixer_control *)kcontrol->private_value; 181 (struct soc_mixer_control *)kcontrol->private_value;
182 struct hsw_priv_data *pdata =
183 snd_soc_platform_get_drvdata(platform);
184 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; 182 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
185 struct sst_hsw *hsw = pdata->hsw; 183 struct sst_hsw *hsw = pdata->hsw;
186 u32 volume; 184 u32 volume;
@@ -208,8 +206,8 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
208static int hsw_volume_put(struct snd_kcontrol *kcontrol, 206static int hsw_volume_put(struct snd_kcontrol *kcontrol,
209 struct snd_ctl_elem_value *ucontrol) 207 struct snd_ctl_elem_value *ucontrol)
210{ 208{
211 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); 209 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
212 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); 210 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
213 struct sst_hsw *hsw = pdata->hsw; 211 struct sst_hsw *hsw = pdata->hsw;
214 u32 volume; 212 u32 volume;
215 213
@@ -233,8 +231,8 @@ static int hsw_volume_put(struct snd_kcontrol *kcontrol,
233static int hsw_volume_get(struct snd_kcontrol *kcontrol, 231static int hsw_volume_get(struct snd_kcontrol *kcontrol,
234 struct snd_ctl_elem_value *ucontrol) 232 struct snd_ctl_elem_value *ucontrol)
235{ 233{
236 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); 234 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
237 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); 235 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
238 struct sst_hsw *hsw = pdata->hsw; 236 struct sst_hsw *hsw = pdata->hsw;
239 unsigned int volume = 0; 237 unsigned int volume = 0;
240 238
@@ -778,20 +776,11 @@ static const struct snd_soc_dapm_route graph[] = {
778 776
779static int hsw_pcm_probe(struct snd_soc_platform *platform) 777static int hsw_pcm_probe(struct snd_soc_platform *platform)
780{ 778{
779 struct hsw_priv_data *priv_data = snd_soc_platform_get_drvdata(platform);
781 struct sst_pdata *pdata = dev_get_platdata(platform->dev); 780 struct sst_pdata *pdata = dev_get_platdata(platform->dev);
782 struct hsw_priv_data *priv_data; 781 struct device *dma_dev = pdata->dma_dev;
783 struct device *dma_dev;
784 int i, ret = 0; 782 int i, ret = 0;
785 783
786 if (!pdata)
787 return -ENODEV;
788
789 dma_dev = pdata->dma_dev;
790
791 priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data), GFP_KERNEL);
792 priv_data->hsw = pdata->dsp;
793 snd_soc_platform_set_drvdata(platform, priv_data);
794
795 /* allocate DSP buffer page tables */ 784 /* allocate DSP buffer page tables */
796 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { 785 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
797 786
@@ -848,27 +837,38 @@ static struct snd_soc_platform_driver hsw_soc_platform = {
848 .ops = &hsw_pcm_ops, 837 .ops = &hsw_pcm_ops,
849 .pcm_new = hsw_pcm_new, 838 .pcm_new = hsw_pcm_new,
850 .pcm_free = hsw_pcm_free, 839 .pcm_free = hsw_pcm_free,
851 .controls = hsw_volume_controls,
852 .num_controls = ARRAY_SIZE(hsw_volume_controls),
853 .dapm_widgets = widgets,
854 .num_dapm_widgets = ARRAY_SIZE(widgets),
855 .dapm_routes = graph,
856 .num_dapm_routes = ARRAY_SIZE(graph),
857}; 840};
858 841
859static const struct snd_soc_component_driver hsw_dai_component = { 842static const struct snd_soc_component_driver hsw_dai_component = {
860 .name = "haswell-dai", 843 .name = "haswell-dai",
844 .controls = hsw_volume_controls,
845 .num_controls = ARRAY_SIZE(hsw_volume_controls),
846 .dapm_widgets = widgets,
847 .num_dapm_widgets = ARRAY_SIZE(widgets),
848 .dapm_routes = graph,
849 .num_dapm_routes = ARRAY_SIZE(graph),
861}; 850};
862 851
863static int hsw_pcm_dev_probe(struct platform_device *pdev) 852static int hsw_pcm_dev_probe(struct platform_device *pdev)
864{ 853{
865 struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev); 854 struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
855 struct hsw_priv_data *priv_data;
866 int ret; 856 int ret;
867 857
858 if (!sst_pdata)
859 return -EINVAL;
860
861 priv_data = devm_kzalloc(&pdev->dev, sizeof(*priv_data), GFP_KERNEL);
862 if (!priv_data)
863 return -ENOMEM;
864
868 ret = sst_hsw_dsp_init(&pdev->dev, sst_pdata); 865 ret = sst_hsw_dsp_init(&pdev->dev, sst_pdata);
869 if (ret < 0) 866 if (ret < 0)
870 return -ENODEV; 867 return -ENODEV;
871 868
869 priv_data->hsw = sst_pdata->dsp;
870 platform_set_drvdata(pdev, priv_data);
871
872 ret = snd_soc_register_platform(&pdev->dev, &hsw_soc_platform); 872 ret = snd_soc_register_platform(&pdev->dev, &hsw_soc_platform);
873 if (ret < 0) 873 if (ret < 0)
874 goto err_plat; 874 goto err_plat;
diff --git a/sound/soc/intel/sst-mfld-platform-compress.c b/sound/soc/intel/sst-mfld-platform-compress.c
index 29c059ca19e8..59467775c9b8 100644
--- a/sound/soc/intel/sst-mfld-platform-compress.c
+++ b/sound/soc/intel/sst-mfld-platform-compress.c
@@ -86,7 +86,7 @@ static int sst_platform_compr_free(struct snd_compr_stream *cstream)
86 /*need to check*/ 86 /*need to check*/
87 str_id = stream->id; 87 str_id = stream->id;
88 if (str_id) 88 if (str_id)
89 ret_val = stream->compr_ops->close(str_id); 89 ret_val = stream->compr_ops->close(sst->dev, str_id);
90 module_put(sst->dev->driver->owner); 90 module_put(sst->dev->driver->owner);
91 kfree(stream); 91 kfree(stream);
92 pr_debug("%s: %d\n", __func__, ret_val); 92 pr_debug("%s: %d\n", __func__, ret_val);
@@ -158,7 +158,7 @@ static int sst_platform_compr_set_params(struct snd_compr_stream *cstream,
158 cb.drain_cb_param = cstream; 158 cb.drain_cb_param = cstream;
159 cb.drain_notify = sst_drain_notify; 159 cb.drain_notify = sst_drain_notify;
160 160
161 retval = stream->compr_ops->open(&str_params, &cb); 161 retval = stream->compr_ops->open(sst->dev, &str_params, &cb);
162 if (retval < 0) { 162 if (retval < 0) {
163 pr_err("stream allocation failed %d\n", retval); 163 pr_err("stream allocation failed %d\n", retval);
164 return retval; 164 return retval;
@@ -170,10 +170,30 @@ static int sst_platform_compr_set_params(struct snd_compr_stream *cstream,
170 170
171static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd) 171static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd)
172{ 172{
173 struct sst_runtime_stream *stream = 173 struct sst_runtime_stream *stream = cstream->runtime->private_data;
174 cstream->runtime->private_data; 174
175 175 switch (cmd) {
176 return stream->compr_ops->control(cmd, stream->id); 176 case SNDRV_PCM_TRIGGER_START:
177 if (stream->compr_ops->stream_start)
178 return stream->compr_ops->stream_start(sst->dev, stream->id);
179 case SNDRV_PCM_TRIGGER_STOP:
180 if (stream->compr_ops->stream_drop)
181 return stream->compr_ops->stream_drop(sst->dev, stream->id);
182 case SND_COMPR_TRIGGER_DRAIN:
183 if (stream->compr_ops->stream_drain)
184 return stream->compr_ops->stream_drain(sst->dev, stream->id);
185 case SND_COMPR_TRIGGER_PARTIAL_DRAIN:
186 if (stream->compr_ops->stream_partial_drain)
187 return stream->compr_ops->stream_partial_drain(sst->dev, stream->id);
188 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
189 if (stream->compr_ops->stream_pause)
190 return stream->compr_ops->stream_pause(sst->dev, stream->id);
191 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
192 if (stream->compr_ops->stream_pause_release)
193 return stream->compr_ops->stream_pause_release(sst->dev, stream->id);
194 default:
195 return -EINVAL;
196 }
177} 197}
178 198
179static int sst_platform_compr_pointer(struct snd_compr_stream *cstream, 199static int sst_platform_compr_pointer(struct snd_compr_stream *cstream,
@@ -182,7 +202,7 @@ static int sst_platform_compr_pointer(struct snd_compr_stream *cstream,
182 struct sst_runtime_stream *stream; 202 struct sst_runtime_stream *stream;
183 203
184 stream = cstream->runtime->private_data; 204 stream = cstream->runtime->private_data;
185 stream->compr_ops->tstamp(stream->id, tstamp); 205 stream->compr_ops->tstamp(sst->dev, stream->id, tstamp);
186 tstamp->byte_offset = tstamp->copied_total % 206 tstamp->byte_offset = tstamp->copied_total %
187 (u32)cstream->runtime->buffer_size; 207 (u32)cstream->runtime->buffer_size;
188 pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset); 208 pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset);
@@ -195,7 +215,7 @@ static int sst_platform_compr_ack(struct snd_compr_stream *cstream,
195 struct sst_runtime_stream *stream; 215 struct sst_runtime_stream *stream;
196 216
197 stream = cstream->runtime->private_data; 217 stream = cstream->runtime->private_data;
198 stream->compr_ops->ack(stream->id, (unsigned long)bytes); 218 stream->compr_ops->ack(sst->dev, stream->id, (unsigned long)bytes);
199 stream->bytes_written += bytes; 219 stream->bytes_written += bytes;
200 220
201 return 0; 221 return 0;
@@ -225,7 +245,7 @@ static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream,
225 struct sst_runtime_stream *stream = 245 struct sst_runtime_stream *stream =
226 cstream->runtime->private_data; 246 cstream->runtime->private_data;
227 247
228 return stream->compr_ops->set_metadata(stream->id, metadata); 248 return stream->compr_ops->set_metadata(sst->dev, stream->id, metadata);
229} 249}
230 250
231struct snd_compr_ops sst_platform_compr_ops = { 251struct snd_compr_ops sst_platform_compr_ops = {
diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c
index 706212a6a68c..8e1e9bc27642 100644
--- a/sound/soc/intel/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/sst-mfld-platform-pcm.c
@@ -277,7 +277,7 @@ static int sst_platform_alloc_stream(struct snd_pcm_substream *substream,
277 277
278 stream->stream_info.str_id = str_params.stream_id; 278 stream->stream_info.str_id = str_params.stream_id;
279 279
280 ret_val = stream->ops->open(&str_params); 280 ret_val = stream->ops->open(sst->dev, &str_params);
281 if (ret_val <= 0) 281 if (ret_val <= 0)
282 return ret_val; 282 return ret_val;
283 283
@@ -314,14 +314,12 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream)
314 stream->stream_info.arg = substream; 314 stream->stream_info.arg = substream;
315 stream->stream_info.buffer_ptr = 0; 315 stream->stream_info.buffer_ptr = 0;
316 stream->stream_info.sfreq = substream->runtime->rate; 316 stream->stream_info.sfreq = substream->runtime->rate;
317 ret_val = stream->ops->device_control( 317 ret_val = stream->ops->stream_init(sst->dev, &stream->stream_info);
318 SST_SND_STREAM_INIT, &stream->stream_info);
319 if (ret_val) 318 if (ret_val)
320 pr_err("control_set ret error %d\n", ret_val); 319 pr_err("control_set ret error %d\n", ret_val);
321 return ret_val; 320 return ret_val;
322 321
323} 322}
324/* end -- helper functions */
325 323
326static int sst_media_open(struct snd_pcm_substream *substream, 324static int sst_media_open(struct snd_pcm_substream *substream,
327 struct snd_soc_dai *dai) 325 struct snd_soc_dai *dai)
@@ -373,7 +371,7 @@ static void sst_media_close(struct snd_pcm_substream *substream,
373 stream = substream->runtime->private_data; 371 stream = substream->runtime->private_data;
374 str_id = stream->stream_info.str_id; 372 str_id = stream->stream_info.str_id;
375 if (str_id) 373 if (str_id)
376 ret_val = stream->ops->close(str_id); 374 ret_val = stream->ops->close(sst->dev, str_id);
377 module_put(sst->dev->driver->owner); 375 module_put(sst->dev->driver->owner);
378 kfree(stream); 376 kfree(stream);
379} 377}
@@ -403,8 +401,7 @@ static int sst_media_prepare(struct snd_pcm_substream *substream,
403 stream = substream->runtime->private_data; 401 stream = substream->runtime->private_data;
404 str_id = stream->stream_info.str_id; 402 str_id = stream->stream_info.str_id;
405 if (stream->stream_info.str_id) { 403 if (stream->stream_info.str_id) {
406 ret_val = stream->ops->device_control( 404 ret_val = stream->ops->stream_drop(sst->dev, str_id);
407 SST_SND_DROP, &str_id);
408 return ret_val; 405 return ret_val;
409 } 406 }
410 407
@@ -461,7 +458,7 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
461{ 458{
462 int ret_val = 0, str_id; 459 int ret_val = 0, str_id;
463 struct sst_runtime_stream *stream; 460 struct sst_runtime_stream *stream;
464 int str_cmd, status; 461 int status;
465 462
466 pr_debug("sst_platform_pcm_trigger called\n"); 463 pr_debug("sst_platform_pcm_trigger called\n");
467 stream = substream->runtime->private_data; 464 stream = substream->runtime->private_data;
@@ -469,29 +466,29 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
469 switch (cmd) { 466 switch (cmd) {
470 case SNDRV_PCM_TRIGGER_START: 467 case SNDRV_PCM_TRIGGER_START:
471 pr_debug("sst: Trigger Start\n"); 468 pr_debug("sst: Trigger Start\n");
472 str_cmd = SST_SND_START;
473 status = SST_PLATFORM_RUNNING; 469 status = SST_PLATFORM_RUNNING;
474 stream->stream_info.arg = substream; 470 stream->stream_info.arg = substream;
471 ret_val = stream->ops->stream_start(sst->dev, str_id);
475 break; 472 break;
476 case SNDRV_PCM_TRIGGER_STOP: 473 case SNDRV_PCM_TRIGGER_STOP:
477 pr_debug("sst: in stop\n"); 474 pr_debug("sst: in stop\n");
478 str_cmd = SST_SND_DROP;
479 status = SST_PLATFORM_DROPPED; 475 status = SST_PLATFORM_DROPPED;
476 ret_val = stream->ops->stream_drop(sst->dev, str_id);
480 break; 477 break;
481 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 478 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
482 pr_debug("sst: in pause\n"); 479 pr_debug("sst: in pause\n");
483 str_cmd = SST_SND_PAUSE;
484 status = SST_PLATFORM_PAUSED; 480 status = SST_PLATFORM_PAUSED;
481 ret_val = stream->ops->stream_pause(sst->dev, str_id);
485 break; 482 break;
486 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 483 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
487 pr_debug("sst: in pause release\n"); 484 pr_debug("sst: in pause release\n");
488 str_cmd = SST_SND_RESUME;
489 status = SST_PLATFORM_RUNNING; 485 status = SST_PLATFORM_RUNNING;
486 ret_val = stream->ops->stream_pause_release(sst->dev, str_id);
490 break; 487 break;
491 default: 488 default:
492 return -EINVAL; 489 return -EINVAL;
493 } 490 }
494 ret_val = stream->ops->device_control(str_cmd, &str_id); 491
495 if (!ret_val) 492 if (!ret_val)
496 sst_set_stream_status(stream, status); 493 sst_set_stream_status(stream, status);
497 494
@@ -511,8 +508,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer
511 if (status == SST_PLATFORM_INIT) 508 if (status == SST_PLATFORM_INIT)
512 return 0; 509 return 0;
513 str_info = &stream->stream_info; 510 str_info = &stream->stream_info;
514 ret_val = stream->ops->device_control( 511 ret_val = stream->ops->stream_read_tstamp(sst->dev, str_info);
515 SST_SND_BUFFER_POINTER, str_info);
516 if (ret_val) { 512 if (ret_val) {
517 pr_err("sst: error code = %d\n", ret_val); 513 pr_err("sst: error code = %d\n", ret_val);
518 return ret_val; 514 return ret_val;
@@ -554,7 +550,13 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
554 return retval; 550 return retval;
555} 551}
556 552
557static struct snd_soc_platform_driver sst_soc_platform_drv = { 553static int sst_soc_probe(struct snd_soc_platform *platform)
554{
555 return sst_dsp_init_v2_dpcm(platform);
556}
557
558static struct snd_soc_platform_driver sst_soc_platform_drv = {
559 .probe = sst_soc_probe,
558 .ops = &sst_platform_ops, 560 .ops = &sst_platform_ops,
559 .compr_ops = &sst_platform_compr_ops, 561 .compr_ops = &sst_platform_compr_ops,
560 .pcm_new = sst_pcm_new, 562 .pcm_new = sst_pcm_new,
diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/sst-mfld-platform.h
index 6c6a42c08e24..0c5b943daff3 100644
--- a/sound/soc/intel/sst-mfld-platform.h
+++ b/sound/soc/intel/sst-mfld-platform.h
@@ -54,20 +54,6 @@ enum sst_drv_status {
54 SST_PLATFORM_DROPPED, 54 SST_PLATFORM_DROPPED,
55}; 55};
56 56
57enum sst_controls {
58 SST_SND_ALLOC = 0x00,
59 SST_SND_PAUSE = 0x01,
60 SST_SND_RESUME = 0x02,
61 SST_SND_DROP = 0x03,
62 SST_SND_FREE = 0x04,
63 SST_SND_BUFFER_POINTER = 0x05,
64 SST_SND_STREAM_INIT = 0x06,
65 SST_SND_START = 0x07,
66 SST_SET_BYTE_STREAM = 0x100A,
67 SST_GET_BYTE_STREAM = 0x100B,
68 SST_MAX_CONTROLS = SST_GET_BYTE_STREAM,
69};
70
71enum sst_stream_ops { 57enum sst_stream_ops {
72 STREAM_OPS_PLAYBACK = 0, 58 STREAM_OPS_PLAYBACK = 0,
73 STREAM_OPS_CAPTURE, 59 STREAM_OPS_CAPTURE,
@@ -113,24 +99,36 @@ struct sst_compress_cb {
113 99
114struct compress_sst_ops { 100struct compress_sst_ops {
115 const char *name; 101 const char *name;
116 int (*open) (struct snd_sst_params *str_params, 102 int (*open)(struct device *dev,
117 struct sst_compress_cb *cb); 103 struct snd_sst_params *str_params, struct sst_compress_cb *cb);
118 int (*control) (unsigned int cmd, unsigned int str_id); 104 int (*stream_start)(struct device *dev, unsigned int str_id);
119 int (*tstamp) (unsigned int str_id, struct snd_compr_tstamp *tstamp); 105 int (*stream_drop)(struct device *dev, unsigned int str_id);
120 int (*ack) (unsigned int str_id, unsigned long bytes); 106 int (*stream_drain)(struct device *dev, unsigned int str_id);
121 int (*close) (unsigned int str_id); 107 int (*stream_partial_drain)(struct device *dev, unsigned int str_id);
122 int (*get_caps) (struct snd_compr_caps *caps); 108 int (*stream_pause)(struct device *dev, unsigned int str_id);
123 int (*get_codec_caps) (struct snd_compr_codec_caps *codec); 109 int (*stream_pause_release)(struct device *dev, unsigned int str_id);
124 int (*set_metadata) (unsigned int str_id, 110
111 int (*tstamp)(struct device *dev, unsigned int str_id,
112 struct snd_compr_tstamp *tstamp);
113 int (*ack)(struct device *dev, unsigned int str_id,
114 unsigned long bytes);
115 int (*close)(struct device *dev, unsigned int str_id);
116 int (*get_caps)(struct snd_compr_caps *caps);
117 int (*get_codec_caps)(struct snd_compr_codec_caps *codec);
118 int (*set_metadata)(struct device *dev, unsigned int str_id,
125 struct snd_compr_metadata *mdata); 119 struct snd_compr_metadata *mdata);
126
127}; 120};
128 121
129struct sst_ops { 122struct sst_ops {
130 int (*open) (struct snd_sst_params *str_param); 123 int (*open) (struct device *dev, struct snd_sst_params *str_param);
131 int (*device_control) (int cmd, void *arg); 124 int (*stream_init) (struct device *dev, struct pcm_stream_info *str_info);
132 int (*set_generic_params)(enum sst_controls cmd, void *arg); 125 int (*stream_start) (struct device *dev, int str_id);
133 int (*close) (unsigned int str_id); 126 int (*stream_drop) (struct device *dev, int str_id);
127 int (*stream_pause) (struct device *dev, int str_id);
128 int (*stream_pause_release) (struct device *dev, int str_id);
129 int (*stream_read_tstamp) (struct device *dev, struct pcm_stream_info *str_info);
130 int (*send_byte_stream)(struct device *dev, struct snd_sst_bytes_v2 *bytes);
131 int (*close) (struct device *dev, unsigned int str_id);
134}; 132};
135 133
136struct sst_runtime_stream { 134struct sst_runtime_stream {
@@ -152,6 +150,8 @@ struct sst_device {
152}; 150};
153 151
154struct sst_data; 152struct sst_data;
153
154int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform);
155void sst_set_stream_status(struct sst_runtime_stream *stream, int state); 155void sst_set_stream_status(struct sst_runtime_stream *stream, int state);
156int sst_fill_stream_params(void *substream, const struct sst_data *ctx, 156int sst_fill_stream_params(void *substream, const struct sst_data *ctx,
157 struct snd_sst_params *str_params, bool is_compress); 157 struct snd_sst_params *str_params, bool is_compress);
@@ -166,6 +166,7 @@ struct sst_algo_int_control_v2 {
166struct sst_data { 166struct sst_data {
167 struct platform_device *pdev; 167 struct platform_device *pdev;
168 struct sst_platform_data *pdata; 168 struct sst_platform_data *pdata;
169 char *byte_stream;
169 struct mutex lock; 170 struct mutex lock;
170}; 171};
171int sst_register_dsp(struct sst_device *sst); 172int sst_register_dsp(struct sst_device *sst);
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 943922c79f78..b10ae8074461 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -168,7 +168,7 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w,
168static int rx51_hp_event(struct snd_soc_dapm_widget *w, 168static int rx51_hp_event(struct snd_soc_dapm_widget *w,
169 struct snd_kcontrol *k, int event) 169 struct snd_kcontrol *k, int event)
170{ 170{
171 struct snd_soc_codec *codec = w->dapm->codec; 171 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
172 172
173 if (SND_SOC_DAPM_EVENT_ON(event)) 173 if (SND_SOC_DAPM_EVENT_ON(event))
174 tpa6130a2_stereo_enable(codec, 1); 174 tpa6130a2_stereo_enable(codec, 1);
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index 9902efcb8ea1..a05482651aae 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -228,10 +228,12 @@ static struct snd_soc_dai_link speyside_dai[] = {
228 }, 228 },
229}; 229};
230 230
231static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm) 231static int speyside_wm9081_init(struct snd_soc_component *component)
232{ 232{
233 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
234
233 /* At any time the WM9081 is active it will have this clock */ 235 /* At any time the WM9081 is active it will have this clock */
234 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0, 236 return snd_soc_codec_set_sysclk(codec, WM9081_SYSCLK_MCLK, 0,
235 MCLK_AUDIO_RATE, 0); 237 MCLK_AUDIO_RATE, 0);
236} 238}
237 239
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d074aa91b023..c75a27ce7b97 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -270,79 +270,54 @@ static const struct file_operations codec_reg_fops = {
270 .llseek = default_llseek, 270 .llseek = default_llseek,
271}; 271};
272 272
273static struct dentry *soc_debugfs_create_dir(struct dentry *parent, 273static void soc_init_component_debugfs(struct snd_soc_component *component)
274 const char *fmt, ...)
275{ 274{
276 struct dentry *de; 275 if (component->debugfs_prefix) {
277 va_list ap; 276 char *name;
278 char *s;
279 277
280 va_start(ap, fmt); 278 name = kasprintf(GFP_KERNEL, "%s:%s",
281 s = kvasprintf(GFP_KERNEL, fmt, ap); 279 component->debugfs_prefix, component->name);
282 va_end(ap); 280 if (name) {
281 component->debugfs_root = debugfs_create_dir(name,
282 component->card->debugfs_card_root);
283 kfree(name);
284 }
285 } else {
286 component->debugfs_root = debugfs_create_dir(component->name,
287 component->card->debugfs_card_root);
288 }
283 289
284 if (!s) 290 if (!component->debugfs_root) {
285 return NULL; 291 dev_warn(component->dev,
292 "ASoC: Failed to create component debugfs directory\n");
293 return;
294 }
286 295
287 de = debugfs_create_dir(s, parent); 296 snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component),
288 kfree(s); 297 component->debugfs_root);
289 298
290 return de; 299 if (component->init_debugfs)
300 component->init_debugfs(component);
291} 301}
292 302
293static void soc_init_codec_debugfs(struct snd_soc_codec *codec) 303static void soc_cleanup_component_debugfs(struct snd_soc_component *component)
294{ 304{
295 struct dentry *debugfs_card_root = codec->component.card->debugfs_card_root; 305 debugfs_remove_recursive(component->debugfs_root);
306}
296 307
297 codec->debugfs_codec_root = soc_debugfs_create_dir(debugfs_card_root, 308static void soc_init_codec_debugfs(struct snd_soc_component *component)
298 "codec:%s", 309{
299 codec->component.name); 310 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
300 if (!codec->debugfs_codec_root) {
301 dev_warn(codec->dev,
302 "ASoC: Failed to create codec debugfs directory\n");
303 return;
304 }
305 311
306 debugfs_create_bool("cache_sync", 0444, codec->debugfs_codec_root, 312 debugfs_create_bool("cache_sync", 0444, codec->component.debugfs_root,
307 &codec->cache_sync); 313 &codec->cache_sync);
308 debugfs_create_bool("cache_only", 0444, codec->debugfs_codec_root,
309 &codec->cache_only);
310 314
311 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, 315 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
312 codec->debugfs_codec_root, 316 codec->component.debugfs_root,
313 codec, &codec_reg_fops); 317 codec, &codec_reg_fops);
314 if (!codec->debugfs_reg) 318 if (!codec->debugfs_reg)
315 dev_warn(codec->dev, 319 dev_warn(codec->dev,
316 "ASoC: Failed to create codec register debugfs file\n"); 320 "ASoC: Failed to create codec register debugfs file\n");
317
318 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
319}
320
321static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
322{
323 debugfs_remove_recursive(codec->debugfs_codec_root);
324}
325
326static void soc_init_platform_debugfs(struct snd_soc_platform *platform)
327{
328 struct dentry *debugfs_card_root = platform->component.card->debugfs_card_root;
329
330 platform->debugfs_platform_root = soc_debugfs_create_dir(debugfs_card_root,
331 "platform:%s",
332 platform->component.name);
333 if (!platform->debugfs_platform_root) {
334 dev_warn(platform->dev,
335 "ASoC: Failed to create platform debugfs directory\n");
336 return;
337 }
338
339 snd_soc_dapm_debugfs_init(&platform->component.dapm,
340 platform->debugfs_platform_root);
341}
342
343static void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
344{
345 debugfs_remove_recursive(platform->debugfs_platform_root);
346} 321}
347 322
348static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, 323static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
@@ -474,19 +449,15 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
474 449
475#else 450#else
476 451
477static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec) 452#define soc_init_codec_debugfs NULL
478{
479}
480
481static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
482{
483}
484 453
485static inline void soc_init_platform_debugfs(struct snd_soc_platform *platform) 454static inline void soc_init_component_debugfs(
455 struct snd_soc_component *component)
486{ 456{
487} 457}
488 458
489static inline void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform) 459static inline void soc_cleanup_component_debugfs(
460 struct snd_soc_component *component)
490{ 461{
491} 462}
492 463
@@ -579,10 +550,8 @@ int snd_soc_suspend(struct device *dev)
579 struct snd_soc_codec *codec; 550 struct snd_soc_codec *codec;
580 int i, j; 551 int i, j;
581 552
582 /* If the initialization of this soc device failed, there is no codec 553 /* If the card is not initialized yet there is nothing to do */
583 * associated with it. Just bail out in this case. 554 if (!card->instantiated)
584 */
585 if (list_empty(&card->codec_dev_list))
586 return 0; 555 return 0;
587 556
588 /* Due to the resume being scheduled into a workqueue we could 557 /* Due to the resume being scheduled into a workqueue we could
@@ -835,10 +804,8 @@ int snd_soc_resume(struct device *dev)
835 struct snd_soc_card *card = dev_get_drvdata(dev); 804 struct snd_soc_card *card = dev_get_drvdata(dev);
836 int i, ac97_control = 0; 805 int i, ac97_control = 0;
837 806
838 /* If the initialization of this soc device failed, there is no codec 807 /* If the card is not initialized yet there is nothing to do */
839 * associated with it. Just bail out in this case. 808 if (!card->instantiated)
840 */
841 if (list_empty(&card->codec_dev_list))
842 return 0; 809 return 0;
843 810
844 /* activate pins from sleep state */ 811 /* activate pins from sleep state */
@@ -887,35 +854,40 @@ EXPORT_SYMBOL_GPL(snd_soc_resume);
887static const struct snd_soc_dai_ops null_dai_ops = { 854static const struct snd_soc_dai_ops null_dai_ops = {
888}; 855};
889 856
890static struct snd_soc_codec *soc_find_codec( 857static struct snd_soc_component *soc_find_component(
891 const struct device_node *codec_of_node, 858 const struct device_node *of_node, const char *name)
892 const char *codec_name)
893{ 859{
894 struct snd_soc_codec *codec; 860 struct snd_soc_component *component;
895 861
896 list_for_each_entry(codec, &codec_list, list) { 862 list_for_each_entry(component, &component_list, list) {
897 if (codec_of_node) { 863 if (of_node) {
898 if (codec->dev->of_node != codec_of_node) 864 if (component->dev->of_node == of_node)
899 continue; 865 return component;
900 } else { 866 } else if (strcmp(component->name, name) == 0) {
901 if (strcmp(codec->component.name, codec_name)) 867 return component;
902 continue;
903 } 868 }
904
905 return codec;
906 } 869 }
907 870
908 return NULL; 871 return NULL;
909} 872}
910 873
911static struct snd_soc_dai *soc_find_codec_dai(struct snd_soc_codec *codec, 874static struct snd_soc_dai *snd_soc_find_dai(
912 const char *codec_dai_name) 875 const struct snd_soc_dai_link_component *dlc)
913{ 876{
914 struct snd_soc_dai *codec_dai; 877 struct snd_soc_component *component;
878 struct snd_soc_dai *dai;
915 879
916 list_for_each_entry(codec_dai, &codec->component.dai_list, list) { 880 /* Find CPU DAI from registered DAIs*/
917 if (!strcmp(codec_dai->name, codec_dai_name)) { 881 list_for_each_entry(component, &component_list, list) {
918 return codec_dai; 882 if (dlc->of_node && component->dev->of_node != dlc->of_node)
883 continue;
884 if (dlc->name && strcmp(dev_name(component->dev), dlc->name))
885 continue;
886 list_for_each_entry(dai, &component->dai_list, list) {
887 if (dlc->dai_name && strcmp(dai->name, dlc->dai_name))
888 continue;
889
890 return dai;
919 } 891 }
920 } 892 }
921 893
@@ -926,33 +898,19 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
926{ 898{
927 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 899 struct snd_soc_dai_link *dai_link = &card->dai_link[num];
928 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 900 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
929 struct snd_soc_component *component;
930 struct snd_soc_dai_link_component *codecs = dai_link->codecs; 901 struct snd_soc_dai_link_component *codecs = dai_link->codecs;
902 struct snd_soc_dai_link_component cpu_dai_component;
931 struct snd_soc_dai **codec_dais = rtd->codec_dais; 903 struct snd_soc_dai **codec_dais = rtd->codec_dais;
932 struct snd_soc_platform *platform; 904 struct snd_soc_platform *platform;
933 struct snd_soc_dai *cpu_dai;
934 const char *platform_name; 905 const char *platform_name;
935 int i; 906 int i;
936 907
937 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); 908 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num);
938 909
939 /* Find CPU DAI from registered DAIs*/ 910 cpu_dai_component.name = dai_link->cpu_name;
940 list_for_each_entry(component, &component_list, list) { 911 cpu_dai_component.of_node = dai_link->cpu_of_node;
941 if (dai_link->cpu_of_node && 912 cpu_dai_component.dai_name = dai_link->cpu_dai_name;
942 component->dev->of_node != dai_link->cpu_of_node) 913 rtd->cpu_dai = snd_soc_find_dai(&cpu_dai_component);
943 continue;
944 if (dai_link->cpu_name &&
945 strcmp(dev_name(component->dev), dai_link->cpu_name))
946 continue;
947 list_for_each_entry(cpu_dai, &component->dai_list, list) {
948 if (dai_link->cpu_dai_name &&
949 strcmp(cpu_dai->name, dai_link->cpu_dai_name))
950 continue;
951
952 rtd->cpu_dai = cpu_dai;
953 }
954 }
955
956 if (!rtd->cpu_dai) { 914 if (!rtd->cpu_dai) {
957 dev_err(card->dev, "ASoC: CPU DAI %s not registered\n", 915 dev_err(card->dev, "ASoC: CPU DAI %s not registered\n",
958 dai_link->cpu_dai_name); 916 dai_link->cpu_dai_name);
@@ -963,15 +921,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
963 921
964 /* Find CODEC from registered CODECs */ 922 /* Find CODEC from registered CODECs */
965 for (i = 0; i < rtd->num_codecs; i++) { 923 for (i = 0; i < rtd->num_codecs; i++) {
966 struct snd_soc_codec *codec; 924 codec_dais[i] = snd_soc_find_dai(&codecs[i]);
967 codec = soc_find_codec(codecs[i].of_node, codecs[i].name);
968 if (!codec) {
969 dev_err(card->dev, "ASoC: CODEC %s not registered\n",
970 codecs[i].name);
971 return -EPROBE_DEFER;
972 }
973
974 codec_dais[i] = soc_find_codec_dai(codec, codecs[i].dai_name);
975 if (!codec_dais[i]) { 925 if (!codec_dais[i]) {
976 dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", 926 dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n",
977 codecs[i].dai_name); 927 codecs[i].dai_name);
@@ -1012,68 +962,46 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
1012 return 0; 962 return 0;
1013} 963}
1014 964
1015static int soc_remove_platform(struct snd_soc_platform *platform) 965static void soc_remove_component(struct snd_soc_component *component)
1016{ 966{
1017 int ret; 967 if (!component->probed)
1018 968 return;
1019 if (platform->driver->remove) {
1020 ret = platform->driver->remove(platform);
1021 if (ret < 0)
1022 dev_err(platform->dev, "ASoC: failed to remove %d\n",
1023 ret);
1024 }
1025
1026 /* Make sure all DAPM widgets are freed */
1027 snd_soc_dapm_free(&platform->component.dapm);
1028
1029 soc_cleanup_platform_debugfs(platform);
1030 platform->probed = 0;
1031 module_put(platform->dev->driver->owner);
1032
1033 return 0;
1034}
1035 969
1036static void soc_remove_codec(struct snd_soc_codec *codec) 970 /* This is a HACK and will be removed soon */
1037{ 971 if (component->codec)
1038 int err; 972 list_del(&component->codec->card_list);
1039 973
1040 if (codec->driver->remove) { 974 if (component->remove)
1041 err = codec->driver->remove(codec); 975 component->remove(component);
1042 if (err < 0)
1043 dev_err(codec->dev, "ASoC: failed to remove %d\n", err);
1044 }
1045 976
1046 /* Make sure all DAPM widgets are freed */ 977 snd_soc_dapm_free(snd_soc_component_get_dapm(component));
1047 snd_soc_dapm_free(&codec->dapm);
1048 978
1049 soc_cleanup_codec_debugfs(codec); 979 soc_cleanup_component_debugfs(component);
1050 codec->probed = 0; 980 component->probed = 0;
1051 list_del(&codec->card_list); 981 module_put(component->dev->driver->owner);
1052 module_put(codec->dev->driver->owner);
1053} 982}
1054 983
1055static void soc_remove_codec_dai(struct snd_soc_dai *codec_dai, int order) 984static void soc_remove_dai(struct snd_soc_dai *dai, int order)
1056{ 985{
1057 int err; 986 int err;
1058 987
1059 if (codec_dai && codec_dai->probed && 988 if (dai && dai->probed &&
1060 codec_dai->driver->remove_order == order) { 989 dai->driver->remove_order == order) {
1061 if (codec_dai->driver->remove) { 990 if (dai->driver->remove) {
1062 err = codec_dai->driver->remove(codec_dai); 991 err = dai->driver->remove(dai);
1063 if (err < 0) 992 if (err < 0)
1064 dev_err(codec_dai->dev, 993 dev_err(dai->dev,
1065 "ASoC: failed to remove %s: %d\n", 994 "ASoC: failed to remove %s: %d\n",
1066 codec_dai->name, err); 995 dai->name, err);
1067 } 996 }
1068 codec_dai->probed = 0; 997 dai->probed = 0;
1069 } 998 }
1070} 999}
1071 1000
1072static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) 1001static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
1073{ 1002{
1074 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1003 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1075 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1004 int i;
1076 int i, err;
1077 1005
1078 /* unregister the rtd device */ 1006 /* unregister the rtd device */
1079 if (rtd->dev_registered) { 1007 if (rtd->dev_registered) {
@@ -1085,22 +1013,9 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
1085 1013
1086 /* remove the CODEC DAI */ 1014 /* remove the CODEC DAI */
1087 for (i = 0; i < rtd->num_codecs; i++) 1015 for (i = 0; i < rtd->num_codecs; i++)
1088 soc_remove_codec_dai(rtd->codec_dais[i], order); 1016 soc_remove_dai(rtd->codec_dais[i], order);
1089 1017
1090 /* remove the cpu_dai */ 1018 soc_remove_dai(rtd->cpu_dai, order);
1091 if (cpu_dai && cpu_dai->probed &&
1092 cpu_dai->driver->remove_order == order) {
1093 if (cpu_dai->driver->remove) {
1094 err = cpu_dai->driver->remove(cpu_dai);
1095 if (err < 0)
1096 dev_err(cpu_dai->dev,
1097 "ASoC: failed to remove %s: %d\n",
1098 cpu_dai->name, err);
1099 }
1100 cpu_dai->probed = 0;
1101 if (!cpu_dai->codec)
1102 module_put(cpu_dai->dev->driver->owner);
1103 }
1104} 1019}
1105 1020
1106static void soc_remove_link_components(struct snd_soc_card *card, int num, 1021static void soc_remove_link_components(struct snd_soc_card *card, int num,
@@ -1109,29 +1024,24 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num,
1109 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1024 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1110 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1025 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1111 struct snd_soc_platform *platform = rtd->platform; 1026 struct snd_soc_platform *platform = rtd->platform;
1112 struct snd_soc_codec *codec; 1027 struct snd_soc_component *component;
1113 int i; 1028 int i;
1114 1029
1115 /* remove the platform */ 1030 /* remove the platform */
1116 if (platform && platform->probed && 1031 if (platform && platform->component.driver->remove_order == order)
1117 platform->driver->remove_order == order) { 1032 soc_remove_component(&platform->component);
1118 soc_remove_platform(platform);
1119 }
1120 1033
1121 /* remove the CODEC-side CODEC */ 1034 /* remove the CODEC-side CODEC */
1122 for (i = 0; i < rtd->num_codecs; i++) { 1035 for (i = 0; i < rtd->num_codecs; i++) {
1123 codec = rtd->codec_dais[i]->codec; 1036 component = rtd->codec_dais[i]->component;
1124 if (codec && codec->probed && 1037 if (component->driver->remove_order == order)
1125 codec->driver->remove_order == order) 1038 soc_remove_component(component);
1126 soc_remove_codec(codec);
1127 } 1039 }
1128 1040
1129 /* remove any CPU-side CODEC */ 1041 /* remove any CPU-side CODEC */
1130 if (cpu_dai) { 1042 if (cpu_dai) {
1131 codec = cpu_dai->codec; 1043 if (cpu_dai->component->driver->remove_order == order)
1132 if (codec && codec->probed && 1044 soc_remove_component(cpu_dai->component);
1133 codec->driver->remove_order == order)
1134 soc_remove_codec(codec);
1135 } 1045 }
1136} 1046}
1137 1047
@@ -1173,137 +1083,78 @@ static void soc_set_name_prefix(struct snd_soc_card *card,
1173 } 1083 }
1174} 1084}
1175 1085
1176static int soc_probe_codec(struct snd_soc_card *card, 1086static int soc_probe_component(struct snd_soc_card *card,
1177 struct snd_soc_codec *codec) 1087 struct snd_soc_component *component)
1178{ 1088{
1179 int ret = 0; 1089 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1180 const struct snd_soc_codec_driver *driver = codec->driver;
1181 struct snd_soc_dai *dai; 1090 struct snd_soc_dai *dai;
1091 int ret;
1092
1093 if (component->probed)
1094 return 0;
1182 1095
1183 codec->component.card = card; 1096 component->card = card;
1184 codec->dapm.card = card; 1097 dapm->card = card;
1185 soc_set_name_prefix(card, &codec->component); 1098 soc_set_name_prefix(card, component);
1186 1099
1187 if (!try_module_get(codec->dev->driver->owner)) 1100 if (!try_module_get(component->dev->driver->owner))
1188 return -ENODEV; 1101 return -ENODEV;
1189 1102
1190 soc_init_codec_debugfs(codec); 1103 soc_init_component_debugfs(component);
1191 1104
1192 if (driver->dapm_widgets) { 1105 if (component->dapm_widgets) {
1193 ret = snd_soc_dapm_new_controls(&codec->dapm, 1106 ret = snd_soc_dapm_new_controls(dapm, component->dapm_widgets,
1194 driver->dapm_widgets, 1107 component->num_dapm_widgets);
1195 driver->num_dapm_widgets);
1196 1108
1197 if (ret != 0) { 1109 if (ret != 0) {
1198 dev_err(codec->dev, 1110 dev_err(component->dev,
1199 "Failed to create new controls %d\n", ret); 1111 "Failed to create new controls %d\n", ret);
1200 goto err_probe; 1112 goto err_probe;
1201 } 1113 }
1202 } 1114 }
1203 1115
1204 /* Create DAPM widgets for each DAI stream */ 1116 list_for_each_entry(dai, &component->dai_list, list) {
1205 list_for_each_entry(dai, &codec->component.dai_list, list) { 1117 ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1206 ret = snd_soc_dapm_new_dai_widgets(&codec->dapm, dai);
1207
1208 if (ret != 0) { 1118 if (ret != 0) {
1209 dev_err(codec->dev, 1119 dev_err(component->dev,
1210 "Failed to create DAI widgets %d\n", ret); 1120 "Failed to create DAI widgets %d\n", ret);
1211 goto err_probe; 1121 goto err_probe;
1212 } 1122 }
1213 } 1123 }
1214 1124
1215 codec->dapm.idle_bias_off = driver->idle_bias_off; 1125 if (component->probe) {
1216 1126 ret = component->probe(component);
1217 if (driver->probe) {
1218 ret = driver->probe(codec);
1219 if (ret < 0) { 1127 if (ret < 0) {
1220 dev_err(codec->dev, 1128 dev_err(component->dev,
1221 "ASoC: failed to probe CODEC %d\n", ret); 1129 "ASoC: failed to probe component %d\n", ret);
1222 goto err_probe; 1130 goto err_probe;
1223 } 1131 }
1224 WARN(codec->dapm.idle_bias_off &&
1225 codec->dapm.bias_level != SND_SOC_BIAS_OFF,
1226 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1227 codec->component.name);
1228 }
1229
1230 if (driver->controls)
1231 snd_soc_add_codec_controls(codec, driver->controls,
1232 driver->num_controls);
1233 if (driver->dapm_routes)
1234 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
1235 driver->num_dapm_routes);
1236
1237 /* mark codec as probed and add to card codec list */
1238 codec->probed = 1;
1239 list_add(&codec->card_list, &card->codec_dev_list);
1240 list_add(&codec->dapm.list, &card->dapm_list);
1241
1242 return 0;
1243
1244err_probe:
1245 soc_cleanup_codec_debugfs(codec);
1246 module_put(codec->dev->driver->owner);
1247
1248 return ret;
1249}
1250
1251static int soc_probe_platform(struct snd_soc_card *card,
1252 struct snd_soc_platform *platform)
1253{
1254 int ret = 0;
1255 const struct snd_soc_platform_driver *driver = platform->driver;
1256 struct snd_soc_component *component;
1257 struct snd_soc_dai *dai;
1258
1259 platform->component.card = card;
1260 platform->component.dapm.card = card;
1261
1262 if (!try_module_get(platform->dev->driver->owner))
1263 return -ENODEV;
1264
1265 soc_init_platform_debugfs(platform);
1266 1132
1267 if (driver->dapm_widgets) 1133 WARN(dapm->idle_bias_off &&
1268 snd_soc_dapm_new_controls(&platform->component.dapm, 1134 dapm->bias_level != SND_SOC_BIAS_OFF,
1269 driver->dapm_widgets, driver->num_dapm_widgets); 1135 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1270 1136 component->name);
1271 /* Create DAPM widgets for each DAI stream */
1272 list_for_each_entry(component, &component_list, list) {
1273 if (component->dev != platform->dev)
1274 continue;
1275 list_for_each_entry(dai, &component->dai_list, list)
1276 snd_soc_dapm_new_dai_widgets(&platform->component.dapm,
1277 dai);
1278 } 1137 }
1279 1138
1280 platform->component.dapm.idle_bias_off = 1; 1139 if (component->controls)
1140 snd_soc_add_component_controls(component, component->controls,
1141 component->num_controls);
1142 if (component->dapm_routes)
1143 snd_soc_dapm_add_routes(dapm, component->dapm_routes,
1144 component->num_dapm_routes);
1281 1145
1282 if (driver->probe) { 1146 component->probed = 1;
1283 ret = driver->probe(platform); 1147 list_add(&dapm->list, &card->dapm_list);
1284 if (ret < 0) {
1285 dev_err(platform->dev,
1286 "ASoC: failed to probe platform %d\n", ret);
1287 goto err_probe;
1288 }
1289 }
1290
1291 if (driver->controls)
1292 snd_soc_add_platform_controls(platform, driver->controls,
1293 driver->num_controls);
1294 if (driver->dapm_routes)
1295 snd_soc_dapm_add_routes(&platform->component.dapm,
1296 driver->dapm_routes, driver->num_dapm_routes);
1297 1148
1298 /* mark platform as probed and add to card platform list */ 1149 /* This is a HACK and will be removed soon */
1299 platform->probed = 1; 1150 if (component->codec)
1300 list_add(&platform->component.dapm.list, &card->dapm_list); 1151 list_add(&component->codec->card_list, &card->codec_dev_list);
1301 1152
1302 return 0; 1153 return 0;
1303 1154
1304err_probe: 1155err_probe:
1305 soc_cleanup_platform_debugfs(platform); 1156 soc_cleanup_component_debugfs(component);
1306 module_put(platform->dev->driver->owner); 1157 module_put(component->dev->driver->owner);
1307 1158
1308 return ret; 1159 return ret;
1309} 1160}
@@ -1342,17 +1193,21 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd,
1342 } 1193 }
1343 rtd->dev_registered = 1; 1194 rtd->dev_registered = 1;
1344 1195
1345 /* add DAPM sysfs entries for this codec */ 1196 if (rtd->codec) {
1346 ret = snd_soc_dapm_sys_add(rtd->dev); 1197 /* add DAPM sysfs entries for this codec */
1347 if (ret < 0) 1198 ret = snd_soc_dapm_sys_add(rtd->dev);
1348 dev_err(rtd->dev, 1199 if (ret < 0)
1349 "ASoC: failed to add codec dapm sysfs entries: %d\n", ret); 1200 dev_err(rtd->dev,
1201 "ASoC: failed to add codec dapm sysfs entries: %d\n",
1202 ret);
1350 1203
1351 /* add codec sysfs entries */ 1204 /* add codec sysfs entries */
1352 ret = device_create_file(rtd->dev, &dev_attr_codec_reg); 1205 ret = device_create_file(rtd->dev, &dev_attr_codec_reg);
1353 if (ret < 0) 1206 if (ret < 0)
1354 dev_err(rtd->dev, 1207 dev_err(rtd->dev,
1355 "ASoC: failed to add codec sysfs files: %d\n", ret); 1208 "ASoC: failed to add codec sysfs files: %d\n",
1209 ret);
1210 }
1356 1211
1357 return 0; 1212 return 0;
1358} 1213}
@@ -1361,33 +1216,31 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num,
1361 int order) 1216 int order)
1362{ 1217{
1363 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1218 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1364 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1365 struct snd_soc_platform *platform = rtd->platform; 1219 struct snd_soc_platform *platform = rtd->platform;
1220 struct snd_soc_component *component;
1366 int i, ret; 1221 int i, ret;
1367 1222
1368 /* probe the CPU-side component, if it is a CODEC */ 1223 /* probe the CPU-side component, if it is a CODEC */
1369 if (cpu_dai->codec && 1224 component = rtd->cpu_dai->component;
1370 !cpu_dai->codec->probed && 1225 if (component->driver->probe_order == order) {
1371 cpu_dai->codec->driver->probe_order == order) { 1226 ret = soc_probe_component(card, component);
1372 ret = soc_probe_codec(card, cpu_dai->codec);
1373 if (ret < 0) 1227 if (ret < 0)
1374 return ret; 1228 return ret;
1375 } 1229 }
1376 1230
1377 /* probe the CODEC-side components */ 1231 /* probe the CODEC-side components */
1378 for (i = 0; i < rtd->num_codecs; i++) { 1232 for (i = 0; i < rtd->num_codecs; i++) {
1379 if (!rtd->codec_dais[i]->codec->probed && 1233 component = rtd->codec_dais[i]->component;
1380 rtd->codec_dais[i]->codec->driver->probe_order == order) { 1234 if (component->driver->probe_order == order) {
1381 ret = soc_probe_codec(card, rtd->codec_dais[i]->codec); 1235 ret = soc_probe_component(card, component);
1382 if (ret < 0) 1236 if (ret < 0)
1383 return ret; 1237 return ret;
1384 } 1238 }
1385 } 1239 }
1386 1240
1387 /* probe the platform */ 1241 /* probe the platform */
1388 if (!platform->probed && 1242 if (platform->component.driver->probe_order == order) {
1389 platform->driver->probe_order == order) { 1243 ret = soc_probe_component(card, &platform->component);
1390 ret = soc_probe_platform(card, platform);
1391 if (ret < 0) 1244 if (ret < 0)
1392 return ret; 1245 return ret;
1393 } 1246 }
@@ -1482,18 +1335,12 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1482 /* probe the cpu_dai */ 1335 /* probe the cpu_dai */
1483 if (!cpu_dai->probed && 1336 if (!cpu_dai->probed &&
1484 cpu_dai->driver->probe_order == order) { 1337 cpu_dai->driver->probe_order == order) {
1485 if (!cpu_dai->codec) {
1486 if (!try_module_get(cpu_dai->dev->driver->owner))
1487 return -ENODEV;
1488 }
1489
1490 if (cpu_dai->driver->probe) { 1338 if (cpu_dai->driver->probe) {
1491 ret = cpu_dai->driver->probe(cpu_dai); 1339 ret = cpu_dai->driver->probe(cpu_dai);
1492 if (ret < 0) { 1340 if (ret < 0) {
1493 dev_err(cpu_dai->dev, 1341 dev_err(cpu_dai->dev,
1494 "ASoC: failed to probe CPU DAI %s: %d\n", 1342 "ASoC: failed to probe CPU DAI %s: %d\n",
1495 cpu_dai->name, ret); 1343 cpu_dai->name, ret);
1496 module_put(cpu_dai->dev->driver->owner);
1497 return ret; 1344 return ret;
1498 } 1345 }
1499 } 1346 }
@@ -1654,17 +1501,24 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
1654{ 1501{
1655 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1502 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1656 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1503 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1657 const char *codecname = aux_dev->codec_name; 1504 const char *name = aux_dev->codec_name;
1658 1505
1659 rtd->codec = soc_find_codec(aux_dev->codec_of_node, codecname); 1506 rtd->component = soc_find_component(aux_dev->codec_of_node, name);
1660 if (!rtd->codec) { 1507 if (!rtd->component) {
1661 if (aux_dev->codec_of_node) 1508 if (aux_dev->codec_of_node)
1662 codecname = of_node_full_name(aux_dev->codec_of_node); 1509 name = of_node_full_name(aux_dev->codec_of_node);
1663 1510
1664 dev_err(card->dev, "ASoC: %s not registered\n", codecname); 1511 dev_err(card->dev, "ASoC: %s not registered\n", name);
1665 return -EPROBE_DEFER; 1512 return -EPROBE_DEFER;
1666 } 1513 }
1667 1514
1515 /*
1516 * Some places still reference rtd->codec, so we have to keep that
1517 * initialized if the component is a CODEC. Once all those references
1518 * have been removed, this code can be removed as well.
1519 */
1520 rtd->codec = rtd->component->codec;
1521
1668 return 0; 1522 return 0;
1669} 1523}
1670 1524
@@ -1674,18 +1528,13 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1674 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1528 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1675 int ret; 1529 int ret;
1676 1530
1677 if (rtd->codec->probed) { 1531 ret = soc_probe_component(card, rtd->component);
1678 dev_err(rtd->codec->dev, "ASoC: codec already probed\n");
1679 return -EBUSY;
1680 }
1681
1682 ret = soc_probe_codec(card, rtd->codec);
1683 if (ret < 0) 1532 if (ret < 0)
1684 return ret; 1533 return ret;
1685 1534
1686 /* do machine specific initialization */ 1535 /* do machine specific initialization */
1687 if (aux_dev->init) { 1536 if (aux_dev->init) {
1688 ret = aux_dev->init(&rtd->codec->dapm); 1537 ret = aux_dev->init(rtd->component);
1689 if (ret < 0) { 1538 if (ret < 0) {
1690 dev_err(card->dev, "ASoC: failed to init %s: %d\n", 1539 dev_err(card->dev, "ASoC: failed to init %s: %d\n",
1691 aux_dev->name, ret); 1540 aux_dev->name, ret);
@@ -1699,7 +1548,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1699static void soc_remove_aux_dev(struct snd_soc_card *card, int num) 1548static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1700{ 1549{
1701 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1550 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1702 struct snd_soc_codec *codec = rtd->codec; 1551 struct snd_soc_component *component = rtd->component;
1703 1552
1704 /* unregister the rtd device */ 1553 /* unregister the rtd device */
1705 if (rtd->dev_registered) { 1554 if (rtd->dev_registered) {
@@ -1708,8 +1557,8 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1708 rtd->dev_registered = 0; 1557 rtd->dev_registered = 0;
1709 } 1558 }
1710 1559
1711 if (codec && codec->probed) 1560 if (component && component->probed)
1712 soc_remove_codec(codec); 1561 soc_remove_component(component);
1713} 1562}
1714 1563
1715static int snd_soc_init_codec_cache(struct snd_soc_codec *codec) 1564static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
@@ -4116,6 +3965,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
4116 3965
4117 component->dev = dev; 3966 component->dev = dev;
4118 component->driver = driver; 3967 component->driver = driver;
3968 component->probe = component->driver->probe;
3969 component->remove = component->driver->remove;
4119 3970
4120 if (!component->dapm_ptr) 3971 if (!component->dapm_ptr)
4121 component->dapm_ptr = &component->dapm; 3972 component->dapm_ptr = &component->dapm;
@@ -4124,19 +3975,42 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
4124 dapm->dev = dev; 3975 dapm->dev = dev;
4125 dapm->component = component; 3976 dapm->component = component;
4126 dapm->bias_level = SND_SOC_BIAS_OFF; 3977 dapm->bias_level = SND_SOC_BIAS_OFF;
3978 dapm->idle_bias_off = true;
4127 if (driver->seq_notifier) 3979 if (driver->seq_notifier)
4128 dapm->seq_notifier = snd_soc_component_seq_notifier; 3980 dapm->seq_notifier = snd_soc_component_seq_notifier;
4129 if (driver->stream_event) 3981 if (driver->stream_event)
4130 dapm->stream_event = snd_soc_component_stream_event; 3982 dapm->stream_event = snd_soc_component_stream_event;
4131 3983
3984 component->controls = driver->controls;
3985 component->num_controls = driver->num_controls;
3986 component->dapm_widgets = driver->dapm_widgets;
3987 component->num_dapm_widgets = driver->num_dapm_widgets;
3988 component->dapm_routes = driver->dapm_routes;
3989 component->num_dapm_routes = driver->num_dapm_routes;
3990
4132 INIT_LIST_HEAD(&component->dai_list); 3991 INIT_LIST_HEAD(&component->dai_list);
4133 mutex_init(&component->io_mutex); 3992 mutex_init(&component->io_mutex);
4134 3993
4135 return 0; 3994 return 0;
4136} 3995}
4137 3996
3997static void snd_soc_component_init_regmap(struct snd_soc_component *component)
3998{
3999 if (!component->regmap)
4000 component->regmap = dev_get_regmap(component->dev, NULL);
4001 if (component->regmap) {
4002 int val_bytes = regmap_get_val_bytes(component->regmap);
4003 /* Errors are legitimate for non-integer byte multiples */
4004 if (val_bytes > 0)
4005 component->val_bytes = val_bytes;
4006 }
4007}
4008
4138static void snd_soc_component_add_unlocked(struct snd_soc_component *component) 4009static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
4139{ 4010{
4011 if (!component->write && !component->read)
4012 snd_soc_component_init_regmap(component);
4013
4140 list_add(&component->list, &component_list); 4014 list_add(&component->list, &component_list);
4141} 4015}
4142 4016
@@ -4225,22 +4099,18 @@ found:
4225} 4099}
4226EXPORT_SYMBOL_GPL(snd_soc_unregister_component); 4100EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
4227 4101
4228static int snd_soc_platform_drv_write(struct snd_soc_component *component, 4102static int snd_soc_platform_drv_probe(struct snd_soc_component *component)
4229 unsigned int reg, unsigned int val)
4230{ 4103{
4231 struct snd_soc_platform *platform = snd_soc_component_to_platform(component); 4104 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
4232 4105
4233 return platform->driver->write(platform, reg, val); 4106 return platform->driver->probe(platform);
4234} 4107}
4235 4108
4236static int snd_soc_platform_drv_read(struct snd_soc_component *component, 4109static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
4237 unsigned int reg, unsigned int *val)
4238{ 4110{
4239 struct snd_soc_platform *platform = snd_soc_component_to_platform(component); 4111 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
4240 4112
4241 *val = platform->driver->read(platform, reg); 4113 platform->driver->remove(platform);
4242
4243 return 0;
4244} 4114}
4245 4115
4246/** 4116/**
@@ -4261,10 +4131,15 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
4261 4131
4262 platform->dev = dev; 4132 platform->dev = dev;
4263 platform->driver = platform_drv; 4133 platform->driver = platform_drv;
4264 if (platform_drv->write) 4134
4265 platform->component.write = snd_soc_platform_drv_write; 4135 if (platform_drv->probe)
4266 if (platform_drv->read) 4136 platform->component.probe = snd_soc_platform_drv_probe;
4267 platform->component.read = snd_soc_platform_drv_read; 4137 if (platform_drv->remove)
4138 platform->component.remove = snd_soc_platform_drv_remove;
4139
4140#ifdef CONFIG_DEBUG_FS
4141 platform->component.debugfs_prefix = "platform";
4142#endif
4268 4143
4269 mutex_lock(&client_mutex); 4144 mutex_lock(&client_mutex);
4270 snd_soc_component_add_unlocked(&platform->component); 4145 snd_soc_component_add_unlocked(&platform->component);
@@ -4386,6 +4261,20 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
4386 stream->formats |= codec_format_map[i]; 4261 stream->formats |= codec_format_map[i];
4387} 4262}
4388 4263
4264static int snd_soc_codec_drv_probe(struct snd_soc_component *component)
4265{
4266 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
4267
4268 return codec->driver->probe(codec);
4269}
4270
4271static void snd_soc_codec_drv_remove(struct snd_soc_component *component)
4272{
4273 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
4274
4275 codec->driver->remove(codec);
4276}
4277
4389static int snd_soc_codec_drv_write(struct snd_soc_component *component, 4278static int snd_soc_codec_drv_write(struct snd_soc_component *component,
4390 unsigned int reg, unsigned int val) 4279 unsigned int reg, unsigned int val)
4391{ 4280{
@@ -4424,7 +4313,6 @@ int snd_soc_register_codec(struct device *dev,
4424{ 4313{
4425 struct snd_soc_codec *codec; 4314 struct snd_soc_codec *codec;
4426 struct snd_soc_dai *dai; 4315 struct snd_soc_dai *dai;
4427 struct regmap *regmap;
4428 int ret, i; 4316 int ret, i;
4429 4317
4430 dev_dbg(dev, "codec register %s\n", dev_name(dev)); 4318 dev_dbg(dev, "codec register %s\n", dev_name(dev));
@@ -4434,18 +4322,36 @@ int snd_soc_register_codec(struct device *dev,
4434 return -ENOMEM; 4322 return -ENOMEM;
4435 4323
4436 codec->component.dapm_ptr = &codec->dapm; 4324 codec->component.dapm_ptr = &codec->dapm;
4325 codec->component.codec = codec;
4437 4326
4438 ret = snd_soc_component_initialize(&codec->component, 4327 ret = snd_soc_component_initialize(&codec->component,
4439 &codec_drv->component_driver, dev); 4328 &codec_drv->component_driver, dev);
4440 if (ret) 4329 if (ret)
4441 goto err_free; 4330 goto err_free;
4442 4331
4332 if (codec_drv->controls) {
4333 codec->component.controls = codec_drv->controls;
4334 codec->component.num_controls = codec_drv->num_controls;
4335 }
4336 if (codec_drv->dapm_widgets) {
4337 codec->component.dapm_widgets = codec_drv->dapm_widgets;
4338 codec->component.num_dapm_widgets = codec_drv->num_dapm_widgets;
4339 }
4340 if (codec_drv->dapm_routes) {
4341 codec->component.dapm_routes = codec_drv->dapm_routes;
4342 codec->component.num_dapm_routes = codec_drv->num_dapm_routes;
4343 }
4344
4345 if (codec_drv->probe)
4346 codec->component.probe = snd_soc_codec_drv_probe;
4347 if (codec_drv->remove)
4348 codec->component.remove = snd_soc_codec_drv_remove;
4443 if (codec_drv->write) 4349 if (codec_drv->write)
4444 codec->component.write = snd_soc_codec_drv_write; 4350 codec->component.write = snd_soc_codec_drv_write;
4445 if (codec_drv->read) 4351 if (codec_drv->read)
4446 codec->component.read = snd_soc_codec_drv_read; 4352 codec->component.read = snd_soc_codec_drv_read;
4447 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; 4353 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
4448 codec->dapm.codec = codec; 4354 codec->dapm.idle_bias_off = codec_drv->idle_bias_off;
4449 if (codec_drv->seq_notifier) 4355 if (codec_drv->seq_notifier)
4450 codec->dapm.seq_notifier = codec_drv->seq_notifier; 4356 codec->dapm.seq_notifier = codec_drv->seq_notifier;
4451 if (codec_drv->set_bias_level) 4357 if (codec_drv->set_bias_level)
@@ -4455,23 +4361,13 @@ int snd_soc_register_codec(struct device *dev,
4455 codec->component.val_bytes = codec_drv->reg_word_size; 4361 codec->component.val_bytes = codec_drv->reg_word_size;
4456 mutex_init(&codec->mutex); 4362 mutex_init(&codec->mutex);
4457 4363
4458 if (!codec->component.write) { 4364#ifdef CONFIG_DEBUG_FS
4459 if (codec_drv->get_regmap) 4365 codec->component.init_debugfs = soc_init_codec_debugfs;
4460 regmap = codec_drv->get_regmap(dev); 4366 codec->component.debugfs_prefix = "codec";
4461 else 4367#endif
4462 regmap = dev_get_regmap(dev, NULL); 4368
4463 4369 if (codec_drv->get_regmap)
4464 if (regmap) { 4370 codec->component.regmap = codec_drv->get_regmap(dev);
4465 ret = snd_soc_component_init_io(&codec->component,
4466 regmap);
4467 if (ret) {
4468 dev_err(codec->dev,
4469 "Failed to set cache I/O:%d\n",
4470 ret);
4471 goto err_cleanup;
4472 }
4473 }
4474 }
4475 4371
4476 for (i = 0; i < num_dai; i++) { 4372 for (i = 0; i < num_dai; i++) {
4477 fixup_codec_formats(&dai_drv[i].playback); 4373 fixup_codec_formats(&dai_drv[i].playback);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 177bd8639ef9..79f3b1eaf3b1 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3109,7 +3109,8 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3109 } 3109 }
3110 3110
3111 w->dapm = dapm; 3111 w->dapm = dapm;
3112 w->codec = dapm->codec; 3112 if (dapm->component)
3113 w->codec = dapm->component->codec;
3113 INIT_LIST_HEAD(&w->sources); 3114 INIT_LIST_HEAD(&w->sources);
3114 INIT_LIST_HEAD(&w->sinks); 3115 INIT_LIST_HEAD(&w->sinks);
3115 INIT_LIST_HEAD(&w->list); 3116 INIT_LIST_HEAD(&w->list);
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 6307f85e871b..b329b84bc5af 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -336,10 +336,12 @@ static const struct snd_pcm_ops dmaengine_pcm_ops = {
336}; 336};
337 337
338static const struct snd_soc_platform_driver dmaengine_pcm_platform = { 338static const struct snd_soc_platform_driver dmaengine_pcm_platform = {
339 .component_driver = {
340 .probe_order = SND_SOC_COMP_ORDER_LATE,
341 },
339 .ops = &dmaengine_pcm_ops, 342 .ops = &dmaengine_pcm_ops,
340 .pcm_new = dmaengine_pcm_new, 343 .pcm_new = dmaengine_pcm_new,
341 .pcm_free = dmaengine_pcm_free, 344 .pcm_free = dmaengine_pcm_free,
342 .probe_order = SND_SOC_COMP_ORDER_LATE,
343}; 345};
344 346
345static const char * const dmaengine_pcm_dma_channel_names[] = { 347static const char * const dmaengine_pcm_dma_channel_names[] = {
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 7767fbd73eb7..9b3939049cef 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -271,31 +271,3 @@ int snd_soc_platform_write(struct snd_soc_platform *platform,
271 return snd_soc_component_write(&platform->component, reg, val); 271 return snd_soc_component_write(&platform->component, reg, val);
272} 272}
273EXPORT_SYMBOL_GPL(snd_soc_platform_write); 273EXPORT_SYMBOL_GPL(snd_soc_platform_write);
274
275/**
276 * snd_soc_component_init_io() - Initialize regmap IO
277 *
278 * @component: component to initialize
279 * @regmap: regmap instance to use for IO operations
280 *
281 * Return: 0 on success, a negative error code otherwise
282 */
283int snd_soc_component_init_io(struct snd_soc_component *component,
284 struct regmap *regmap)
285{
286 int ret;
287
288 if (!regmap)
289 return -EINVAL;
290
291 ret = regmap_get_val_bytes(regmap);
292 /* Errors are legitimate for non-integer byte
293 * multiples */
294 if (ret > 0)
295 component->val_bytes = ret;
296
297 component->regmap = regmap;
298
299 return 0;
300}
301EXPORT_SYMBOL_GPL(snd_soc_component_init_io);