aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc.h87
-rw-r--r--sound/soc/codecs/max98090.c115
-rw-r--r--sound/soc/codecs/max98090.h3
-rw-r--r--sound/soc/intel/Makefile3
-rw-r--r--sound/soc/intel/byt-max98090.c1
-rw-r--r--sound/soc/intel/byt-rt5640.c54
-rw-r--r--sound/soc/intel/sst-atom-controls.c218
-rw-r--r--sound/soc/intel/sst-atom-controls.h416
-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.c106
-rw-r--r--sound/soc/intel/sst-mfld-platform.h58
-rw-r--r--sound/soc/samsung/speyside.c6
-rw-r--r--sound/soc/soc-core.c669
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c4
-rw-r--r--sound/soc/soc-io.c28
16 files changed, 1325 insertions, 537 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index be6ecae247b0..f8b23dd7c3a7 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,36 @@ 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 bool steal_sibling_dai_widgets;
768 struct snd_soc_codec *codec;
769
770 int (*probe)(struct snd_soc_component *);
771 void (*remove)(struct snd_soc_component *);
772
773#ifdef CONFIG_DEBUG_FS
774 void (*init_debugfs)(struct snd_soc_component *component);
775 const char *debugfs_prefix;
776#endif
734}; 777};
735 778
736/* SoC Audio Codec device */ 779/* SoC Audio Codec device */
@@ -746,11 +789,9 @@ struct snd_soc_codec {
746 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ 789 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
747 unsigned int cache_bypass:1; /* Suppress access to the cache */ 790 unsigned int cache_bypass:1; /* Suppress access to the cache */
748 unsigned int suspended:1; /* Codec is in suspend PM state */ 791 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 */ 792 unsigned int ac97_registered:1; /* Codec has been AC97 registered */
751 unsigned int ac97_created:1; /* Codec has been created by SoC */ 793 unsigned int ac97_created:1; /* Codec has been created by SoC */
752 unsigned int cache_init:1; /* codec cache has been initialized */ 794 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 */ 795 u32 cache_sync; /* Cache needs to be synced to hardware */
755 796
756 /* codec IO */ 797 /* codec IO */
@@ -766,7 +807,6 @@ struct snd_soc_codec {
766 struct snd_soc_dapm_context dapm; 807 struct snd_soc_dapm_context dapm;
767 808
768#ifdef CONFIG_DEBUG_FS 809#ifdef CONFIG_DEBUG_FS
769 struct dentry *debugfs_codec_root;
770 struct dentry *debugfs_reg; 810 struct dentry *debugfs_reg;
771#endif 811#endif
772}; 812};
@@ -813,10 +853,6 @@ struct snd_soc_codec_driver {
813 enum snd_soc_dapm_type, int); 853 enum snd_soc_dapm_type, int);
814 854
815 bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */ 855 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}; 856};
821 857
822/* SoC platform interface */ 858/* SoC platform interface */
@@ -853,13 +889,6 @@ struct snd_soc_platform_driver {
853 /* platform stream compress ops */ 889 /* platform stream compress ops */
854 const struct snd_compr_ops *compr_ops; 890 const struct snd_compr_ops *compr_ops;
855 891
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); 892 int (*bespoke_trigger)(struct snd_pcm_substream *, int);
864}; 893};
865 894
@@ -874,15 +903,10 @@ struct snd_soc_platform {
874 const struct snd_soc_platform_driver *driver; 903 const struct snd_soc_platform_driver *driver;
875 904
876 unsigned int suspended:1; /* platform is suspended */ 905 unsigned int suspended:1; /* platform is suspended */
877 unsigned int probed:1;
878 906
879 struct list_head list; 907 struct list_head list;
880 908
881 struct snd_soc_component component; 909 struct snd_soc_component component;
882
883#ifdef CONFIG_DEBUG_FS
884 struct dentry *debugfs_platform_root;
885#endif
886}; 910};
887 911
888struct snd_soc_dai_link { 912struct snd_soc_dai_link {
@@ -994,7 +1018,7 @@ struct snd_soc_aux_dev {
994 const struct device_node *codec_of_node; 1018 const struct device_node *codec_of_node;
995 1019
996 /* codec/machine specific init - e.g. add machine controls */ 1020 /* codec/machine specific init - e.g. add machine controls */
997 int (*init)(struct snd_soc_dapm_context *dapm); 1021 int (*init)(struct snd_soc_component *component);
998}; 1022};
999 1023
1000/* SoC card */ 1024/* SoC card */
@@ -1112,6 +1136,7 @@ struct snd_soc_pcm_runtime {
1112 struct snd_soc_platform *platform; 1136 struct snd_soc_platform *platform;
1113 struct snd_soc_dai *codec_dai; 1137 struct snd_soc_dai *codec_dai;
1114 struct snd_soc_dai *cpu_dai; 1138 struct snd_soc_dai *cpu_dai;
1139 struct snd_soc_component *component; /* Only valid for AUX dev rtds */
1115 1140
1116 struct snd_soc_dai **codec_dais; 1141 struct snd_soc_dai **codec_dais;
1117 unsigned int num_codecs; 1142 unsigned int num_codecs;
@@ -1260,9 +1285,6 @@ void snd_soc_component_async_complete(struct snd_soc_component *component);
1260int snd_soc_component_test_bits(struct snd_soc_component *component, 1285int snd_soc_component_test_bits(struct snd_soc_component *component,
1261 unsigned int reg, unsigned int mask, unsigned int value); 1286 unsigned int reg, unsigned int mask, unsigned int value);
1262 1287
1263int snd_soc_component_init_io(struct snd_soc_component *component,
1264 struct regmap *regmap);
1265
1266/* device driver data */ 1288/* device driver data */
1267 1289
1268static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, 1290static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
@@ -1276,26 +1298,37 @@ static inline void *snd_soc_card_get_drvdata(struct snd_soc_card *card)
1276 return card->drvdata; 1298 return card->drvdata;
1277} 1299}
1278 1300
1301static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c,
1302 void *data)
1303{
1304 dev_set_drvdata(c->dev, data);
1305}
1306
1307static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
1308{
1309 return dev_get_drvdata(c->dev);
1310}
1311
1279static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec, 1312static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
1280 void *data) 1313 void *data)
1281{ 1314{
1282 dev_set_drvdata(codec->dev, data); 1315 snd_soc_component_set_drvdata(&codec->component, data);
1283} 1316}
1284 1317
1285static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec) 1318static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
1286{ 1319{
1287 return dev_get_drvdata(codec->dev); 1320 return snd_soc_component_get_drvdata(&codec->component);
1288} 1321}
1289 1322
1290static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform, 1323static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform,
1291 void *data) 1324 void *data)
1292{ 1325{
1293 dev_set_drvdata(platform->dev, data); 1326 snd_soc_component_set_drvdata(&platform->component, data);
1294} 1327}
1295 1328
1296static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform) 1329static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform)
1297{ 1330{
1298 return dev_get_drvdata(platform->dev); 1331 return snd_soc_component_get_drvdata(&platform->component);
1299} 1332}
1300 1333
1301static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd, 1334static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 4a063fa88526..7e111865946a 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -1311,8 +1311,6 @@ static const struct snd_soc_dapm_route max98090_dapm_routes[] = {
1311 {"MIC1 Input", NULL, "MIC1"}, 1311 {"MIC1 Input", NULL, "MIC1"},
1312 {"MIC2 Input", NULL, "MIC2"}, 1312 {"MIC2 Input", NULL, "MIC2"},
1313 1313
1314 {"DMICL", NULL, "DMICL_ENA"},
1315 {"DMICR", NULL, "DMICR_ENA"},
1316 {"DMICL", NULL, "AHPF"}, 1314 {"DMICL", NULL, "AHPF"},
1317 {"DMICR", NULL, "AHPF"}, 1315 {"DMICR", NULL, "AHPF"},
1318 1316
@@ -1370,6 +1368,8 @@ static const struct snd_soc_dapm_route max98090_dapm_routes[] = {
1370 {"DMIC Mux", "ADC", "ADCR"}, 1368 {"DMIC Mux", "ADC", "ADCR"},
1371 {"DMIC Mux", "DMIC", "DMICL"}, 1369 {"DMIC Mux", "DMIC", "DMICL"},
1372 {"DMIC Mux", "DMIC", "DMICR"}, 1370 {"DMIC Mux", "DMIC", "DMICR"},
1371 {"DMIC Mux", "DMIC", "DMICL_ENA"},
1372 {"DMIC Mux", "DMIC", "DMICR_ENA"},
1373 1373
1374 {"LBENL Mux", "Normal", "DMIC Mux"}, 1374 {"LBENL Mux", "Normal", "DMIC Mux"},
1375 {"LBENL Mux", "Loopback", "LTENL Mux"}, 1375 {"LBENL Mux", "Loopback", "LTENL Mux"},
@@ -1972,6 +1972,102 @@ static int max98090_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1972 return 0; 1972 return 0;
1973} 1973}
1974 1974
1975static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd,
1976 struct snd_soc_dai *dai)
1977{
1978 struct snd_soc_codec *codec = dai->codec;
1979 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
1980
1981 switch (cmd) {
1982 case SNDRV_PCM_TRIGGER_START:
1983 case SNDRV_PCM_TRIGGER_RESUME:
1984 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1985 if (!max98090->master && dai->active == 1)
1986 queue_delayed_work(system_power_efficient_wq,
1987 &max98090->pll_det_enable_work,
1988 msecs_to_jiffies(10));
1989 break;
1990 case SNDRV_PCM_TRIGGER_STOP:
1991 case SNDRV_PCM_TRIGGER_SUSPEND:
1992 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1993 if (!max98090->master && dai->active == 1)
1994 schedule_work(&max98090->pll_det_disable_work);
1995 break;
1996 default:
1997 break;
1998 }
1999
2000 return 0;
2001}
2002
2003static void max98090_pll_det_enable_work(struct work_struct *work)
2004{
2005 struct max98090_priv *max98090 =
2006 container_of(work, struct max98090_priv,
2007 pll_det_enable_work.work);
2008 struct snd_soc_codec *codec = max98090->codec;
2009 unsigned int status, mask;
2010
2011 /*
2012 * Clear status register in order to clear possibly already occurred
2013 * PLL unlock. If PLL hasn't still locked, the status will be set
2014 * again and PLL unlock interrupt will occur.
2015 * Note this will clear all status bits
2016 */
2017 regmap_read(max98090->regmap, M98090_REG_DEVICE_STATUS, &status);
2018
2019 /*
2020 * Queue jack work in case jack state has just changed but handler
2021 * hasn't run yet
2022 */
2023 regmap_read(max98090->regmap, M98090_REG_INTERRUPT_S, &mask);
2024 status &= mask;
2025 if (status & M98090_JDET_MASK)
2026 queue_delayed_work(system_power_efficient_wq,
2027 &max98090->jack_work,
2028 msecs_to_jiffies(100));
2029
2030 /* Enable PLL unlock interrupt */
2031 snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
2032 M98090_IULK_MASK,
2033 1 << M98090_IULK_SHIFT);
2034}
2035
2036static void max98090_pll_det_disable_work(struct work_struct *work)
2037{
2038 struct max98090_priv *max98090 =
2039 container_of(work, struct max98090_priv, pll_det_disable_work);
2040 struct snd_soc_codec *codec = max98090->codec;
2041
2042 cancel_delayed_work_sync(&max98090->pll_det_enable_work);
2043
2044 /* Disable PLL unlock interrupt */
2045 snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
2046 M98090_IULK_MASK, 0);
2047}
2048
2049static void max98090_pll_work(struct work_struct *work)
2050{
2051 struct max98090_priv *max98090 =
2052 container_of(work, struct max98090_priv, pll_work);
2053 struct snd_soc_codec *codec = max98090->codec;
2054
2055 if (!snd_soc_codec_is_active(codec))
2056 return;
2057
2058 dev_info(codec->dev, "PLL unlocked\n");
2059
2060 /* Toggle shutdown OFF then ON */
2061 snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
2062 M98090_SHDNN_MASK, 0);
2063 msleep(10);
2064 snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
2065 M98090_SHDNN_MASK, M98090_SHDNN_MASK);
2066
2067 /* Give PLL time to lock */
2068 msleep(10);
2069}
2070
1975static void max98090_jack_work(struct work_struct *work) 2071static void max98090_jack_work(struct work_struct *work)
1976{ 2072{
1977 struct max98090_priv *max98090 = container_of(work, 2073 struct max98090_priv *max98090 = container_of(work,
@@ -2103,8 +2199,10 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
2103 if (active & M98090_SLD_MASK) 2199 if (active & M98090_SLD_MASK)
2104 dev_dbg(codec->dev, "M98090_SLD_MASK\n"); 2200 dev_dbg(codec->dev, "M98090_SLD_MASK\n");
2105 2201
2106 if (active & M98090_ULK_MASK) 2202 if (active & M98090_ULK_MASK) {
2107 dev_err(codec->dev, "M98090_ULK_MASK\n"); 2203 dev_dbg(codec->dev, "M98090_ULK_MASK\n");
2204 schedule_work(&max98090->pll_work);
2205 }
2108 2206
2109 if (active & M98090_JDET_MASK) { 2207 if (active & M98090_JDET_MASK) {
2110 dev_dbg(codec->dev, "M98090_JDET_MASK\n"); 2208 dev_dbg(codec->dev, "M98090_JDET_MASK\n");
@@ -2177,6 +2275,7 @@ static struct snd_soc_dai_ops max98090_dai_ops = {
2177 .set_tdm_slot = max98090_set_tdm_slot, 2275 .set_tdm_slot = max98090_set_tdm_slot,
2178 .hw_params = max98090_dai_hw_params, 2276 .hw_params = max98090_dai_hw_params,
2179 .digital_mute = max98090_dai_digital_mute, 2277 .digital_mute = max98090_dai_digital_mute,
2278 .trigger = max98090_dai_trigger,
2180}; 2279};
2181 2280
2182static struct snd_soc_dai_driver max98090_dai[] = { 2281static struct snd_soc_dai_driver max98090_dai[] = {
@@ -2258,6 +2357,11 @@ static int max98090_probe(struct snd_soc_codec *codec)
2258 max98090->jack_state = M98090_JACK_STATE_NO_HEADSET; 2357 max98090->jack_state = M98090_JACK_STATE_NO_HEADSET;
2259 2358
2260 INIT_DELAYED_WORK(&max98090->jack_work, max98090_jack_work); 2359 INIT_DELAYED_WORK(&max98090->jack_work, max98090_jack_work);
2360 INIT_DELAYED_WORK(&max98090->pll_det_enable_work,
2361 max98090_pll_det_enable_work);
2362 INIT_WORK(&max98090->pll_det_disable_work,
2363 max98090_pll_det_disable_work);
2364 INIT_WORK(&max98090->pll_work, max98090_pll_work);
2261 2365
2262 /* Enable jack detection */ 2366 /* Enable jack detection */
2263 snd_soc_write(codec, M98090_REG_JACK_DETECT, 2367 snd_soc_write(codec, M98090_REG_JACK_DETECT,
@@ -2310,6 +2414,9 @@ static int max98090_remove(struct snd_soc_codec *codec)
2310 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); 2414 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
2311 2415
2312 cancel_delayed_work_sync(&max98090->jack_work); 2416 cancel_delayed_work_sync(&max98090->jack_work);
2417 cancel_delayed_work_sync(&max98090->pll_det_enable_work);
2418 cancel_work_sync(&max98090->pll_det_disable_work);
2419 cancel_work_sync(&max98090->pll_work);
2313 2420
2314 return 0; 2421 return 0;
2315} 2422}
diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h
index cf1b6062ba8c..14427a566f41 100644
--- a/sound/soc/codecs/max98090.h
+++ b/sound/soc/codecs/max98090.h
@@ -1532,6 +1532,9 @@ struct max98090_priv {
1532 int irq; 1532 int irq;
1533 int jack_state; 1533 int jack_state;
1534 struct delayed_work jack_work; 1534 struct delayed_work jack_work;
1535 struct delayed_work pll_det_enable_work;
1536 struct work_struct pll_det_disable_work;
1537 struct work_struct pll_work;
1535 struct snd_soc_jack *jack; 1538 struct snd_soc_jack *jack;
1536 unsigned int dai_fmt; 1539 unsigned int dai_fmt;
1537 int tdm_slots; 1540 int tdm_slots;
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/byt-max98090.c b/sound/soc/intel/byt-max98090.c
index b8b8af571ef1..d52681e7225e 100644
--- a/sound/soc/intel/byt-max98090.c
+++ b/sound/soc/intel/byt-max98090.c
@@ -139,6 +139,7 @@ static struct snd_soc_card byt_max98090_card = {
139 .num_dapm_routes = ARRAY_SIZE(byt_max98090_audio_map), 139 .num_dapm_routes = ARRAY_SIZE(byt_max98090_audio_map),
140 .controls = byt_max98090_controls, 140 .controls = byt_max98090_controls,
141 .num_controls = ARRAY_SIZE(byt_max98090_controls), 141 .num_controls = ARRAY_SIZE(byt_max98090_controls),
142 .fully_routed = true,
142}; 143};
143 144
144static int byt_max98090_probe(struct platform_device *pdev) 145static int byt_max98090_probe(struct platform_device *pdev)
diff --git a/sound/soc/intel/byt-rt5640.c b/sound/soc/intel/byt-rt5640.c
index 234a58de3c53..c323a101214e 100644
--- a/sound/soc/intel/byt-rt5640.c
+++ b/sound/soc/intel/byt-rt5640.c
@@ -17,6 +17,7 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/acpi.h> 18#include <linux/acpi.h>
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/dmi.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <sound/pcm.h> 22#include <sound/pcm.h>
22#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
@@ -36,8 +37,6 @@ static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
36static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { 37static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
37 {"Headset Mic", NULL, "MICBIAS1"}, 38 {"Headset Mic", NULL, "MICBIAS1"},
38 {"IN2P", NULL, "Headset Mic"}, 39 {"IN2P", NULL, "Headset Mic"},
39 {"IN2N", NULL, "Headset Mic"},
40 {"DMIC1", NULL, "Internal Mic"},
41 {"Headphone", NULL, "HPOL"}, 40 {"Headphone", NULL, "HPOL"},
42 {"Headphone", NULL, "HPOR"}, 41 {"Headphone", NULL, "HPOR"},
43 {"Speaker", NULL, "SPOLP"}, 42 {"Speaker", NULL, "SPOLP"},
@@ -46,6 +45,22 @@ static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
46 {"Speaker", NULL, "SPORN"}, 45 {"Speaker", NULL, "SPORN"},
47}; 46};
48 47
48static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
49 {"DMIC1", NULL, "Internal Mic"},
50};
51
52static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
53 {"Internal Mic", NULL, "MICBIAS1"},
54 {"IN1P", NULL, "Internal Mic"},
55};
56
57enum {
58 BYT_RT5640_DMIC1_MAP,
59 BYT_RT5640_IN1_MAP,
60};
61
62static unsigned long byt_rt5640_custom_map = BYT_RT5640_DMIC1_MAP;
63
49static const struct snd_kcontrol_new byt_rt5640_controls[] = { 64static const struct snd_kcontrol_new byt_rt5640_controls[] = {
50 SOC_DAPM_PIN_SWITCH("Headphone"), 65 SOC_DAPM_PIN_SWITCH("Headphone"),
51 SOC_DAPM_PIN_SWITCH("Headset Mic"), 66 SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -77,12 +92,32 @@ static int byt_rt5640_hw_params(struct snd_pcm_substream *substream,
77 return 0; 92 return 0;
78} 93}
79 94
95static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
96{
97 byt_rt5640_custom_map = (unsigned long)id->driver_data;
98 return 1;
99}
100
101static const struct dmi_system_id byt_rt5640_quirk_table[] = {
102 {
103 .callback = byt_rt5640_quirk_cb,
104 .matches = {
105 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
106 DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
107 },
108 .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP,
109 },
110 {}
111};
112
80static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) 113static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
81{ 114{
82 int ret; 115 int ret;
83 struct snd_soc_codec *codec = runtime->codec; 116 struct snd_soc_codec *codec = runtime->codec;
84 struct snd_soc_dapm_context *dapm = &codec->dapm; 117 struct snd_soc_dapm_context *dapm = &codec->dapm;
85 struct snd_soc_card *card = runtime->card; 118 struct snd_soc_card *card = runtime->card;
119 const struct snd_soc_dapm_route *custom_map;
120 int num_routes;
86 121
87 card->dapm.idle_bias_off = true; 122 card->dapm.idle_bias_off = true;
88 123
@@ -93,6 +128,21 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
93 return ret; 128 return ret;
94 } 129 }
95 130
131 dmi_check_system(byt_rt5640_quirk_table);
132 switch (byt_rt5640_custom_map) {
133 case BYT_RT5640_IN1_MAP:
134 custom_map = byt_rt5640_intmic_in1_map;
135 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
136 break;
137 default:
138 custom_map = byt_rt5640_intmic_dmic1_map;
139 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
140 };
141
142 ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes);
143 if (ret)
144 return ret;
145
96 snd_soc_dapm_ignore_suspend(dapm, "HPOL"); 146 snd_soc_dapm_ignore_suspend(dapm, "HPOL");
97 snd_soc_dapm_ignore_suspend(dapm, "HPOR"); 147 snd_soc_dapm_ignore_suspend(dapm, "HPOR");
98 148
diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c
new file mode 100644
index 000000000000..7104a34181a9
--- /dev/null
+++ b/sound/soc/intel/sst-atom-controls.c
@@ -0,0 +1,218 @@
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
28static int sst_fill_byte_control(struct sst_data *drv,
29 u8 ipc_msg, u8 block,
30 u8 task_id, u8 pipe_id,
31 u16 len, void *cmd_data)
32{
33 struct snd_sst_bytes_v2 *byte_data = drv->byte_stream;
34
35 byte_data->type = SST_CMD_BYTES_SET;
36 byte_data->ipc_msg = ipc_msg;
37 byte_data->block = block;
38 byte_data->task_id = task_id;
39 byte_data->pipe_id = pipe_id;
40
41 if (len > SST_MAX_BIN_BYTES - sizeof(*byte_data)) {
42 dev_err(&drv->pdev->dev, "command length too big (%u)", len);
43 return -EINVAL;
44 }
45 byte_data->len = len;
46 memcpy(byte_data->bytes, cmd_data, len);
47 print_hex_dump_bytes("writing to lpe: ", DUMP_PREFIX_OFFSET,
48 byte_data, len + sizeof(*byte_data));
49 return 0;
50}
51
52static int sst_fill_and_send_cmd_unlocked(struct sst_data *drv,
53 u8 ipc_msg, u8 block, u8 task_id, u8 pipe_id,
54 void *cmd_data, u16 len)
55{
56 int ret = 0;
57
58 ret = sst_fill_byte_control(drv, ipc_msg,
59 block, task_id, pipe_id, len, cmd_data);
60 if (ret < 0)
61 return ret;
62 return sst->ops->send_byte_stream(sst->dev, drv->byte_stream);
63}
64
65/**
66 * sst_fill_and_send_cmd - generate the IPC message and send it to the FW
67 * @ipc_msg: type of IPC (CMD, SET_PARAMS, GET_PARAMS)
68 * @cmd_data: the IPC payload
69 */
70static int sst_fill_and_send_cmd(struct sst_data *drv,
71 u8 ipc_msg, u8 block, u8 task_id, u8 pipe_id,
72 void *cmd_data, u16 len)
73{
74 int ret;
75
76 mutex_lock(&drv->lock);
77 ret = sst_fill_and_send_cmd_unlocked(drv, ipc_msg, block,
78 task_id, pipe_id, cmd_data, len);
79 mutex_unlock(&drv->lock);
80
81 return ret;
82}
83
84static int sst_send_algo_cmd(struct sst_data *drv,
85 struct sst_algo_control *bc)
86{
87 int len, ret = 0;
88 struct sst_cmd_set_params *cmd;
89
90 /*bc->max includes sizeof algos + length field*/
91 len = sizeof(cmd->dst) + sizeof(cmd->command_id) + bc->max;
92
93 cmd = kzalloc(len, GFP_KERNEL);
94 if (cmd == NULL)
95 return -ENOMEM;
96
97 SST_FILL_DESTINATION(2, cmd->dst, bc->pipe_id, bc->module_id);
98 cmd->command_id = bc->cmd_id;
99 memcpy(cmd->params, bc->params, bc->max);
100
101 ret = sst_fill_and_send_cmd_unlocked(drv, SST_IPC_IA_SET_PARAMS,
102 SST_FLAG_BLOCKED, bc->task_id, 0, cmd, len);
103 kfree(cmd);
104 return ret;
105}
106
107static int sst_algo_bytes_ctl_info(struct snd_kcontrol *kcontrol,
108 struct snd_ctl_elem_info *uinfo)
109{
110 struct sst_algo_control *bc = (void *)kcontrol->private_value;
111
112 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
113 uinfo->count = bc->max;
114
115 return 0;
116}
117
118static int sst_algo_control_get(struct snd_kcontrol *kcontrol,
119 struct snd_ctl_elem_value *ucontrol)
120{
121 struct sst_algo_control *bc = (void *)kcontrol->private_value;
122 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
123
124 switch (bc->type) {
125 case SST_ALGO_PARAMS:
126 memcpy(ucontrol->value.bytes.data, bc->params, bc->max);
127 break;
128 default:
129 dev_err(component->dev, "Invalid Input- algo type:%d\n",
130 bc->type);
131 return -EINVAL;
132
133 }
134 return 0;
135}
136
137static int sst_algo_control_set(struct snd_kcontrol *kcontrol,
138 struct snd_ctl_elem_value *ucontrol)
139{
140 int ret = 0;
141 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
142 struct sst_data *drv = snd_soc_component_get_drvdata(cmpnt);
143 struct sst_algo_control *bc = (void *)kcontrol->private_value;
144
145 dev_dbg(cmpnt->dev, "control_name=%s\n", kcontrol->id.name);
146 mutex_lock(&drv->lock);
147 switch (bc->type) {
148 case SST_ALGO_PARAMS:
149 memcpy(bc->params, ucontrol->value.bytes.data, bc->max);
150 break;
151 default:
152 mutex_unlock(&drv->lock);
153 dev_err(cmpnt->dev, "Invalid Input- algo type:%d\n",
154 bc->type);
155 return -EINVAL;
156 }
157 /*if pipe is enabled, need to send the algo params from here*/
158 if (bc->w && bc->w->power)
159 ret = sst_send_algo_cmd(drv, bc);
160 mutex_unlock(&drv->lock);
161
162 return ret;
163}
164
165static const struct snd_kcontrol_new sst_algo_controls[] = {
166 SST_ALGO_KCONTROL_BYTES("media_loop1_out", "fir", 272, SST_MODULE_ID_FIR_24,
167 SST_PATH_INDEX_MEDIA_LOOP1_OUT, 0, SST_TASK_SBA, SBA_VB_SET_FIR),
168 SST_ALGO_KCONTROL_BYTES("media_loop1_out", "iir", 300, SST_MODULE_ID_IIR_24,
169 SST_PATH_INDEX_MEDIA_LOOP1_OUT, 0, SST_TASK_SBA, SBA_VB_SET_IIR),
170 SST_ALGO_KCONTROL_BYTES("media_loop1_out", "mdrp", 286, SST_MODULE_ID_MDRP,
171 SST_PATH_INDEX_MEDIA_LOOP1_OUT, 0, SST_TASK_SBA, SBA_SET_MDRP),
172 SST_ALGO_KCONTROL_BYTES("media_loop2_out", "fir", 272, SST_MODULE_ID_FIR_24,
173 SST_PATH_INDEX_MEDIA_LOOP2_OUT, 0, SST_TASK_SBA, SBA_VB_SET_FIR),
174 SST_ALGO_KCONTROL_BYTES("media_loop2_out", "iir", 300, SST_MODULE_ID_IIR_24,
175 SST_PATH_INDEX_MEDIA_LOOP2_OUT, 0, SST_TASK_SBA, SBA_VB_SET_IIR),
176 SST_ALGO_KCONTROL_BYTES("media_loop2_out", "mdrp", 286, SST_MODULE_ID_MDRP,
177 SST_PATH_INDEX_MEDIA_LOOP2_OUT, 0, SST_TASK_SBA, SBA_SET_MDRP),
178 SST_ALGO_KCONTROL_BYTES("sprot_loop_out", "lpro", 192, SST_MODULE_ID_SPROT,
179 SST_PATH_INDEX_SPROT_LOOP_OUT, 0, SST_TASK_SBA, SBA_VB_LPRO),
180 SST_ALGO_KCONTROL_BYTES("codec_in0", "dcr", 52, SST_MODULE_ID_FILT_DCR,
181 SST_PATH_INDEX_CODEC_IN0, 0, SST_TASK_SBA, SBA_VB_SET_IIR),
182 SST_ALGO_KCONTROL_BYTES("codec_in1", "dcr", 52, SST_MODULE_ID_FILT_DCR,
183 SST_PATH_INDEX_CODEC_IN1, 0, SST_TASK_SBA, SBA_VB_SET_IIR),
184
185};
186
187static int sst_algo_control_init(struct device *dev)
188{
189 int i = 0;
190 struct sst_algo_control *bc;
191 /*allocate space to cache the algo parameters in the driver*/
192 for (i = 0; i < ARRAY_SIZE(sst_algo_controls); i++) {
193 bc = (struct sst_algo_control *)sst_algo_controls[i].private_value;
194 bc->params = devm_kzalloc(dev, bc->max, GFP_KERNEL);
195 if (bc->params == NULL)
196 return -ENOMEM;
197 }
198 return 0;
199}
200
201int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform)
202{
203 int ret = 0;
204 struct sst_data *drv = snd_soc_platform_get_drvdata(platform);
205
206 drv->byte_stream = devm_kzalloc(platform->dev,
207 SST_MAX_BIN_BYTES, GFP_KERNEL);
208 if (!drv->byte_stream)
209 return -ENOMEM;
210
211 /*Initialize algo control params*/
212 ret = sst_algo_control_init(platform->dev);
213 if (ret)
214 return ret;
215 ret = snd_soc_add_platform_controls(platform, sst_algo_controls,
216 ARRAY_SIZE(sst_algo_controls));
217 return ret;
218}
diff --git a/sound/soc/intel/sst-atom-controls.h b/sound/soc/intel/sst-atom-controls.h
index 14063ab8c7c5..a73e894b175c 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,423 @@
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};
311
312#define SST_FILL_LOCATION_IDS(dst, cell_idx, pipe_id) do { \
313 dst.location_id.p.cell_nbr_idx = (cell_idx); \
314 dst.location_id.p.path_id = (pipe_id); \
315 } while (0)
316#define SST_FILL_LOCATION_ID(dst, loc_id) (\
317 dst.location_id.f = (loc_id))
318#define SST_FILL_MODULE_ID(dst, mod_id) (\
319 dst.module_id = (mod_id))
320
321#define SST_FILL_DESTINATION1(dst, id) do { \
322 SST_FILL_LOCATION_ID(dst, (id) & 0xFFFF); \
323 SST_FILL_MODULE_ID(dst, ((id) & 0xFFFF0000) >> 16); \
324 } while (0)
325#define SST_FILL_DESTINATION2(dst, loc_id, mod_id) do { \
326 SST_FILL_LOCATION_ID(dst, loc_id); \
327 SST_FILL_MODULE_ID(dst, mod_id); \
328 } while (0)
329#define SST_FILL_DESTINATION3(dst, cell_idx, path_id, mod_id) do { \
330 SST_FILL_LOCATION_IDS(dst, cell_idx, path_id); \
331 SST_FILL_MODULE_ID(dst, mod_id); \
332 } while (0)
333
334#define SST_FILL_DESTINATION(level, dst, ...) \
335 SST_FILL_DESTINATION##level(dst, __VA_ARGS__)
336#define SST_FILL_DEFAULT_DESTINATION(dst) \
337 SST_FILL_DESTINATION(2, dst, SST_DEFAULT_LOCATION_ID, SST_DEFAULT_MODULE_ID)
338
339struct sst_destination_id {
340 union sst_location_id {
341 struct {
342 u8 cell_nbr_idx; /* module index */
343 u8 path_id; /* pipe_id */
344 } __packed p; /* part */
345 u16 f; /* full */
346 } __packed location_id;
347 u16 module_id;
348} __packed;
349struct sst_dsp_header {
350 struct sst_destination_id dst;
351 u16 command_id;
352 u16 length;
353} __packed;
354
355/*
356 *
357 * Common Commands
358 *
359 */
360struct sst_cmd_generic {
361 struct sst_dsp_header header;
362} __packed;
363struct sst_cmd_set_params {
364 struct sst_destination_id dst;
365 u16 command_id;
366 char params[0];
367} __packed;
368#define SST_CONTROL_NAME(xpname, xmname, xinstance, xtype) \
369 xpname " " xmname " " #xinstance " " xtype
370
371#define SST_COMBO_CONTROL_NAME(xpname, xmname, xinstance, xtype, xsubmodule) \
372 xpname " " xmname " " #xinstance " " xtype " " xsubmodule
373enum sst_algo_kcontrol_type {
374 SST_ALGO_PARAMS,
375 SST_ALGO_BYPASS,
376};
377
378struct sst_algo_control {
379 enum sst_algo_kcontrol_type type;
380 int max;
381 u16 module_id;
382 u16 pipe_id;
383 u16 task_id;
384 u16 cmd_id;
385 bool bypass;
386 unsigned char *params;
387 struct snd_soc_dapm_widget *w;
388};
389
390/* size of the control = size of params + size of length field */
391#define SST_ALGO_CTL_VALUE(xcount, xtype, xpipe, xmod, xtask, xcmd) \
392 (struct sst_algo_control){ \
393 .max = xcount + sizeof(u16), .type = xtype, .module_id = xmod, \
394 .pipe_id = xpipe, .task_id = xtask, .cmd_id = xcmd, \
395 }
396
397#define SST_ALGO_KCONTROL(xname, xcount, xmod, xpipe, \
398 xtask, xcmd, xtype, xinfo, xget, xput) \
399{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
400 .name = xname, \
401 .info = xinfo, .get = xget, .put = xput, \
402 .private_value = (unsigned long)& \
403 SST_ALGO_CTL_VALUE(xcount, xtype, xpipe, \
404 xmod, xtask, xcmd), \
405}
406
407#define SST_ALGO_KCONTROL_BYTES(xpname, xmname, xcount, xmod, \
408 xpipe, xinstance, xtask, xcmd) \
409 SST_ALGO_KCONTROL(SST_CONTROL_NAME(xpname, xmname, xinstance, "params"), \
410 xcount, xmod, xpipe, xtask, xcmd, SST_ALGO_PARAMS, \
411 sst_algo_bytes_ctl_info, \
412 sst_algo_control_get, sst_algo_control_set)
413
414#define SST_ALGO_KCONTROL_BOOL(xpname, xmname, xmod, xpipe, xinstance, xtask) \
415 SST_ALGO_KCONTROL(SST_CONTROL_NAME(xpname, xmname, xinstance, "bypass"), \
416 0, xmod, xpipe, xtask, 0, SST_ALGO_BYPASS, \
417 snd_soc_info_bool_ext, \
418 sst_algo_control_get, sst_algo_control_set)
419
420#define SST_ALGO_BYPASS_PARAMS(xpname, xmname, xcount, xmod, xpipe, \
421 xinstance, xtask, xcmd) \
422 SST_ALGO_KCONTROL_BOOL(xpname, xmname, xmod, xpipe, xinstance, xtask), \
423 SST_ALGO_KCONTROL_BYTES(xpname, xmname, xcount, xmod, xpipe, xinstance, xtask, xcmd)
424
425#define SST_COMBO_ALGO_KCONTROL_BYTES(xpname, xmname, xsubmod, xcount, xmod, \
426 xpipe, xinstance, xtask, xcmd) \
427 SST_ALGO_KCONTROL(SST_COMBO_CONTROL_NAME(xpname, xmname, xinstance, "params", \
428 xsubmod), \
429 xcount, xmod, xpipe, xtask, xcmd, SST_ALGO_PARAMS, \
430 sst_algo_bytes_ctl_info, \
431 sst_algo_control_get, sst_algo_control_set)
432
433
434struct sst_enum {
435 bool tx;
436 unsigned short reg;
437 unsigned int max;
438 const char * const *texts;
439 struct snd_soc_dapm_widget *w;
440};
29 441
30#endif 442#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..aa9b600dfc9b 100644
--- a/sound/soc/intel/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/sst-mfld-platform-pcm.c
@@ -43,12 +43,12 @@ int sst_register_dsp(struct sst_device *dev)
43 return -ENODEV; 43 return -ENODEV;
44 mutex_lock(&sst_lock); 44 mutex_lock(&sst_lock);
45 if (sst) { 45 if (sst) {
46 pr_err("we already have a device %s\n", sst->name); 46 dev_err(dev->dev, "we already have a device %s\n", sst->name);
47 module_put(dev->dev->driver->owner); 47 module_put(dev->dev->driver->owner);
48 mutex_unlock(&sst_lock); 48 mutex_unlock(&sst_lock);
49 return -EEXIST; 49 return -EEXIST;
50 } 50 }
51 pr_debug("registering device %s\n", dev->name); 51 dev_dbg(dev->dev, "registering device %s\n", dev->name);
52 sst = dev; 52 sst = dev;
53 mutex_unlock(&sst_lock); 53 mutex_unlock(&sst_lock);
54 return 0; 54 return 0;
@@ -70,7 +70,7 @@ int sst_unregister_dsp(struct sst_device *dev)
70 } 70 }
71 71
72 module_put(sst->dev->driver->owner); 72 module_put(sst->dev->driver->owner);
73 pr_debug("unreg %s\n", sst->name); 73 dev_dbg(dev->dev, "unreg %s\n", sst->name);
74 sst = NULL; 74 sst = NULL;
75 mutex_unlock(&sst_lock); 75 mutex_unlock(&sst_lock);
76 return 0; 76 return 0;
@@ -252,7 +252,7 @@ int sst_fill_stream_params(void *substream,
252} 252}
253 253
254static int sst_platform_alloc_stream(struct snd_pcm_substream *substream, 254static int sst_platform_alloc_stream(struct snd_pcm_substream *substream,
255 struct snd_soc_platform *platform) 255 struct snd_soc_dai *dai)
256{ 256{
257 struct sst_runtime_stream *stream = 257 struct sst_runtime_stream *stream =
258 substream->runtime->private_data; 258 substream->runtime->private_data;
@@ -260,7 +260,7 @@ static int sst_platform_alloc_stream(struct snd_pcm_substream *substream,
260 struct snd_sst_params str_params = {0}; 260 struct snd_sst_params str_params = {0};
261 struct snd_sst_alloc_params_ext alloc_params = {0}; 261 struct snd_sst_alloc_params_ext alloc_params = {0};
262 int ret_val = 0; 262 int ret_val = 0;
263 struct sst_data *ctx = snd_soc_platform_get_drvdata(platform); 263 struct sst_data *ctx = snd_soc_dai_get_drvdata(dai);
264 264
265 /* set codec params and inform SST driver the same */ 265 /* set codec params and inform SST driver the same */
266 sst_fill_pcm_params(substream, &param); 266 sst_fill_pcm_params(substream, &param);
@@ -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
@@ -306,22 +306,31 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream)
306{ 306{
307 struct sst_runtime_stream *stream = 307 struct sst_runtime_stream *stream =
308 substream->runtime->private_data; 308 substream->runtime->private_data;
309 struct snd_soc_pcm_runtime *rtd = substream->private_data;
309 int ret_val; 310 int ret_val;
310 311
311 pr_debug("setting buffer ptr param\n"); 312 dev_dbg(rtd->dev, "setting buffer ptr param\n");
312 sst_set_stream_status(stream, SST_PLATFORM_INIT); 313 sst_set_stream_status(stream, SST_PLATFORM_INIT);
313 stream->stream_info.period_elapsed = sst_period_elapsed; 314 stream->stream_info.period_elapsed = sst_period_elapsed;
314 stream->stream_info.arg = substream; 315 stream->stream_info.arg = substream;
315 stream->stream_info.buffer_ptr = 0; 316 stream->stream_info.buffer_ptr = 0;
316 stream->stream_info.sfreq = substream->runtime->rate; 317 stream->stream_info.sfreq = substream->runtime->rate;
317 ret_val = stream->ops->device_control( 318 ret_val = stream->ops->stream_init(sst->dev, &stream->stream_info);
318 SST_SND_STREAM_INIT, &stream->stream_info);
319 if (ret_val) 319 if (ret_val)
320 pr_err("control_set ret error %d\n", ret_val); 320 dev_err(rtd->dev, "control_set ret error %d\n", ret_val);
321 return ret_val; 321 return ret_val;
322 322
323} 323}
324/* end -- helper functions */ 324
325static int power_up_sst(struct sst_runtime_stream *stream)
326{
327 return stream->ops->power(sst->dev, true);
328}
329
330static void power_down_sst(struct sst_runtime_stream *stream)
331{
332 stream->ops->power(sst->dev, false);
333}
325 334
326static int sst_media_open(struct snd_pcm_substream *substream, 335static int sst_media_open(struct snd_pcm_substream *substream,
327 struct snd_soc_dai *dai) 336 struct snd_soc_dai *dai)
@@ -339,7 +348,7 @@ static int sst_media_open(struct snd_pcm_substream *substream,
339 mutex_lock(&sst_lock); 348 mutex_lock(&sst_lock);
340 if (!sst || 349 if (!sst ||
341 !try_module_get(sst->dev->driver->owner)) { 350 !try_module_get(sst->dev->driver->owner)) {
342 pr_err("no device available to run\n"); 351 dev_err(dai->dev, "no device available to run\n");
343 ret_val = -ENODEV; 352 ret_val = -ENODEV;
344 goto out_ops; 353 goto out_ops;
345 } 354 }
@@ -352,6 +361,10 @@ static int sst_media_open(struct snd_pcm_substream *substream,
352 /* allocate memory for SST API set */ 361 /* allocate memory for SST API set */
353 runtime->private_data = stream; 362 runtime->private_data = stream;
354 363
364 ret_val = power_up_sst(stream);
365 if (ret_val < 0)
366 return ret_val;
367
355 /* Make sure, that the period size is always even */ 368 /* Make sure, that the period size is always even */
356 snd_pcm_hw_constraint_step(substream->runtime, 0, 369 snd_pcm_hw_constraint_step(substream->runtime, 0,
357 SNDRV_PCM_HW_PARAM_PERIODS, 2); 370 SNDRV_PCM_HW_PARAM_PERIODS, 2);
@@ -371,26 +384,29 @@ static void sst_media_close(struct snd_pcm_substream *substream,
371 int ret_val = 0, str_id; 384 int ret_val = 0, str_id;
372 385
373 stream = substream->runtime->private_data; 386 stream = substream->runtime->private_data;
387 power_down_sst(stream);
388
374 str_id = stream->stream_info.str_id; 389 str_id = stream->stream_info.str_id;
375 if (str_id) 390 if (str_id)
376 ret_val = stream->ops->close(str_id); 391 ret_val = stream->ops->close(sst->dev, str_id);
377 module_put(sst->dev->driver->owner); 392 module_put(sst->dev->driver->owner);
378 kfree(stream); 393 kfree(stream);
379} 394}
380 395
381static inline unsigned int get_current_pipe_id(struct snd_soc_platform *platform, 396static inline unsigned int get_current_pipe_id(struct snd_soc_dai *dai,
382 struct snd_pcm_substream *substream) 397 struct snd_pcm_substream *substream)
383{ 398{
384 struct sst_data *sst = snd_soc_platform_get_drvdata(platform); 399 struct sst_data *sst = snd_soc_dai_get_drvdata(dai);
385 struct sst_dev_stream_map *map = sst->pdata->pdev_strm_map; 400 struct sst_dev_stream_map *map = sst->pdata->pdev_strm_map;
386 struct sst_runtime_stream *stream = 401 struct sst_runtime_stream *stream =
387 substream->runtime->private_data; 402 substream->runtime->private_data;
388 u32 str_id = stream->stream_info.str_id; 403 u32 str_id = stream->stream_info.str_id;
389 unsigned int pipe_id; 404 unsigned int pipe_id;
405
390 pipe_id = map[str_id].device_id; 406 pipe_id = map[str_id].device_id;
391 407
392 pr_debug("%s: got pipe_id = %#x for str_id = %d\n", 408 dev_dbg(dai->dev, "got pipe_id = %#x for str_id = %d\n",
393 __func__, pipe_id, str_id); 409 pipe_id, str_id);
394 return pipe_id; 410 return pipe_id;
395} 411}
396 412
@@ -403,12 +419,11 @@ static int sst_media_prepare(struct snd_pcm_substream *substream,
403 stream = substream->runtime->private_data; 419 stream = substream->runtime->private_data;
404 str_id = stream->stream_info.str_id; 420 str_id = stream->stream_info.str_id;
405 if (stream->stream_info.str_id) { 421 if (stream->stream_info.str_id) {
406 ret_val = stream->ops->device_control( 422 ret_val = stream->ops->stream_drop(sst->dev, str_id);
407 SST_SND_DROP, &str_id);
408 return ret_val; 423 return ret_val;
409 } 424 }
410 425
411 ret_val = sst_platform_alloc_stream(substream, dai->platform); 426 ret_val = sst_platform_alloc_stream(substream, dai);
412 if (ret_val <= 0) 427 if (ret_val <= 0)
413 return ret_val; 428 return ret_val;
414 snprintf(substream->pcm->id, sizeof(substream->pcm->id), 429 snprintf(substream->pcm->id, sizeof(substream->pcm->id),
@@ -461,37 +476,40 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
461{ 476{
462 int ret_val = 0, str_id; 477 int ret_val = 0, str_id;
463 struct sst_runtime_stream *stream; 478 struct sst_runtime_stream *stream;
464 int str_cmd, status; 479 int status;
480 struct snd_soc_pcm_runtime *rtd = substream->private_data;
465 481
466 pr_debug("sst_platform_pcm_trigger called\n"); 482 dev_dbg(rtd->dev, "sst_platform_pcm_trigger called\n");
483 if (substream->pcm->internal)
484 return 0;
467 stream = substream->runtime->private_data; 485 stream = substream->runtime->private_data;
468 str_id = stream->stream_info.str_id; 486 str_id = stream->stream_info.str_id;
469 switch (cmd) { 487 switch (cmd) {
470 case SNDRV_PCM_TRIGGER_START: 488 case SNDRV_PCM_TRIGGER_START:
471 pr_debug("sst: Trigger Start\n"); 489 dev_dbg(rtd->dev, "sst: Trigger Start\n");
472 str_cmd = SST_SND_START;
473 status = SST_PLATFORM_RUNNING; 490 status = SST_PLATFORM_RUNNING;
474 stream->stream_info.arg = substream; 491 stream->stream_info.arg = substream;
492 ret_val = stream->ops->stream_start(sst->dev, str_id);
475 break; 493 break;
476 case SNDRV_PCM_TRIGGER_STOP: 494 case SNDRV_PCM_TRIGGER_STOP:
477 pr_debug("sst: in stop\n"); 495 dev_dbg(rtd->dev, "sst: in stop\n");
478 str_cmd = SST_SND_DROP;
479 status = SST_PLATFORM_DROPPED; 496 status = SST_PLATFORM_DROPPED;
497 ret_val = stream->ops->stream_drop(sst->dev, str_id);
480 break; 498 break;
481 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 499 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
482 pr_debug("sst: in pause\n"); 500 dev_dbg(rtd->dev, "sst: in pause\n");
483 str_cmd = SST_SND_PAUSE;
484 status = SST_PLATFORM_PAUSED; 501 status = SST_PLATFORM_PAUSED;
502 ret_val = stream->ops->stream_pause(sst->dev, str_id);
485 break; 503 break;
486 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 504 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
487 pr_debug("sst: in pause release\n"); 505 dev_dbg(rtd->dev, "sst: in pause release\n");
488 str_cmd = SST_SND_RESUME;
489 status = SST_PLATFORM_RUNNING; 506 status = SST_PLATFORM_RUNNING;
507 ret_val = stream->ops->stream_pause_release(sst->dev, str_id);
490 break; 508 break;
491 default: 509 default:
492 return -EINVAL; 510 return -EINVAL;
493 } 511 }
494 ret_val = stream->ops->device_control(str_cmd, &str_id); 512
495 if (!ret_val) 513 if (!ret_val)
496 sst_set_stream_status(stream, status); 514 sst_set_stream_status(stream, status);
497 515
@@ -505,16 +523,16 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer
505 struct sst_runtime_stream *stream; 523 struct sst_runtime_stream *stream;
506 int ret_val, status; 524 int ret_val, status;
507 struct pcm_stream_info *str_info; 525 struct pcm_stream_info *str_info;
526 struct snd_soc_pcm_runtime *rtd = substream->private_data;
508 527
509 stream = substream->runtime->private_data; 528 stream = substream->runtime->private_data;
510 status = sst_get_stream_status(stream); 529 status = sst_get_stream_status(stream);
511 if (status == SST_PLATFORM_INIT) 530 if (status == SST_PLATFORM_INIT)
512 return 0; 531 return 0;
513 str_info = &stream->stream_info; 532 str_info = &stream->stream_info;
514 ret_val = stream->ops->device_control( 533 ret_val = stream->ops->stream_read_tstamp(sst->dev, str_info);
515 SST_SND_BUFFER_POINTER, str_info);
516 if (ret_val) { 534 if (ret_val) {
517 pr_err("sst: error code = %d\n", ret_val); 535 dev_err(rtd->dev, "sst: error code = %d\n", ret_val);
518 return ret_val; 536 return ret_val;
519 } 537 }
520 substream->runtime->delay = str_info->pcm_delay; 538 substream->runtime->delay = str_info->pcm_delay;
@@ -530,7 +548,7 @@ static struct snd_pcm_ops sst_platform_ops = {
530 548
531static void sst_pcm_free(struct snd_pcm *pcm) 549static void sst_pcm_free(struct snd_pcm *pcm)
532{ 550{
533 pr_debug("sst_pcm_free called\n"); 551 dev_dbg(pcm->dev, "sst_pcm_free called\n");
534 snd_pcm_lib_preallocate_free_for_all(pcm); 552 snd_pcm_lib_preallocate_free_for_all(pcm);
535} 553}
536 554
@@ -547,14 +565,20 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
547 snd_dma_continuous_data(GFP_DMA), 565 snd_dma_continuous_data(GFP_DMA),
548 SST_MIN_BUFFER, SST_MAX_BUFFER); 566 SST_MIN_BUFFER, SST_MAX_BUFFER);
549 if (retval) { 567 if (retval) {
550 pr_err("dma buffer allocationf fail\n"); 568 dev_err(rtd->dev, "dma buffer allocationf fail\n");
551 return retval; 569 return retval;
552 } 570 }
553 } 571 }
554 return retval; 572 return retval;
555} 573}
556 574
557static struct snd_soc_platform_driver sst_soc_platform_drv = { 575static int sst_soc_probe(struct snd_soc_platform *platform)
576{
577 return sst_dsp_init_v2_dpcm(platform);
578}
579
580static struct snd_soc_platform_driver sst_soc_platform_drv = {
581 .probe = sst_soc_probe,
558 .ops = &sst_platform_ops, 582 .ops = &sst_platform_ops,
559 .compr_ops = &sst_platform_compr_ops, 583 .compr_ops = &sst_platform_compr_ops,
560 .pcm_new = sst_pcm_new, 584 .pcm_new = sst_pcm_new,
@@ -574,13 +598,11 @@ static int sst_platform_probe(struct platform_device *pdev)
574 598
575 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); 599 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
576 if (drv == NULL) { 600 if (drv == NULL) {
577 pr_err("kzalloc failed\n");
578 return -ENOMEM; 601 return -ENOMEM;
579 } 602 }
580 603
581 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 604 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
582 if (pdata == NULL) { 605 if (pdata == NULL) {
583 pr_err("kzalloc failed for pdata\n");
584 return -ENOMEM; 606 return -ENOMEM;
585 } 607 }
586 608
@@ -592,14 +614,14 @@ static int sst_platform_probe(struct platform_device *pdev)
592 614
593 ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv); 615 ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv);
594 if (ret) { 616 if (ret) {
595 pr_err("registering soc platform failed\n"); 617 dev_err(&pdev->dev, "registering soc platform failed\n");
596 return ret; 618 return ret;
597 } 619 }
598 620
599 ret = snd_soc_register_component(&pdev->dev, &sst_component, 621 ret = snd_soc_register_component(&pdev->dev, &sst_component,
600 sst_platform_dai, ARRAY_SIZE(sst_platform_dai)); 622 sst_platform_dai, ARRAY_SIZE(sst_platform_dai));
601 if (ret) { 623 if (ret) {
602 pr_err("registering cpu dais failed\n"); 624 dev_err(&pdev->dev, "registering cpu dais failed\n");
603 snd_soc_unregister_platform(&pdev->dev); 625 snd_soc_unregister_platform(&pdev->dev);
604 } 626 }
605 return ret; 627 return ret;
@@ -610,7 +632,7 @@ static int sst_platform_remove(struct platform_device *pdev)
610 632
611 snd_soc_unregister_component(&pdev->dev); 633 snd_soc_unregister_component(&pdev->dev);
612 snd_soc_unregister_platform(&pdev->dev); 634 snd_soc_unregister_platform(&pdev->dev);
613 pr_debug("sst_platform_remove success\n"); 635 dev_dbg(&pdev->dev, "sst_platform_remove success\n");
614 return 0; 636 return 0;
615} 637}
616 638
diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/sst-mfld-platform.h
index 6c6a42c08e24..19f83ec51613 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,37 @@ 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);
132 int (*power)(struct device *dev, bool state);
134}; 133};
135 134
136struct sst_runtime_stream { 135struct sst_runtime_stream {
@@ -152,6 +151,8 @@ struct sst_device {
152}; 151};
153 152
154struct sst_data; 153struct sst_data;
154
155int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform);
155void sst_set_stream_status(struct sst_runtime_stream *stream, int state); 156void sst_set_stream_status(struct sst_runtime_stream *stream, int state);
156int sst_fill_stream_params(void *substream, const struct sst_data *ctx, 157int sst_fill_stream_params(void *substream, const struct sst_data *ctx,
157 struct snd_sst_params *str_params, bool is_compress); 158 struct snd_sst_params *str_params, bool is_compress);
@@ -166,6 +167,7 @@ struct sst_algo_int_control_v2 {
166struct sst_data { 167struct sst_data {
167 struct platform_device *pdev; 168 struct platform_device *pdev;
168 struct sst_platform_data *pdata; 169 struct sst_platform_data *pdata;
170 struct snd_sst_bytes_v2 *byte_stream;
169 struct mutex lock; 171 struct mutex lock;
170}; 172};
171int sst_register_dsp(struct sst_device *sst); 173int sst_register_dsp(struct sst_device *sst);
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 d4bfd4a9076f..1b422c5c36c8 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 453
481static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) 454static inline void soc_init_component_debugfs(
455 struct snd_soc_component *component)
482{ 456{
483} 457}
484 458
485static inline void soc_init_platform_debugfs(struct snd_soc_platform *platform) 459static inline void soc_cleanup_component_debugfs(
486{ 460 struct snd_soc_component *component)
487}
488
489static inline void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
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,111 @@ 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; 1090 struct snd_soc_component *dai_component, *component2;
1181 struct snd_soc_dai *dai; 1091 struct snd_soc_dai *dai;
1092 int ret;
1093
1094 if (component->probed)
1095 return 0;
1182 1096
1183 codec->component.card = card; 1097 component->card = card;
1184 codec->dapm.card = card; 1098 dapm->card = card;
1185 soc_set_name_prefix(card, &codec->component); 1099 soc_set_name_prefix(card, component);
1186 1100
1187 if (!try_module_get(codec->dev->driver->owner)) 1101 if (!try_module_get(component->dev->driver->owner))
1188 return -ENODEV; 1102 return -ENODEV;
1189 1103
1190 soc_init_codec_debugfs(codec); 1104 soc_init_component_debugfs(component);
1191 1105
1192 if (driver->dapm_widgets) { 1106 if (component->dapm_widgets) {
1193 ret = snd_soc_dapm_new_controls(&codec->dapm, 1107 ret = snd_soc_dapm_new_controls(dapm, component->dapm_widgets,
1194 driver->dapm_widgets, 1108 component->num_dapm_widgets);
1195 driver->num_dapm_widgets);
1196 1109
1197 if (ret != 0) { 1110 if (ret != 0) {
1198 dev_err(codec->dev, 1111 dev_err(component->dev,
1199 "Failed to create new controls %d\n", ret); 1112 "Failed to create new controls %d\n", ret);
1200 goto err_probe; 1113 goto err_probe;
1201 } 1114 }
1202 } 1115 }
1203 1116
1204 /* Create DAPM widgets for each DAI stream */ 1117 /*
1205 list_for_each_entry(dai, &codec->component.dai_list, list) { 1118 * This is rather ugly, but certain platforms expect that the DAPM
1206 ret = snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); 1119 * widgets for the DAIs for components with the same parent device are
1120 * created in the platforms DAPM context. Until that is fixed we need to
1121 * keep this.
1122 */
1123 if (component->steal_sibling_dai_widgets) {
1124 dai_component = NULL;
1125 list_for_each_entry(component2, &component_list, list) {
1126 if (component == component2)
1127 continue;
1207 1128
1208 if (ret != 0) { 1129 if (component2->dev == component->dev &&
1209 dev_err(codec->dev, 1130 !list_empty(&component2->dai_list)) {
1210 "Failed to create DAI widgets %d\n", ret); 1131 dai_component = component2;
1211 goto err_probe; 1132 break;
1133 }
1212 } 1134 }
1213 } 1135 } else {
1214 1136 dai_component = component;
1215 codec->dapm.idle_bias_off = driver->idle_bias_off; 1137 list_for_each_entry(component2, &component_list, list) {
1216 1138 if (component2->dev == component->dev &&
1217 if (driver->probe) { 1139 component2->steal_sibling_dai_widgets) {
1218 ret = driver->probe(codec); 1140 dai_component = NULL;
1219 if (ret < 0) { 1141 break;
1220 dev_err(codec->dev, 1142 }
1221 "ASoC: failed to probe CODEC %d\n", ret);
1222 goto err_probe;
1223 } 1143 }
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 } 1144 }
1229 1145
1230 if (driver->controls) 1146 if (dai_component) {
1231 snd_soc_add_codec_controls(codec, driver->controls, 1147 list_for_each_entry(dai, &dai_component->dai_list, list) {
1232 driver->num_controls); 1148 snd_soc_dapm_new_dai_widgets(dapm, dai);
1233 if (driver->dapm_routes) 1149 if (ret != 0) {
1234 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes, 1150 dev_err(component->dev,
1235 driver->num_dapm_routes); 1151 "Failed to create DAI widgets %d\n",
1236 1152 ret);
1237 /* mark codec as probed and add to card codec list */ 1153 goto err_probe;
1238 codec->probed = 1; 1154 }
1239 list_add(&codec->card_list, &card->codec_dev_list); 1155 }
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
1267 if (driver->dapm_widgets)
1268 snd_soc_dapm_new_controls(&platform->component.dapm,
1269 driver->dapm_widgets, driver->num_dapm_widgets);
1270
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 } 1156 }
1279 1157
1280 platform->component.dapm.idle_bias_off = 1; 1158 if (component->probe) {
1281 1159 ret = component->probe(component);
1282 if (driver->probe) {
1283 ret = driver->probe(platform);
1284 if (ret < 0) { 1160 if (ret < 0) {
1285 dev_err(platform->dev, 1161 dev_err(component->dev,
1286 "ASoC: failed to probe platform %d\n", ret); 1162 "ASoC: failed to probe component %d\n", ret);
1287 goto err_probe; 1163 goto err_probe;
1288 } 1164 }
1165
1166 WARN(dapm->idle_bias_off &&
1167 dapm->bias_level != SND_SOC_BIAS_OFF,
1168 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1169 component->name);
1289 } 1170 }
1290 1171
1291 if (driver->controls) 1172 if (component->controls)
1292 snd_soc_add_platform_controls(platform, driver->controls, 1173 snd_soc_add_component_controls(component, component->controls,
1293 driver->num_controls); 1174 component->num_controls);
1294 if (driver->dapm_routes) 1175 if (component->dapm_routes)
1295 snd_soc_dapm_add_routes(&platform->component.dapm, 1176 snd_soc_dapm_add_routes(dapm, component->dapm_routes,
1296 driver->dapm_routes, driver->num_dapm_routes); 1177 component->num_dapm_routes);
1297 1178
1298 /* mark platform as probed and add to card platform list */ 1179 component->probed = 1;
1299 platform->probed = 1; 1180 list_add(&dapm->list, &card->dapm_list);
1300 list_add(&platform->component.dapm.list, &card->dapm_list); 1181
1182 /* This is a HACK and will be removed soon */
1183 if (component->codec)
1184 list_add(&component->codec->card_list, &card->codec_dev_list);
1301 1185
1302 return 0; 1186 return 0;
1303 1187
1304err_probe: 1188err_probe:
1305 soc_cleanup_platform_debugfs(platform); 1189 soc_cleanup_component_debugfs(component);
1306 module_put(platform->dev->driver->owner); 1190 module_put(component->dev->driver->owner);
1307 1191
1308 return ret; 1192 return ret;
1309} 1193}
@@ -1342,17 +1226,21 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd,
1342 } 1226 }
1343 rtd->dev_registered = 1; 1227 rtd->dev_registered = 1;
1344 1228
1345 /* add DAPM sysfs entries for this codec */ 1229 if (rtd->codec) {
1346 ret = snd_soc_dapm_sys_add(rtd->dev); 1230 /* add DAPM sysfs entries for this codec */
1347 if (ret < 0) 1231 ret = snd_soc_dapm_sys_add(rtd->dev);
1348 dev_err(rtd->dev, 1232 if (ret < 0)
1349 "ASoC: failed to add codec dapm sysfs entries: %d\n", ret); 1233 dev_err(rtd->dev,
1234 "ASoC: failed to add codec dapm sysfs entries: %d\n",
1235 ret);
1350 1236
1351 /* add codec sysfs entries */ 1237 /* add codec sysfs entries */
1352 ret = device_create_file(rtd->dev, &dev_attr_codec_reg); 1238 ret = device_create_file(rtd->dev, &dev_attr_codec_reg);
1353 if (ret < 0) 1239 if (ret < 0)
1354 dev_err(rtd->dev, 1240 dev_err(rtd->dev,
1355 "ASoC: failed to add codec sysfs files: %d\n", ret); 1241 "ASoC: failed to add codec sysfs files: %d\n",
1242 ret);
1243 }
1356 1244
1357 return 0; 1245 return 0;
1358} 1246}
@@ -1361,33 +1249,31 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num,
1361 int order) 1249 int order)
1362{ 1250{
1363 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1251 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; 1252 struct snd_soc_platform *platform = rtd->platform;
1253 struct snd_soc_component *component;
1366 int i, ret; 1254 int i, ret;
1367 1255
1368 /* probe the CPU-side component, if it is a CODEC */ 1256 /* probe the CPU-side component, if it is a CODEC */
1369 if (cpu_dai->codec && 1257 component = rtd->cpu_dai->component;
1370 !cpu_dai->codec->probed && 1258 if (component->driver->probe_order == order) {
1371 cpu_dai->codec->driver->probe_order == order) { 1259 ret = soc_probe_component(card, component);
1372 ret = soc_probe_codec(card, cpu_dai->codec);
1373 if (ret < 0) 1260 if (ret < 0)
1374 return ret; 1261 return ret;
1375 } 1262 }
1376 1263
1377 /* probe the CODEC-side components */ 1264 /* probe the CODEC-side components */
1378 for (i = 0; i < rtd->num_codecs; i++) { 1265 for (i = 0; i < rtd->num_codecs; i++) {
1379 if (!rtd->codec_dais[i]->codec->probed && 1266 component = rtd->codec_dais[i]->component;
1380 rtd->codec_dais[i]->codec->driver->probe_order == order) { 1267 if (component->driver->probe_order == order) {
1381 ret = soc_probe_codec(card, rtd->codec_dais[i]->codec); 1268 ret = soc_probe_component(card, component);
1382 if (ret < 0) 1269 if (ret < 0)
1383 return ret; 1270 return ret;
1384 } 1271 }
1385 } 1272 }
1386 1273
1387 /* probe the platform */ 1274 /* probe the platform */
1388 if (!platform->probed && 1275 if (platform->component.driver->probe_order == order) {
1389 platform->driver->probe_order == order) { 1276 ret = soc_probe_component(card, &platform->component);
1390 ret = soc_probe_platform(card, platform);
1391 if (ret < 0) 1277 if (ret < 0)
1392 return ret; 1278 return ret;
1393 } 1279 }
@@ -1482,18 +1368,12 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1482 /* probe the cpu_dai */ 1368 /* probe the cpu_dai */
1483 if (!cpu_dai->probed && 1369 if (!cpu_dai->probed &&
1484 cpu_dai->driver->probe_order == order) { 1370 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) { 1371 if (cpu_dai->driver->probe) {
1491 ret = cpu_dai->driver->probe(cpu_dai); 1372 ret = cpu_dai->driver->probe(cpu_dai);
1492 if (ret < 0) { 1373 if (ret < 0) {
1493 dev_err(cpu_dai->dev, 1374 dev_err(cpu_dai->dev,
1494 "ASoC: failed to probe CPU DAI %s: %d\n", 1375 "ASoC: failed to probe CPU DAI %s: %d\n",
1495 cpu_dai->name, ret); 1376 cpu_dai->name, ret);
1496 module_put(cpu_dai->dev->driver->owner);
1497 return ret; 1377 return ret;
1498 } 1378 }
1499 } 1379 }
@@ -1654,17 +1534,24 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
1654{ 1534{
1655 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1535 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1656 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1536 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1657 const char *codecname = aux_dev->codec_name; 1537 const char *name = aux_dev->codec_name;
1658 1538
1659 rtd->codec = soc_find_codec(aux_dev->codec_of_node, codecname); 1539 rtd->component = soc_find_component(aux_dev->codec_of_node, name);
1660 if (!rtd->codec) { 1540 if (!rtd->component) {
1661 if (aux_dev->codec_of_node) 1541 if (aux_dev->codec_of_node)
1662 codecname = of_node_full_name(aux_dev->codec_of_node); 1542 name = of_node_full_name(aux_dev->codec_of_node);
1663 1543
1664 dev_err(card->dev, "ASoC: %s not registered\n", codecname); 1544 dev_err(card->dev, "ASoC: %s not registered\n", name);
1665 return -EPROBE_DEFER; 1545 return -EPROBE_DEFER;
1666 } 1546 }
1667 1547
1548 /*
1549 * Some places still reference rtd->codec, so we have to keep that
1550 * initialized if the component is a CODEC. Once all those references
1551 * have been removed, this code can be removed as well.
1552 */
1553 rtd->codec = rtd->component->codec;
1554
1668 return 0; 1555 return 0;
1669} 1556}
1670 1557
@@ -1674,18 +1561,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]; 1561 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1675 int ret; 1562 int ret;
1676 1563
1677 if (rtd->codec->probed) { 1564 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) 1565 if (ret < 0)
1684 return ret; 1566 return ret;
1685 1567
1686 /* do machine specific initialization */ 1568 /* do machine specific initialization */
1687 if (aux_dev->init) { 1569 if (aux_dev->init) {
1688 ret = aux_dev->init(&rtd->codec->dapm); 1570 ret = aux_dev->init(rtd->component);
1689 if (ret < 0) { 1571 if (ret < 0) {
1690 dev_err(card->dev, "ASoC: failed to init %s: %d\n", 1572 dev_err(card->dev, "ASoC: failed to init %s: %d\n",
1691 aux_dev->name, ret); 1573 aux_dev->name, ret);
@@ -1699,7 +1581,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) 1581static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1700{ 1582{
1701 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1583 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1702 struct snd_soc_codec *codec = rtd->codec; 1584 struct snd_soc_component *component = rtd->component;
1703 1585
1704 /* unregister the rtd device */ 1586 /* unregister the rtd device */
1705 if (rtd->dev_registered) { 1587 if (rtd->dev_registered) {
@@ -1708,8 +1590,8 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1708 rtd->dev_registered = 0; 1590 rtd->dev_registered = 0;
1709 } 1591 }
1710 1592
1711 if (codec && codec->probed) 1593 if (component && component->probed)
1712 soc_remove_codec(codec); 1594 soc_remove_component(component);
1713} 1595}
1714 1596
1715static int snd_soc_init_codec_cache(struct snd_soc_codec *codec) 1597static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
@@ -4116,6 +3998,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
4116 3998
4117 component->dev = dev; 3999 component->dev = dev;
4118 component->driver = driver; 4000 component->driver = driver;
4001 component->probe = component->driver->probe;
4002 component->remove = component->driver->remove;
4119 4003
4120 if (!component->dapm_ptr) 4004 if (!component->dapm_ptr)
4121 component->dapm_ptr = &component->dapm; 4005 component->dapm_ptr = &component->dapm;
@@ -4124,19 +4008,42 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
4124 dapm->dev = dev; 4008 dapm->dev = dev;
4125 dapm->component = component; 4009 dapm->component = component;
4126 dapm->bias_level = SND_SOC_BIAS_OFF; 4010 dapm->bias_level = SND_SOC_BIAS_OFF;
4011 dapm->idle_bias_off = true;
4127 if (driver->seq_notifier) 4012 if (driver->seq_notifier)
4128 dapm->seq_notifier = snd_soc_component_seq_notifier; 4013 dapm->seq_notifier = snd_soc_component_seq_notifier;
4129 if (driver->stream_event) 4014 if (driver->stream_event)
4130 dapm->stream_event = snd_soc_component_stream_event; 4015 dapm->stream_event = snd_soc_component_stream_event;
4131 4016
4017 component->controls = driver->controls;
4018 component->num_controls = driver->num_controls;
4019 component->dapm_widgets = driver->dapm_widgets;
4020 component->num_dapm_widgets = driver->num_dapm_widgets;
4021 component->dapm_routes = driver->dapm_routes;
4022 component->num_dapm_routes = driver->num_dapm_routes;
4023
4132 INIT_LIST_HEAD(&component->dai_list); 4024 INIT_LIST_HEAD(&component->dai_list);
4133 mutex_init(&component->io_mutex); 4025 mutex_init(&component->io_mutex);
4134 4026
4135 return 0; 4027 return 0;
4136} 4028}
4137 4029
4030static void snd_soc_component_init_regmap(struct snd_soc_component *component)
4031{
4032 if (!component->regmap)
4033 component->regmap = dev_get_regmap(component->dev, NULL);
4034 if (component->regmap) {
4035 int val_bytes = regmap_get_val_bytes(component->regmap);
4036 /* Errors are legitimate for non-integer byte multiples */
4037 if (val_bytes > 0)
4038 component->val_bytes = val_bytes;
4039 }
4040}
4041
4138static void snd_soc_component_add_unlocked(struct snd_soc_component *component) 4042static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
4139{ 4043{
4044 if (!component->write && !component->read)
4045 snd_soc_component_init_regmap(component);
4046
4140 list_add(&component->list, &component_list); 4047 list_add(&component->list, &component_list);
4141} 4048}
4142 4049
@@ -4225,22 +4132,18 @@ found:
4225} 4132}
4226EXPORT_SYMBOL_GPL(snd_soc_unregister_component); 4133EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
4227 4134
4228static int snd_soc_platform_drv_write(struct snd_soc_component *component, 4135static int snd_soc_platform_drv_probe(struct snd_soc_component *component)
4229 unsigned int reg, unsigned int val)
4230{ 4136{
4231 struct snd_soc_platform *platform = snd_soc_component_to_platform(component); 4137 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
4232 4138
4233 return platform->driver->write(platform, reg, val); 4139 return platform->driver->probe(platform);
4234} 4140}
4235 4141
4236static int snd_soc_platform_drv_read(struct snd_soc_component *component, 4142static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
4237 unsigned int reg, unsigned int *val)
4238{ 4143{
4239 struct snd_soc_platform *platform = snd_soc_component_to_platform(component); 4144 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
4240 4145
4241 *val = platform->driver->read(platform, reg); 4146 platform->driver->remove(platform);
4242
4243 return 0;
4244} 4147}
4245 4148
4246/** 4149/**
@@ -4261,10 +4164,28 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
4261 4164
4262 platform->dev = dev; 4165 platform->dev = dev;
4263 platform->driver = platform_drv; 4166 platform->driver = platform_drv;
4264 if (platform_drv->write) 4167 if (platform_drv->controls) {
4265 platform->component.write = snd_soc_platform_drv_write; 4168 platform->component.controls = platform_drv->controls;
4266 if (platform_drv->read) 4169 platform->component.num_controls = platform_drv->num_controls;
4267 platform->component.read = snd_soc_platform_drv_read; 4170 }
4171 if (platform_drv->dapm_widgets) {
4172 platform->component.dapm_widgets = platform_drv->dapm_widgets;
4173 platform->component.num_dapm_widgets = platform_drv->num_dapm_widgets;
4174 platform->component.steal_sibling_dai_widgets = true;
4175 }
4176 if (platform_drv->dapm_routes) {
4177 platform->component.dapm_routes = platform_drv->dapm_routes;
4178 platform->component.num_dapm_routes = platform_drv->num_dapm_routes;
4179 }
4180
4181 if (platform_drv->probe)
4182 platform->component.probe = snd_soc_platform_drv_probe;
4183 if (platform_drv->remove)
4184 platform->component.remove = snd_soc_platform_drv_remove;
4185
4186#ifdef CONFIG_DEBUG_FS
4187 platform->component.debugfs_prefix = "platform";
4188#endif
4268 4189
4269 mutex_lock(&client_mutex); 4190 mutex_lock(&client_mutex);
4270 snd_soc_component_add_unlocked(&platform->component); 4191 snd_soc_component_add_unlocked(&platform->component);
@@ -4386,6 +4307,20 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
4386 stream->formats |= codec_format_map[i]; 4307 stream->formats |= codec_format_map[i];
4387} 4308}
4388 4309
4310static int snd_soc_codec_drv_probe(struct snd_soc_component *component)
4311{
4312 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
4313
4314 return codec->driver->probe(codec);
4315}
4316
4317static void snd_soc_codec_drv_remove(struct snd_soc_component *component)
4318{
4319 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
4320
4321 codec->driver->remove(codec);
4322}
4323
4389static int snd_soc_codec_drv_write(struct snd_soc_component *component, 4324static int snd_soc_codec_drv_write(struct snd_soc_component *component,
4390 unsigned int reg, unsigned int val) 4325 unsigned int reg, unsigned int val)
4391{ 4326{
@@ -4424,7 +4359,6 @@ int snd_soc_register_codec(struct device *dev,
4424{ 4359{
4425 struct snd_soc_codec *codec; 4360 struct snd_soc_codec *codec;
4426 struct snd_soc_dai *dai; 4361 struct snd_soc_dai *dai;
4427 struct regmap *regmap;
4428 int ret, i; 4362 int ret, i;
4429 4363
4430 dev_dbg(dev, "codec register %s\n", dev_name(dev)); 4364 dev_dbg(dev, "codec register %s\n", dev_name(dev));
@@ -4434,18 +4368,37 @@ int snd_soc_register_codec(struct device *dev,
4434 return -ENOMEM; 4368 return -ENOMEM;
4435 4369
4436 codec->component.dapm_ptr = &codec->dapm; 4370 codec->component.dapm_ptr = &codec->dapm;
4371 codec->component.codec = codec;
4437 4372
4438 ret = snd_soc_component_initialize(&codec->component, 4373 ret = snd_soc_component_initialize(&codec->component,
4439 &codec_drv->component_driver, dev); 4374 &codec_drv->component_driver, dev);
4440 if (ret) 4375 if (ret)
4441 goto err_free; 4376 goto err_free;
4442 4377
4378 if (codec_drv->controls) {
4379 codec->component.controls = codec_drv->controls;
4380 codec->component.num_controls = codec_drv->num_controls;
4381 }
4382 if (codec_drv->dapm_widgets) {
4383 codec->component.dapm_widgets = codec_drv->dapm_widgets;
4384 codec->component.num_dapm_widgets = codec_drv->num_dapm_widgets;
4385 }
4386 if (codec_drv->dapm_routes) {
4387 codec->component.dapm_routes = codec_drv->dapm_routes;
4388 codec->component.num_dapm_routes = codec_drv->num_dapm_routes;
4389 }
4390
4391 if (codec_drv->probe)
4392 codec->component.probe = snd_soc_codec_drv_probe;
4393 if (codec_drv->remove)
4394 codec->component.remove = snd_soc_codec_drv_remove;
4443 if (codec_drv->write) 4395 if (codec_drv->write)
4444 codec->component.write = snd_soc_codec_drv_write; 4396 codec->component.write = snd_soc_codec_drv_write;
4445 if (codec_drv->read) 4397 if (codec_drv->read)
4446 codec->component.read = snd_soc_codec_drv_read; 4398 codec->component.read = snd_soc_codec_drv_read;
4447 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; 4399 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
4448 codec->dapm.codec = codec; 4400 codec->dapm.codec = codec;
4401 codec->dapm.idle_bias_off = codec_drv->idle_bias_off;
4449 if (codec_drv->seq_notifier) 4402 if (codec_drv->seq_notifier)
4450 codec->dapm.seq_notifier = codec_drv->seq_notifier; 4403 codec->dapm.seq_notifier = codec_drv->seq_notifier;
4451 if (codec_drv->set_bias_level) 4404 if (codec_drv->set_bias_level)
@@ -4455,23 +4408,13 @@ int snd_soc_register_codec(struct device *dev,
4455 codec->component.val_bytes = codec_drv->reg_word_size; 4408 codec->component.val_bytes = codec_drv->reg_word_size;
4456 mutex_init(&codec->mutex); 4409 mutex_init(&codec->mutex);
4457 4410
4458 if (!codec->component.write) { 4411#ifdef CONFIG_DEBUG_FS
4459 if (codec_drv->get_regmap) 4412 codec->component.init_debugfs = soc_init_codec_debugfs;
4460 regmap = codec_drv->get_regmap(dev); 4413 codec->component.debugfs_prefix = "codec";
4461 else 4414#endif
4462 regmap = dev_get_regmap(dev, NULL); 4415
4463 4416 if (codec_drv->get_regmap)
4464 if (regmap) { 4417 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 4418
4476 for (i = 0; i < num_dai; i++) { 4419 for (i = 0; i < num_dai; i++) {
4477 fixup_codec_formats(&dai_drv[i].playback); 4420 fixup_codec_formats(&dai_drv[i].playback);
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);