aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPadmavathi Venna <padma.v@samsung.com>2013-08-12 05:49:51 -0400
committerMark Brown <broonie@linaro.org>2013-08-13 08:44:06 -0400
commit7da493e9229c737c399886f57996f6bfd4454e21 (patch)
tree62517af9c20826b47e88fbcb355467a7f2b6723d
parent2f6f0ffb2b073a0a5a9ffe5705b8e8cc43558d3a (diff)
ASoC: Samsung: I2S: Add quirks as driver data in I2S
Samsung has different versions of I2S introduced in different platforms. Each version has some new support added for multichannel, secondary fifo, s/w reset control and internal mux for rclk src clk. Each newly added change has a quirk. So this patch adds all the required quirks as driver data and based on compatible string from dtsi fetches the quirks. Signed-off-by: Padmavathi Venna <padma.v@samsung.com> Reviewed-by: Tomasz Figa <t.figa@samsung.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--Documentation/devicetree/bindings/sound/samsung-i2s.txt18
-rw-r--r--sound/soc/samsung/i2s.c62
2 files changed, 42 insertions, 38 deletions
diff --git a/Documentation/devicetree/bindings/sound/samsung-i2s.txt b/Documentation/devicetree/bindings/sound/samsung-i2s.txt
index 025e66b85a43..25a0024d1b0a 100644
--- a/Documentation/devicetree/bindings/sound/samsung-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/samsung-i2s.txt
@@ -2,7 +2,11 @@
2 2
3Required SoC Specific Properties: 3Required SoC Specific Properties:
4 4
5- compatible : "samsung,i2s-v5" 5- compatible : should be one of the following.
6 - samsung,s3c6410-i2s: for 8/16/24bit stereo I2S.
7 - samsung,s5pv210-i2s: for 8/16/24bit multichannel(5.1) I2S with
8 secondary fifo, s/w reset control and internal mux for root clk src.
9
6- reg: physical base address of the controller and length of memory mapped 10- reg: physical base address of the controller and length of memory mapped
7 region. 11 region.
8- dmas: list of DMA controller phandle and DMA request line ordered pairs. 12- dmas: list of DMA controller phandle and DMA request line ordered pairs.
@@ -21,13 +25,6 @@ Required SoC Specific Properties:
21 25
22Optional SoC Specific Properties: 26Optional SoC Specific Properties:
23 27
24- samsung,supports-6ch: If the I2S Primary sound source has 5.1 Channel
25 support, this flag is enabled.
26- samsung,supports-rstclr: This flag should be set if I2S software reset bit
27 control is required. When this flag is set I2S software reset bit will be
28 enabled or disabled based on need.
29- samsung,supports-secdai:If I2S block has a secondary FIFO and internal DMA,
30 then this flag is enabled.
31- samsung,idma-addr: Internal DMA register base address of the audio 28- samsung,idma-addr: Internal DMA register base address of the audio
32 sub system(used in secondary sound source). 29 sub system(used in secondary sound source).
33- pinctrl-0: Should specify pin control groups used for this controller. 30- pinctrl-0: Should specify pin control groups used for this controller.
@@ -36,7 +33,7 @@ Optional SoC Specific Properties:
36Example: 33Example:
37 34
38i2s0: i2s@03830000 { 35i2s0: i2s@03830000 {
39 compatible = "samsung,i2s-v5"; 36 compatible = "samsung,s5pv210-i2s";
40 reg = <0x03830000 0x100>; 37 reg = <0x03830000 0x100>;
41 dmas = <&pdma0 10 38 dmas = <&pdma0 10
42 &pdma0 9 39 &pdma0 9
@@ -46,9 +43,6 @@ i2s0: i2s@03830000 {
46 <&clock_audss EXYNOS_I2S_BUS>, 43 <&clock_audss EXYNOS_I2S_BUS>,
47 <&clock_audss EXYNOS_SCLK_I2S>; 44 <&clock_audss EXYNOS_SCLK_I2S>;
48 clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; 45 clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
49 samsung,supports-6ch;
50 samsung,supports-rstclr;
51 samsung,supports-secdai;
52 samsung,idma-addr = <0x03000000>; 46 samsung,idma-addr = <0x03000000>;
53 pinctrl-names = "default"; 47 pinctrl-names = "default";
54 pinctrl-0 = <&i2s0_bus>; 48 pinctrl-0 = <&i2s0_bus>;
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 849ac0e225ca..3b4835a1bd23 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -40,6 +40,7 @@ enum samsung_dai_type {
40 40
41struct samsung_i2s_dai_data { 41struct samsung_i2s_dai_data {
42 int dai_type; 42 int dai_type;
43 u32 quirks;
43}; 44};
44 45
45struct i2s_dai { 46struct i2s_dai {
@@ -1032,18 +1033,18 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
1032 1033
1033static const struct of_device_id exynos_i2s_match[]; 1034static const struct of_device_id exynos_i2s_match[];
1034 1035
1035static inline int samsung_i2s_get_driver_data(struct platform_device *pdev) 1036static inline const struct samsung_i2s_dai_data *samsung_i2s_get_driver_data(
1037 struct platform_device *pdev)
1036{ 1038{
1037#ifdef CONFIG_OF 1039#ifdef CONFIG_OF
1038 struct samsung_i2s_dai_data *data;
1039 if (pdev->dev.of_node) { 1040 if (pdev->dev.of_node) {
1040 const struct of_device_id *match; 1041 const struct of_device_id *match;
1041 match = of_match_node(exynos_i2s_match, pdev->dev.of_node); 1042 match = of_match_node(exynos_i2s_match, pdev->dev.of_node);
1042 data = (struct samsung_i2s_dai_data *) match->data; 1043 return match->data;
1043 return data->dai_type;
1044 } else 1044 } else
1045#endif 1045#endif
1046 return platform_get_device_id(pdev)->driver_data; 1046 return (struct samsung_i2s_dai_data *)
1047 platform_get_device_id(pdev)->driver_data;
1047} 1048}
1048 1049
1049#ifdef CONFIG_PM_RUNTIME 1050#ifdef CONFIG_PM_RUNTIME
@@ -1074,13 +1075,13 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1074 struct resource *res; 1075 struct resource *res;
1075 u32 regs_base, quirks = 0, idma_addr = 0; 1076 u32 regs_base, quirks = 0, idma_addr = 0;
1076 struct device_node *np = pdev->dev.of_node; 1077 struct device_node *np = pdev->dev.of_node;
1077 enum samsung_dai_type samsung_dai_type; 1078 const struct samsung_i2s_dai_data *i2s_dai_data;
1078 int ret = 0; 1079 int ret = 0;
1079 1080
1080 /* Call during Seconday interface registration */ 1081 /* Call during Seconday interface registration */
1081 samsung_dai_type = samsung_i2s_get_driver_data(pdev); 1082 i2s_dai_data = samsung_i2s_get_driver_data(pdev);
1082 1083
1083 if (samsung_dai_type == TYPE_SEC) { 1084 if (i2s_dai_data->dai_type == TYPE_SEC) {
1084 sec_dai = dev_get_drvdata(&pdev->dev); 1085 sec_dai = dev_get_drvdata(&pdev->dev);
1085 if (!sec_dai) { 1086 if (!sec_dai) {
1086 dev_err(&pdev->dev, "Unable to get drvdata\n"); 1087 dev_err(&pdev->dev, "Unable to get drvdata\n");
@@ -1129,15 +1130,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1129 idma_addr = i2s_cfg->idma_addr; 1130 idma_addr = i2s_cfg->idma_addr;
1130 } 1131 }
1131 } else { 1132 } else {
1132 if (of_find_property(np, "samsung,supports-6ch", NULL)) 1133 quirks = i2s_dai_data->quirks;
1133 quirks |= QUIRK_PRI_6CHAN;
1134
1135 if (of_find_property(np, "samsung,supports-secdai", NULL))
1136 quirks |= QUIRK_SEC_DAI;
1137
1138 if (of_find_property(np, "samsung,supports-rstclr", NULL))
1139 quirks |= QUIRK_NEED_RSTCLR;
1140
1141 if (of_property_read_u32(np, "samsung,idma-addr", 1134 if (of_property_read_u32(np, "samsung,idma-addr",
1142 &idma_addr)) { 1135 &idma_addr)) {
1143 if (quirks & QUIRK_SEC_DAI) { 1136 if (quirks & QUIRK_SEC_DAI) {
@@ -1250,27 +1243,44 @@ static int samsung_i2s_remove(struct platform_device *pdev)
1250 return 0; 1243 return 0;
1251} 1244}
1252 1245
1246static const struct samsung_i2s_dai_data i2sv3_dai_type = {
1247 .dai_type = TYPE_PRI,
1248 .quirks = QUIRK_NO_MUXPSR,
1249};
1250
1251static const struct samsung_i2s_dai_data i2sv5_dai_type = {
1252 .dai_type = TYPE_PRI,
1253 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR,
1254};
1255
1256static const struct samsung_i2s_dai_data samsung_dai_type_pri = {
1257 .dai_type = TYPE_PRI,
1258};
1259
1260static const struct samsung_i2s_dai_data samsung_dai_type_sec = {
1261 .dai_type = TYPE_SEC,
1262};
1263
1253static struct platform_device_id samsung_i2s_driver_ids[] = { 1264static struct platform_device_id samsung_i2s_driver_ids[] = {
1254 { 1265 {
1255 .name = "samsung-i2s", 1266 .name = "samsung-i2s",
1256 .driver_data = TYPE_PRI, 1267 .driver_data = (kernel_ulong_t)&samsung_dai_type_pri,
1257 }, { 1268 }, {
1258 .name = "samsung-i2s-sec", 1269 .name = "samsung-i2s-sec",
1259 .driver_data = TYPE_SEC, 1270 .driver_data = (kernel_ulong_t)&samsung_dai_type_sec,
1260 }, 1271 },
1261 {}, 1272 {},
1262}; 1273};
1263MODULE_DEVICE_TABLE(platform, samsung_i2s_driver_ids); 1274MODULE_DEVICE_TABLE(platform, samsung_i2s_driver_ids);
1264 1275
1265#ifdef CONFIG_OF 1276#ifdef CONFIG_OF
1266static struct samsung_i2s_dai_data samsung_i2s_dai_data_array[] = {
1267 [TYPE_PRI] = { TYPE_PRI },
1268 [TYPE_SEC] = { TYPE_SEC },
1269};
1270
1271static const struct of_device_id exynos_i2s_match[] = { 1277static const struct of_device_id exynos_i2s_match[] = {
1272 { .compatible = "samsung,i2s-v5", 1278 {
1273 .data = &samsung_i2s_dai_data_array[TYPE_PRI], 1279 .compatible = "samsung,s3c6410-i2s",
1280 .data = &i2sv3_dai_type,
1281 }, {
1282 .compatible = "samsung,s5pv210-i2s",
1283 .data = &i2sv5_dai_type,
1274 }, 1284 },
1275 {}, 1285 {},
1276}; 1286};