aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/samsung
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-11 06:06:41 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-11 06:06:41 -0500
commit2944c2f5d5c88d5893d6a1dad51d0768aed52d00 (patch)
treeb09658ebfcbb078afe82beb6e462b3edebd03ddd /sound/soc/samsung
parentf8843c91c60ed744cc7dd6326e44ddb91250ab35 (diff)
parent5b1d3c3472f1941ab1a78575fe9ada718a7c0c25 (diff)
Merge remote-tracking branch 'asoc/topic/samsung' into asoc-next
Diffstat (limited to 'sound/soc/samsung')
-rw-r--r--sound/soc/samsung/Kconfig6
-rw-r--r--sound/soc/samsung/dma.c3
-rw-r--r--sound/soc/samsung/dma.h1
-rw-r--r--sound/soc/samsung/i2s.c267
-rw-r--r--sound/soc/samsung/i2s.h7
-rw-r--r--sound/soc/samsung/smdk_wm8580.c7
-rw-r--r--sound/soc/samsung/smdk_wm8994.c30
7 files changed, 256 insertions, 65 deletions
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 3c7c3a59ed39..90e7e6653233 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -63,7 +63,7 @@ config SND_SOC_SAMSUNG_SMDK_WM8580
63 63
64config SND_SOC_SAMSUNG_SMDK_WM8994 64config SND_SOC_SAMSUNG_SMDK_WM8994
65 tristate "SoC I2S Audio support for WM8994 on SMDK" 65 tristate "SoC I2S Audio support for WM8994 on SMDK"
66 depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210 || MACH_SMDK4212) 66 depends on SND_SOC_SAMSUNG
67 depends on I2C=y && GENERIC_HARDIRQS 67 depends on I2C=y && GENERIC_HARDIRQS
68 select MFD_WM8994 68 select MFD_WM8994
69 select SND_SOC_WM8994 69 select SND_SOC_WM8994
@@ -162,7 +162,7 @@ config SND_SOC_GONI_AQUILA_WM8994
162 162
163config SND_SOC_SAMSUNG_SMDK_SPDIF 163config SND_SOC_SAMSUNG_SMDK_SPDIF
164 tristate "SoC S/PDIF Audio support for SMDK" 164 tristate "SoC S/PDIF Audio support for SMDK"
165 depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210 || MACH_SMDKV310 || MACH_SMDK4212) 165 depends on SND_SOC_SAMSUNG
166 select SND_SAMSUNG_SPDIF 166 select SND_SAMSUNG_SPDIF
167 help 167 help
168 Say Y if you want to add support for SoC S/PDIF audio on the SMDK. 168 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
@@ -177,7 +177,7 @@ config SND_SOC_SMDK_WM8580_PCM
177 177
178config SND_SOC_SMDK_WM8994_PCM 178config SND_SOC_SMDK_WM8994_PCM
179 tristate "SoC PCM Audio support for WM8994 on SMDK" 179 tristate "SoC PCM Audio support for WM8994 on SMDK"
180 depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310 || MACH_SMDK4212) 180 depends on SND_SOC_SAMSUNG
181 depends on I2C=y && GENERIC_HARDIRQS 181 depends on I2C=y && GENERIC_HARDIRQS
182 select MFD_WM8994 182 select MFD_WM8994
183 select SND_SOC_WM8994 183 select SND_SOC_WM8994
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index db87628d7630..21b79262010e 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -174,7 +174,8 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
174 config.width = prtd->params->dma_size; 174 config.width = prtd->params->dma_size;
175 config.fifo = prtd->params->dma_addr; 175 config.fifo = prtd->params->dma_addr;
176 prtd->params->ch = prtd->params->ops->request( 176 prtd->params->ch = prtd->params->ops->request(
177 prtd->params->channel, &req); 177 prtd->params->channel, &req, rtd->cpu_dai->dev,
178 prtd->params->ch_name);
178 prtd->params->ops->config(prtd->params->ch, &config); 179 prtd->params->ops->config(prtd->params->ch, &config);
179 } 180 }
180 181
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index 73d8c7c8a1e8..189a7a6d5020 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -19,6 +19,7 @@ struct s3c_dma_params {
19 int dma_size; /* Size of the DMA transfer */ 19 int dma_size; /* Size of the DMA transfer */
20 unsigned ch; 20 unsigned ch;
21 struct samsung_dma_ops *ops; 21 struct samsung_dma_ops *ops;
22 char *ch_name;
22}; 23};
23 24
24int asoc_dma_platform_register(struct device *dev); 25int asoc_dma_platform_register(struct device *dev);
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index d2d124f1dd1b..d7231e336a7c 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -15,11 +15,15 @@
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/of_gpio.h>
18#include <linux/pm_runtime.h> 20#include <linux/pm_runtime.h>
19 21
20#include <sound/soc.h> 22#include <sound/soc.h>
21#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
22 24
25#include <mach/dma.h>
26
23#include <linux/platform_data/asoc-s3c.h> 27#include <linux/platform_data/asoc-s3c.h>
24 28
25#include "dma.h" 29#include "dma.h"
@@ -29,6 +33,15 @@
29 33
30#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) 34#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
31 35
36enum samsung_dai_type {
37 TYPE_PRI,
38 TYPE_SEC,
39};
40
41struct samsung_i2s_dai_data {
42 int dai_type;
43};
44
32struct i2s_dai { 45struct i2s_dai {
33 /* Platform device for this DAI */ 46 /* Platform device for this DAI */
34 struct platform_device *pdev; 47 struct platform_device *pdev;
@@ -66,6 +79,7 @@ struct i2s_dai {
66 u32 suspend_i2smod; 79 u32 suspend_i2smod;
67 u32 suspend_i2scon; 80 u32 suspend_i2scon;
68 u32 suspend_i2spsr; 81 u32 suspend_i2spsr;
82 unsigned long gpios[7]; /* i2s gpio line numbers */
69}; 83};
70 84
71/* Lock for cross i/f checks */ 85/* Lock for cross i/f checks */
@@ -651,6 +665,9 @@ static int i2s_startup(struct snd_pcm_substream *substream,
651 /* Enforce set_sysclk in Master mode */ 665 /* Enforce set_sysclk in Master mode */
652 i2s->rclk_srcrate = 0; 666 i2s->rclk_srcrate = 0;
653 667
668 if (!any_active(i2s) && (i2s->quirks & QUIRK_NEED_RSTCLR))
669 writel(CON_RSTCLR, i2s->addr + I2SCON);
670
654 spin_unlock_irqrestore(&lock, flags); 671 spin_unlock_irqrestore(&lock, flags);
655 672
656 return 0; 673 return 0;
@@ -981,8 +998,7 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
981 i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; 998 i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
982 } else { /* Create a new platform_device for Secondary */ 999 } else { /* Create a new platform_device for Secondary */
983 i2s->pdev = platform_device_register_resndata(NULL, 1000 i2s->pdev = platform_device_register_resndata(NULL,
984 pdev->name, pdev->id + SAMSUNG_I2S_SECOFF, 1001 "samsung-i2s-sec", -1, NULL, 0, NULL, 0);
985 NULL, 0, NULL, 0);
986 if (IS_ERR(i2s->pdev)) 1002 if (IS_ERR(i2s->pdev))
987 return NULL; 1003 return NULL;
988 } 1004 }
@@ -993,18 +1009,103 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
993 return i2s; 1009 return i2s;
994} 1010}
995 1011
1012#ifdef CONFIG_OF
1013static int samsung_i2s_parse_dt_gpio(struct i2s_dai *i2s)
1014{
1015 struct device *dev = &i2s->pdev->dev;
1016 int index, gpio, ret;
1017
1018 for (index = 0; index < 7; index++) {
1019 gpio = of_get_gpio(dev->of_node, index);
1020 if (!gpio_is_valid(gpio)) {
1021 dev_err(dev, "invalid gpio[%d]: %d\n", index, gpio);
1022 goto free_gpio;
1023 }
1024
1025 ret = gpio_request(gpio, dev_name(dev));
1026 if (ret) {
1027 dev_err(dev, "gpio [%d] request failed\n", gpio);
1028 goto free_gpio;
1029 }
1030 i2s->gpios[index] = gpio;
1031 }
1032 return 0;
1033
1034free_gpio:
1035 while (--index >= 0)
1036 gpio_free(i2s->gpios[index]);
1037 return -EINVAL;
1038}
1039
1040static void samsung_i2s_dt_gpio_free(struct i2s_dai *i2s)
1041{
1042 unsigned int index;
1043 for (index = 0; index < 7; index++)
1044 gpio_free(i2s->gpios[index]);
1045}
1046#else
1047static int samsung_i2s_parse_dt_gpio(struct i2s_dai *dai)
1048{
1049 return -EINVAL;
1050}
1051
1052static void samsung_i2s_dt_gpio_free(struct i2s_dai *dai)
1053{
1054}
1055
1056#endif
1057
1058static const struct of_device_id exynos_i2s_match[];
1059
1060static inline int samsung_i2s_get_driver_data(struct platform_device *pdev)
1061{
1062#ifdef CONFIG_OF
1063 struct samsung_i2s_dai_data *data;
1064 if (pdev->dev.of_node) {
1065 const struct of_device_id *match;
1066 match = of_match_node(exynos_i2s_match, pdev->dev.of_node);
1067 data = (struct samsung_i2s_dai_data *) match->data;
1068 return data->dai_type;
1069 } else
1070#endif
1071 return platform_get_device_id(pdev)->driver_data;
1072}
1073
1074#ifdef CONFIG_PM_RUNTIME
1075static int i2s_runtime_suspend(struct device *dev)
1076{
1077 struct i2s_dai *i2s = dev_get_drvdata(dev);
1078
1079 clk_disable_unprepare(i2s->clk);
1080
1081 return 0;
1082}
1083
1084static int i2s_runtime_resume(struct device *dev)
1085{
1086 struct i2s_dai *i2s = dev_get_drvdata(dev);
1087
1088 clk_prepare_enable(i2s->clk);
1089
1090 return 0;
1091}
1092#endif /* CONFIG_PM_RUNTIME */
1093
996static int samsung_i2s_probe(struct platform_device *pdev) 1094static int samsung_i2s_probe(struct platform_device *pdev)
997{ 1095{
998 u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan;
999 struct i2s_dai *pri_dai, *sec_dai = NULL; 1096 struct i2s_dai *pri_dai, *sec_dai = NULL;
1000 struct s3c_audio_pdata *i2s_pdata; 1097 struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data;
1001 struct samsung_i2s *i2s_cfg; 1098 struct samsung_i2s *i2s_cfg = NULL;
1002 struct resource *res; 1099 struct resource *res;
1003 u32 regs_base, quirks; 1100 u32 regs_base, quirks = 0, idma_addr = 0;
1101 struct device_node *np = pdev->dev.of_node;
1102 enum samsung_dai_type samsung_dai_type;
1004 int ret = 0; 1103 int ret = 0;
1005 1104
1006 /* Call during Seconday interface registration */ 1105 /* Call during Seconday interface registration */
1007 if (pdev->id >= SAMSUNG_I2S_SECOFF) { 1106 samsung_dai_type = samsung_i2s_get_driver_data(pdev);
1107
1108 if (samsung_dai_type == TYPE_SEC) {
1008 sec_dai = dev_get_drvdata(&pdev->dev); 1109 sec_dai = dev_get_drvdata(&pdev->dev);
1009 snd_soc_register_dai(&sec_dai->pdev->dev, 1110 snd_soc_register_dai(&sec_dai->pdev->dev,
1010 &sec_dai->i2s_dai_drv); 1111 &sec_dai->i2s_dai_drv);
@@ -1012,31 +1113,60 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1012 return 0; 1113 return 0;
1013 } 1114 }
1014 1115
1015 i2s_pdata = pdev->dev.platform_data; 1116 pri_dai = i2s_alloc_dai(pdev, false);
1016 if (i2s_pdata == NULL) { 1117 if (!pri_dai) {
1017 dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n"); 1118 dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
1018 return -EINVAL; 1119 return -ENOMEM;
1019 } 1120 }
1020 1121
1021 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 1122 if (!np) {
1022 if (!res) { 1123 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1023 dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); 1124 if (!res) {
1024 return -ENXIO; 1125 dev_err(&pdev->dev,
1025 } 1126 "Unable to get I2S-TX dma resource\n");
1026 dma_pl_chan = res->start; 1127 return -ENXIO;
1128 }
1129 pri_dai->dma_playback.channel = res->start;
1027 1130
1028 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 1131 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
1029 if (!res) { 1132 if (!res) {
1030 dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); 1133 dev_err(&pdev->dev,
1031 return -ENXIO; 1134 "Unable to get I2S-RX dma resource\n");
1032 } 1135 return -ENXIO;
1033 dma_cp_chan = res->start; 1136 }
1137 pri_dai->dma_capture.channel = res->start;
1034 1138
1035 res = platform_get_resource(pdev, IORESOURCE_DMA, 2); 1139 if (i2s_pdata == NULL) {
1036 if (res) 1140 dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
1037 dma_pl_sec_chan = res->start; 1141 return -EINVAL;
1038 else 1142 }
1039 dma_pl_sec_chan = 0; 1143
1144 if (&i2s_pdata->type)
1145 i2s_cfg = &i2s_pdata->type.i2s;
1146
1147 if (i2s_cfg) {
1148 quirks = i2s_cfg->quirks;
1149 idma_addr = i2s_cfg->idma_addr;
1150 }
1151 } else {
1152 if (of_find_property(np, "samsung,supports-6ch", NULL))
1153 quirks |= QUIRK_PRI_6CHAN;
1154
1155 if (of_find_property(np, "samsung,supports-secdai", NULL))
1156 quirks |= QUIRK_SEC_DAI;
1157
1158 if (of_find_property(np, "samsung,supports-rstclr", NULL))
1159 quirks |= QUIRK_NEED_RSTCLR;
1160
1161 if (of_property_read_u32(np, "samsung,idma-addr",
1162 &idma_addr)) {
1163 if (quirks & QUIRK_SEC_DAI) {
1164 dev_err(&pdev->dev, "idma address is not"\
1165 "specified");
1166 return -EINVAL;
1167 }
1168 }
1169 }
1040 1170
1041 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1171 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1042 if (!res) { 1172 if (!res) {
@@ -1051,24 +1181,14 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1051 } 1181 }
1052 regs_base = res->start; 1182 regs_base = res->start;
1053 1183
1054 i2s_cfg = &i2s_pdata->type.i2s;
1055 quirks = i2s_cfg->quirks;
1056
1057 pri_dai = i2s_alloc_dai(pdev, false);
1058 if (!pri_dai) {
1059 dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
1060 ret = -ENOMEM;
1061 goto err;
1062 }
1063
1064 pri_dai->dma_playback.dma_addr = regs_base + I2STXD; 1184 pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
1065 pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; 1185 pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
1066 pri_dai->dma_playback.client = 1186 pri_dai->dma_playback.client =
1067 (struct s3c2410_dma_client *)&pri_dai->dma_playback; 1187 (struct s3c2410_dma_client *)&pri_dai->dma_playback;
1188 pri_dai->dma_playback.ch_name = "tx";
1068 pri_dai->dma_capture.client = 1189 pri_dai->dma_capture.client =
1069 (struct s3c2410_dma_client *)&pri_dai->dma_capture; 1190 (struct s3c2410_dma_client *)&pri_dai->dma_capture;
1070 pri_dai->dma_playback.channel = dma_pl_chan; 1191 pri_dai->dma_capture.ch_name = "rx";
1071 pri_dai->dma_capture.channel = dma_cp_chan;
1072 pri_dai->dma_playback.dma_size = 4; 1192 pri_dai->dma_playback.dma_size = 4;
1073 pri_dai->dma_capture.dma_size = 4; 1193 pri_dai->dma_capture.dma_size = 4;
1074 pri_dai->base = regs_base; 1194 pri_dai->base = regs_base;
@@ -1087,20 +1207,34 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1087 sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; 1207 sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
1088 sec_dai->dma_playback.client = 1208 sec_dai->dma_playback.client =
1089 (struct s3c2410_dma_client *)&sec_dai->dma_playback; 1209 (struct s3c2410_dma_client *)&sec_dai->dma_playback;
1090 /* Use iDMA always if SysDMA not provided */ 1210 sec_dai->dma_playback.ch_name = "tx-sec";
1091 sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1; 1211
1212 if (!np) {
1213 res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
1214 if (res)
1215 sec_dai->dma_playback.channel = res->start;
1216 }
1217
1092 sec_dai->dma_playback.dma_size = 4; 1218 sec_dai->dma_playback.dma_size = 4;
1093 sec_dai->base = regs_base; 1219 sec_dai->base = regs_base;
1094 sec_dai->quirks = quirks; 1220 sec_dai->quirks = quirks;
1095 sec_dai->idma_playback.dma_addr = i2s_cfg->idma_addr; 1221 sec_dai->idma_playback.dma_addr = idma_addr;
1096 sec_dai->pri_dai = pri_dai; 1222 sec_dai->pri_dai = pri_dai;
1097 pri_dai->sec_dai = sec_dai; 1223 pri_dai->sec_dai = sec_dai;
1098 } 1224 }
1099 1225
1100 if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { 1226 if (np) {
1101 dev_err(&pdev->dev, "Unable to configure gpio\n"); 1227 if (samsung_i2s_parse_dt_gpio(pri_dai)) {
1102 ret = -EINVAL; 1228 dev_err(&pdev->dev, "Unable to configure gpio\n");
1103 goto err; 1229 ret = -EINVAL;
1230 goto err;
1231 }
1232 } else {
1233 if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
1234 dev_err(&pdev->dev, "Unable to configure gpio\n");
1235 ret = -EINVAL;
1236 goto err;
1237 }
1104 } 1238 }
1105 1239
1106 snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv); 1240 snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv);
@@ -1120,10 +1254,14 @@ static int samsung_i2s_remove(struct platform_device *pdev)
1120{ 1254{
1121 struct i2s_dai *i2s, *other; 1255 struct i2s_dai *i2s, *other;
1122 struct resource *res; 1256 struct resource *res;
1257 struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data;
1123 1258
1124 i2s = dev_get_drvdata(&pdev->dev); 1259 i2s = dev_get_drvdata(&pdev->dev);
1125 other = i2s->pri_dai ? : i2s->sec_dai; 1260 other = i2s->pri_dai ? : i2s->sec_dai;
1126 1261
1262 if (!i2s_pdata->cfg_gpio && pdev->dev.of_node)
1263 samsung_i2s_dt_gpio_free(i2s->pri_dai);
1264
1127 if (other) { 1265 if (other) {
1128 other->pri_dai = NULL; 1266 other->pri_dai = NULL;
1129 other->sec_dai = NULL; 1267 other->sec_dai = NULL;
@@ -1143,12 +1281,47 @@ static int samsung_i2s_remove(struct platform_device *pdev)
1143 return 0; 1281 return 0;
1144} 1282}
1145 1283
1284static struct platform_device_id samsung_i2s_driver_ids[] = {
1285 {
1286 .name = "samsung-i2s",
1287 .driver_data = TYPE_PRI,
1288 }, {
1289 .name = "samsung-i2s-sec",
1290 .driver_data = TYPE_SEC,
1291 },
1292 {},
1293};
1294MODULE_DEVICE_TABLE(platform, samsung-i2s-driver-ids);
1295
1296#ifdef CONFIG_OF
1297static struct samsung_i2s_dai_data samsung_i2s_dai_data_array[] = {
1298 [TYPE_PRI] = { TYPE_PRI },
1299 [TYPE_SEC] = { TYPE_SEC },
1300};
1301
1302static const struct of_device_id exynos_i2s_match[] = {
1303 { .compatible = "samsung,i2s-v5",
1304 .data = &samsung_i2s_dai_data_array[TYPE_PRI],
1305 },
1306 {},
1307};
1308MODULE_DEVICE_TABLE(of, exynos_i2s_match);
1309#endif
1310
1311static const struct dev_pm_ops samsung_i2s_pm = {
1312 SET_RUNTIME_PM_OPS(i2s_runtime_suspend,
1313 i2s_runtime_resume, NULL)
1314};
1315
1146static struct platform_driver samsung_i2s_driver = { 1316static struct platform_driver samsung_i2s_driver = {
1147 .probe = samsung_i2s_probe, 1317 .probe = samsung_i2s_probe,
1148 .remove = samsung_i2s_remove, 1318 .remove = samsung_i2s_remove,
1319 .id_table = samsung_i2s_driver_ids,
1149 .driver = { 1320 .driver = {
1150 .name = "samsung-i2s", 1321 .name = "samsung-i2s",
1151 .owner = THIS_MODULE, 1322 .owner = THIS_MODULE,
1323 .of_match_table = of_match_ptr(exynos_i2s_match),
1324 .pm = &samsung_i2s_pm,
1152 }, 1325 },
1153}; 1326};
1154 1327
diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h
index d420a7ca56ca..7966afc934db 100644
--- a/sound/soc/samsung/i2s.h
+++ b/sound/soc/samsung/i2s.h
@@ -13,13 +13,6 @@
13#ifndef __SND_SOC_SAMSUNG_I2S_H 13#ifndef __SND_SOC_SAMSUNG_I2S_H
14#define __SND_SOC_SAMSUNG_I2S_H 14#define __SND_SOC_SAMSUNG_I2S_H
15 15
16/*
17 * Maximum number of I2S blocks that any SoC can have.
18 * The secondary interface of a CPU dai(if there exists any),
19 * is indexed at [cpu-dai's ID + SAMSUNG_I2S_SECOFF]
20 */
21#define SAMSUNG_I2S_SECOFF 4
22
23#define SAMSUNG_I2S_DIV_BCLK 1 16#define SAMSUNG_I2S_DIV_BCLK 1
24 17
25#define SAMSUNG_I2S_RCLKSRC_0 0 18#define SAMSUNG_I2S_RCLKSRC_0 0
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index 7e2b710763be..7a16b32ed673 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -193,9 +193,9 @@ static struct snd_soc_dai_link smdk_dai[] = {
193 [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */ 193 [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */
194 .name = "Sec_FIFO TX", 194 .name = "Sec_FIFO TX",
195 .stream_name = "Playback", 195 .stream_name = "Playback",
196 .cpu_dai_name = "samsung-i2s.x", 196 .cpu_dai_name = "samsung-i2s-sec",
197 .codec_dai_name = "wm8580-hifi-playback", 197 .codec_dai_name = "wm8580-hifi-playback",
198 .platform_name = "samsung-i2s.x", 198 .platform_name = "samsung-i2s-sec",
199 .codec_name = "wm8580.0-001b", 199 .codec_name = "wm8580.0-001b",
200 .ops = &smdk_ops, 200 .ops = &smdk_ops,
201 }, 201 },
@@ -223,9 +223,6 @@ static int __init smdk_audio_init(void)
223 if (machine_is_smdkc100() 223 if (machine_is_smdkc100()
224 || machine_is_smdkv210() || machine_is_smdkc110()) { 224 || machine_is_smdkv210() || machine_is_smdkc110()) {
225 smdk.num_links = 3; 225 smdk.num_links = 3;
226 /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */
227 str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name;
228 str[strlen(str) - 1] = '0' + SAMSUNG_I2S_SECOFF;
229 } else if (machine_is_smdk6410()) { 226 } else if (machine_is_smdk6410()) {
230 str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name; 227 str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name;
231 str[strlen(str) - 1] = '2'; 228 str[strlen(str) - 1] = '2';
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
index b0d0ab8bff5a..581ea4a06fc6 100644
--- a/sound/soc/samsung/smdk_wm8994.c
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -10,6 +10,7 @@
10#include "../codecs/wm8994.h" 10#include "../codecs/wm8994.h"
11#include <sound/pcm_params.h> 11#include <sound/pcm_params.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/of.h>
13 14
14 /* 15 /*
15 * Default CFG switch settings to use this driver: 16 * Default CFG switch settings to use this driver:
@@ -134,9 +135,9 @@ static struct snd_soc_dai_link smdk_dai[] = {
134 }, { /* Sec_Fifo Playback i/f */ 135 }, { /* Sec_Fifo Playback i/f */
135 .name = "Sec_FIFO TX", 136 .name = "Sec_FIFO TX",
136 .stream_name = "Sec_Dai", 137 .stream_name = "Sec_Dai",
137 .cpu_dai_name = "samsung-i2s.4", 138 .cpu_dai_name = "samsung-i2s-sec",
138 .codec_dai_name = "wm8994-aif1", 139 .codec_dai_name = "wm8994-aif1",
139 .platform_name = "samsung-i2s.4", 140 .platform_name = "samsung-i2s-sec",
140 .codec_name = "wm8994-codec", 141 .codec_name = "wm8994-codec",
141 .ops = &smdk_ops, 142 .ops = &smdk_ops,
142 }, 143 },
@@ -153,9 +154,25 @@ static struct snd_soc_card smdk = {
153static int smdk_audio_probe(struct platform_device *pdev) 154static int smdk_audio_probe(struct platform_device *pdev)
154{ 155{
155 int ret; 156 int ret;
157 struct device_node *np = pdev->dev.of_node;
156 struct snd_soc_card *card = &smdk; 158 struct snd_soc_card *card = &smdk;
157 159
158 card->dev = &pdev->dev; 160 card->dev = &pdev->dev;
161
162 if (np) {
163 smdk_dai[0].cpu_dai_name = NULL;
164 smdk_dai[0].cpu_of_node = of_parse_phandle(np,
165 "samsung,i2s-controller", 0);
166 if (!smdk_dai[0].cpu_of_node) {
167 dev_err(&pdev->dev,
168 "Property 'samsung,i2s-controller' missing or invalid\n");
169 ret = -EINVAL;
170 }
171
172 smdk_dai[0].platform_name = NULL;
173 smdk_dai[0].platform_of_node = smdk_dai[0].cpu_of_node;
174 }
175
159 ret = snd_soc_register_card(card); 176 ret = snd_soc_register_card(card);
160 177
161 if (ret) 178 if (ret)
@@ -173,10 +190,19 @@ static int smdk_audio_remove(struct platform_device *pdev)
173 return 0; 190 return 0;
174} 191}
175 192
193#ifdef CONFIG_OF
194static const struct of_device_id samsung_wm8994_of_match[] = {
195 { .compatible = "samsung,smdk-wm8994", },
196 {},
197};
198MODULE_DEVICE_TABLE(of, samsung_wm8994_of_match);
199#endif /* CONFIG_OF */
200
176static struct platform_driver smdk_audio_driver = { 201static struct platform_driver smdk_audio_driver = {
177 .driver = { 202 .driver = {
178 .name = "smdk-audio", 203 .name = "smdk-audio",
179 .owner = THIS_MODULE, 204 .owner = THIS_MODULE,
205 .of_match_table = of_match_ptr(samsung_wm8994_of_match),
180 }, 206 },
181 .probe = smdk_audio_probe, 207 .probe = smdk_audio_probe,
182 .remove = smdk_audio_remove, 208 .remove = smdk_audio_remove,