diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/Kconfig | 5 | ||||
-rw-r--r-- | sound/soc/codecs/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/codecs/rl6347a.c | 128 | ||||
-rw-r--r-- | sound/soc/codecs/rl6347a.h | 32 | ||||
-rw-r--r-- | sound/soc/codecs/rt286.c | 97 | ||||
-rw-r--r-- | sound/soc/codecs/rt5640.c | 5 | ||||
-rw-r--r-- | sound/soc/qcom/Kconfig | 9 | ||||
-rw-r--r-- | sound/soc/qcom/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/qcom/apq8016_sbc.c | 198 | ||||
-rw-r--r-- | sound/soc/qcom/storm.c | 26 | ||||
-rw-r--r-- | sound/soc/sh/rcar/core.c | 111 | ||||
-rw-r--r-- | sound/soc/sh/rcar/dma.c | 113 | ||||
-rw-r--r-- | sound/soc/sh/rcar/dvc.c | 30 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 112 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsrc-card.c | 438 | ||||
-rw-r--r-- | sound/soc/sh/rcar/src.c | 121 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ssi.c | 96 |
17 files changed, 950 insertions, 575 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 9b36011a814e..efaafce8ba38 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -509,6 +509,11 @@ config SND_SOC_RL6231 | |||
509 | default m if SND_SOC_RT5670=m | 509 | default m if SND_SOC_RT5670=m |
510 | default m if SND_SOC_RT5677=m | 510 | default m if SND_SOC_RT5677=m |
511 | 511 | ||
512 | config SND_SOC_RL6347A | ||
513 | tristate | ||
514 | default y if SND_SOC_RT286=y | ||
515 | default m if SND_SOC_RT286=m | ||
516 | |||
512 | config SND_SOC_RT286 | 517 | config SND_SOC_RT286 |
513 | tristate | 518 | tristate |
514 | depends on I2C | 519 | depends on I2C |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3dcf5ac85e89..cf160d972cb3 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -77,6 +77,7 @@ snd-soc-pcm512x-objs := pcm512x.o | |||
77 | snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o | 77 | snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o |
78 | snd-soc-pcm512x-spi-objs := pcm512x-spi.o | 78 | snd-soc-pcm512x-spi-objs := pcm512x-spi.o |
79 | snd-soc-rl6231-objs := rl6231.o | 79 | snd-soc-rl6231-objs := rl6231.o |
80 | snd-soc-rl6347a-objs := rl6347a.o | ||
80 | snd-soc-rt286-objs := rt286.o | 81 | snd-soc-rt286-objs := rt286.o |
81 | snd-soc-rt5631-objs := rt5631.o | 82 | snd-soc-rt5631-objs := rt5631.o |
82 | snd-soc-rt5640-objs := rt5640.o | 83 | snd-soc-rt5640-objs := rt5640.o |
@@ -263,6 +264,7 @@ obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o | |||
263 | obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o | 264 | obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o |
264 | obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o | 265 | obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o |
265 | obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o | 266 | obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o |
267 | obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o | ||
266 | obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o | 268 | obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o |
267 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o | 269 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o |
268 | obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o | 270 | obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o |
diff --git a/sound/soc/codecs/rl6347a.c b/sound/soc/codecs/rl6347a.c new file mode 100644 index 000000000000..91d5166bd3a1 --- /dev/null +++ b/sound/soc/codecs/rl6347a.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * rl6347a.c - RL6347A class device shared support | ||
3 | * | ||
4 | * Copyright 2015 Realtek Semiconductor Corp. | ||
5 | * | ||
6 | * Author: Oder Chiou <oder_chiou@realtek.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/moduleparam.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/pm.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/spi/spi.h> | ||
21 | #include <linux/dmi.h> | ||
22 | #include <linux/acpi.h> | ||
23 | #include <sound/core.h> | ||
24 | #include <sound/pcm.h> | ||
25 | #include <sound/pcm_params.h> | ||
26 | #include <sound/soc.h> | ||
27 | #include <sound/soc-dapm.h> | ||
28 | #include <sound/initval.h> | ||
29 | #include <sound/tlv.h> | ||
30 | #include <sound/jack.h> | ||
31 | #include <linux/workqueue.h> | ||
32 | #include <sound/hda_verbs.h> | ||
33 | |||
34 | #include "rl6347a.h" | ||
35 | |||
36 | int rl6347a_hw_write(void *context, unsigned int reg, unsigned int value) | ||
37 | { | ||
38 | struct i2c_client *client = context; | ||
39 | struct rl6347a_priv *rl6347a = i2c_get_clientdata(client); | ||
40 | u8 data[4]; | ||
41 | int ret, i; | ||
42 | |||
43 | /* handle index registers */ | ||
44 | if (reg <= 0xff) { | ||
45 | rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg); | ||
46 | for (i = 0; i < rl6347a->index_cache_size; i++) { | ||
47 | if (reg == rl6347a->index_cache[i].reg) { | ||
48 | rl6347a->index_cache[i].def = value; | ||
49 | break; | ||
50 | } | ||
51 | |||
52 | } | ||
53 | reg = RL6347A_PROC_COEF; | ||
54 | } | ||
55 | |||
56 | data[0] = (reg >> 24) & 0xff; | ||
57 | data[1] = (reg >> 16) & 0xff; | ||
58 | /* | ||
59 | * 4 bit VID: reg should be 0 | ||
60 | * 12 bit VID: value should be 0 | ||
61 | * So we use an OR operator to handle it rather than use if condition. | ||
62 | */ | ||
63 | data[2] = ((reg >> 8) & 0xff) | ((value >> 8) & 0xff); | ||
64 | data[3] = value & 0xff; | ||
65 | |||
66 | ret = i2c_master_send(client, data, 4); | ||
67 | |||
68 | if (ret == 4) | ||
69 | return 0; | ||
70 | else | ||
71 | pr_err("ret=%d\n", ret); | ||
72 | if (ret < 0) | ||
73 | return ret; | ||
74 | else | ||
75 | return -EIO; | ||
76 | } | ||
77 | EXPORT_SYMBOL_GPL(rl6347a_hw_write); | ||
78 | |||
79 | int rl6347a_hw_read(void *context, unsigned int reg, unsigned int *value) | ||
80 | { | ||
81 | struct i2c_client *client = context; | ||
82 | struct i2c_msg xfer[2]; | ||
83 | int ret; | ||
84 | __be32 be_reg; | ||
85 | unsigned int index, vid, buf = 0x0; | ||
86 | |||
87 | /* handle index registers */ | ||
88 | if (reg <= 0xff) { | ||
89 | rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg); | ||
90 | reg = RL6347A_PROC_COEF; | ||
91 | } | ||
92 | |||
93 | reg = reg | 0x80000; | ||
94 | vid = (reg >> 8) & 0xfff; | ||
95 | |||
96 | if (AC_VERB_GET_AMP_GAIN_MUTE == (vid & 0xf00)) { | ||
97 | index = (reg >> 8) & 0xf; | ||
98 | reg = (reg & ~0xf0f) | index; | ||
99 | } | ||
100 | be_reg = cpu_to_be32(reg); | ||
101 | |||
102 | /* Write register */ | ||
103 | xfer[0].addr = client->addr; | ||
104 | xfer[0].flags = 0; | ||
105 | xfer[0].len = 4; | ||
106 | xfer[0].buf = (u8 *)&be_reg; | ||
107 | |||
108 | /* Read data */ | ||
109 | xfer[1].addr = client->addr; | ||
110 | xfer[1].flags = I2C_M_RD; | ||
111 | xfer[1].len = 4; | ||
112 | xfer[1].buf = (u8 *)&buf; | ||
113 | |||
114 | ret = i2c_transfer(client->adapter, xfer, 2); | ||
115 | if (ret < 0) | ||
116 | return ret; | ||
117 | else if (ret != 2) | ||
118 | return -EIO; | ||
119 | |||
120 | *value = be32_to_cpu(buf); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | EXPORT_SYMBOL_GPL(rl6347a_hw_read); | ||
125 | |||
126 | MODULE_DESCRIPTION("RL6347A class device shared support"); | ||
127 | MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>"); | ||
128 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/rl6347a.h b/sound/soc/codecs/rl6347a.h new file mode 100644 index 000000000000..1cb56e50b7f3 --- /dev/null +++ b/sound/soc/codecs/rl6347a.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * rl6347a.h - RL6347A class device shared support | ||
3 | * | ||
4 | * Copyright 2015 Realtek Semiconductor Corp. | ||
5 | * | ||
6 | * Author: Oder Chiou <oder_chiou@realtek.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | #ifndef __RL6347A_H__ | ||
13 | #define __RL6347A_H__ | ||
14 | |||
15 | #define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D) | ||
16 | |||
17 | #define RL6347A_VENDOR_REGISTERS 0x20 | ||
18 | |||
19 | #define RL6347A_COEF_INDEX\ | ||
20 | VERB_CMD(AC_VERB_SET_COEF_INDEX, RL6347A_VENDOR_REGISTERS, 0) | ||
21 | #define RL6347A_PROC_COEF\ | ||
22 | VERB_CMD(AC_VERB_SET_PROC_COEF, RL6347A_VENDOR_REGISTERS, 0) | ||
23 | |||
24 | struct rl6347a_priv { | ||
25 | struct reg_default *index_cache; | ||
26 | int index_cache_size; | ||
27 | }; | ||
28 | |||
29 | int rl6347a_hw_write(void *context, unsigned int reg, unsigned int value); | ||
30 | int rl6347a_hw_read(void *context, unsigned int reg, unsigned int *value); | ||
31 | |||
32 | #endif /* __RL6347A_H__ */ | ||
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index c6cca0639e0d..5c43e263b2c1 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c | |||
@@ -31,12 +31,15 @@ | |||
31 | #include <sound/rt286.h> | 31 | #include <sound/rt286.h> |
32 | #include <sound/hda_verbs.h> | 32 | #include <sound/hda_verbs.h> |
33 | 33 | ||
34 | #include "rl6347a.h" | ||
34 | #include "rt286.h" | 35 | #include "rt286.h" |
35 | 36 | ||
36 | #define RT286_VENDOR_ID 0x10ec0286 | 37 | #define RT286_VENDOR_ID 0x10ec0286 |
37 | #define RT288_VENDOR_ID 0x10ec0288 | 38 | #define RT288_VENDOR_ID 0x10ec0288 |
38 | 39 | ||
39 | struct rt286_priv { | 40 | struct rt286_priv { |
41 | struct reg_default *index_cache; | ||
42 | int index_cache_size; | ||
40 | struct regmap *regmap; | 43 | struct regmap *regmap; |
41 | struct snd_soc_codec *codec; | 44 | struct snd_soc_codec *codec; |
42 | struct rt286_platform_data pdata; | 45 | struct rt286_platform_data pdata; |
@@ -45,7 +48,6 @@ struct rt286_priv { | |||
45 | struct delayed_work jack_detect_work; | 48 | struct delayed_work jack_detect_work; |
46 | int sys_clk; | 49 | int sys_clk; |
47 | int clk_id; | 50 | int clk_id; |
48 | struct reg_default *index_cache; | ||
49 | }; | 51 | }; |
50 | 52 | ||
51 | static struct reg_default rt286_index_def[] = { | 53 | static struct reg_default rt286_index_def[] = { |
@@ -185,94 +187,6 @@ static bool rt286_readable_register(struct device *dev, unsigned int reg) | |||
185 | } | 187 | } |
186 | } | 188 | } |
187 | 189 | ||
188 | static int rt286_hw_write(void *context, unsigned int reg, unsigned int value) | ||
189 | { | ||
190 | struct i2c_client *client = context; | ||
191 | struct rt286_priv *rt286 = i2c_get_clientdata(client); | ||
192 | u8 data[4]; | ||
193 | int ret, i; | ||
194 | |||
195 | /* handle index registers */ | ||
196 | if (reg <= 0xff) { | ||
197 | rt286_hw_write(client, RT286_COEF_INDEX, reg); | ||
198 | for (i = 0; i < INDEX_CACHE_SIZE; i++) { | ||
199 | if (reg == rt286->index_cache[i].reg) { | ||
200 | rt286->index_cache[i].def = value; | ||
201 | break; | ||
202 | } | ||
203 | |||
204 | } | ||
205 | reg = RT286_PROC_COEF; | ||
206 | } | ||
207 | |||
208 | data[0] = (reg >> 24) & 0xff; | ||
209 | data[1] = (reg >> 16) & 0xff; | ||
210 | /* | ||
211 | * 4 bit VID: reg should be 0 | ||
212 | * 12 bit VID: value should be 0 | ||
213 | * So we use an OR operator to handle it rather than use if condition. | ||
214 | */ | ||
215 | data[2] = ((reg >> 8) & 0xff) | ((value >> 8) & 0xff); | ||
216 | data[3] = value & 0xff; | ||
217 | |||
218 | ret = i2c_master_send(client, data, 4); | ||
219 | |||
220 | if (ret == 4) | ||
221 | return 0; | ||
222 | else | ||
223 | pr_err("ret=%d\n", ret); | ||
224 | if (ret < 0) | ||
225 | return ret; | ||
226 | else | ||
227 | return -EIO; | ||
228 | } | ||
229 | |||
230 | static int rt286_hw_read(void *context, unsigned int reg, unsigned int *value) | ||
231 | { | ||
232 | struct i2c_client *client = context; | ||
233 | struct i2c_msg xfer[2]; | ||
234 | int ret; | ||
235 | __be32 be_reg; | ||
236 | unsigned int index, vid, buf = 0x0; | ||
237 | |||
238 | /* handle index registers */ | ||
239 | if (reg <= 0xff) { | ||
240 | rt286_hw_write(client, RT286_COEF_INDEX, reg); | ||
241 | reg = RT286_PROC_COEF; | ||
242 | } | ||
243 | |||
244 | reg = reg | 0x80000; | ||
245 | vid = (reg >> 8) & 0xfff; | ||
246 | |||
247 | if (AC_VERB_GET_AMP_GAIN_MUTE == (vid & 0xf00)) { | ||
248 | index = (reg >> 8) & 0xf; | ||
249 | reg = (reg & ~0xf0f) | index; | ||
250 | } | ||
251 | be_reg = cpu_to_be32(reg); | ||
252 | |||
253 | /* Write register */ | ||
254 | xfer[0].addr = client->addr; | ||
255 | xfer[0].flags = 0; | ||
256 | xfer[0].len = 4; | ||
257 | xfer[0].buf = (u8 *)&be_reg; | ||
258 | |||
259 | /* Read data */ | ||
260 | xfer[1].addr = client->addr; | ||
261 | xfer[1].flags = I2C_M_RD; | ||
262 | xfer[1].len = 4; | ||
263 | xfer[1].buf = (u8 *)&buf; | ||
264 | |||
265 | ret = i2c_transfer(client->adapter, xfer, 2); | ||
266 | if (ret < 0) | ||
267 | return ret; | ||
268 | else if (ret != 2) | ||
269 | return -EIO; | ||
270 | |||
271 | *value = be32_to_cpu(buf); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | #ifdef CONFIG_PM | 190 | #ifdef CONFIG_PM |
277 | static void rt286_index_sync(struct snd_soc_codec *codec) | 191 | static void rt286_index_sync(struct snd_soc_codec *codec) |
278 | { | 192 | { |
@@ -1174,8 +1088,8 @@ static const struct regmap_config rt286_regmap = { | |||
1174 | .max_register = 0x02370100, | 1088 | .max_register = 0x02370100, |
1175 | .volatile_reg = rt286_volatile_register, | 1089 | .volatile_reg = rt286_volatile_register, |
1176 | .readable_reg = rt286_readable_register, | 1090 | .readable_reg = rt286_readable_register, |
1177 | .reg_write = rt286_hw_write, | 1091 | .reg_write = rl6347a_hw_write, |
1178 | .reg_read = rt286_hw_read, | 1092 | .reg_read = rl6347a_hw_read, |
1179 | .cache_type = REGCACHE_RBTREE, | 1093 | .cache_type = REGCACHE_RBTREE, |
1180 | .reg_defaults = rt286_reg, | 1094 | .reg_defaults = rt286_reg, |
1181 | .num_reg_defaults = ARRAY_SIZE(rt286_reg), | 1095 | .num_reg_defaults = ARRAY_SIZE(rt286_reg), |
@@ -1248,6 +1162,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c, | |||
1248 | } | 1162 | } |
1249 | 1163 | ||
1250 | rt286->index_cache = rt286_index_def; | 1164 | rt286->index_cache = rt286_index_def; |
1165 | rt286->index_cache_size = INDEX_CACHE_SIZE; | ||
1251 | rt286->i2c = i2c; | 1166 | rt286->i2c = i2c; |
1252 | i2c_set_clientdata(i2c, rt286); | 1167 | i2c_set_clientdata(i2c, rt286); |
1253 | 1168 | ||
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index f40752a6c242..9bc78e57513d 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c | |||
@@ -51,7 +51,7 @@ static const struct regmap_range_cfg rt5640_ranges[] = { | |||
51 | .window_len = 0x1, }, | 51 | .window_len = 0x1, }, |
52 | }; | 52 | }; |
53 | 53 | ||
54 | static struct reg_default init_list[] = { | 54 | static const struct reg_default init_list[] = { |
55 | {RT5640_PR_BASE + 0x3d, 0x3600}, | 55 | {RT5640_PR_BASE + 0x3d, 0x3600}, |
56 | {RT5640_PR_BASE + 0x12, 0x0aa8}, | 56 | {RT5640_PR_BASE + 0x12, 0x0aa8}, |
57 | {RT5640_PR_BASE + 0x14, 0x0aaa}, | 57 | {RT5640_PR_BASE + 0x14, 0x0aaa}, |
@@ -59,7 +59,6 @@ static struct reg_default init_list[] = { | |||
59 | {RT5640_PR_BASE + 0x21, 0xe0e0}, | 59 | {RT5640_PR_BASE + 0x21, 0xe0e0}, |
60 | {RT5640_PR_BASE + 0x23, 0x1804}, | 60 | {RT5640_PR_BASE + 0x23, 0x1804}, |
61 | }; | 61 | }; |
62 | #define RT5640_INIT_REG_LEN ARRAY_SIZE(init_list) | ||
63 | 62 | ||
64 | static const struct reg_default rt5640_reg[] = { | 63 | static const struct reg_default rt5640_reg[] = { |
65 | { 0x00, 0x000e }, | 64 | { 0x00, 0x000e }, |
@@ -2122,7 +2121,7 @@ MODULE_DEVICE_TABLE(of, rt5640_of_match); | |||
2122 | #endif | 2121 | #endif |
2123 | 2122 | ||
2124 | #ifdef CONFIG_ACPI | 2123 | #ifdef CONFIG_ACPI |
2125 | static struct acpi_device_id rt5640_acpi_match[] = { | 2124 | static const struct acpi_device_id rt5640_acpi_match[] = { |
2126 | { "INT33CA", 0 }, | 2125 | { "INT33CA", 0 }, |
2127 | { "10EC5640", 0 }, | 2126 | { "10EC5640", 0 }, |
2128 | { "10EC5642", 0 }, | 2127 | { "10EC5642", 0 }, |
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 938144c59e2b..807fedfa1c76 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig | |||
@@ -32,3 +32,12 @@ config SND_SOC_STORM | |||
32 | help | 32 | help |
33 | Say Y or M if you want add support for SoC audio on the | 33 | Say Y or M if you want add support for SoC audio on the |
34 | Qualcomm Technologies IPQ806X-based Storm board. | 34 | Qualcomm Technologies IPQ806X-based Storm board. |
35 | |||
36 | config SND_SOC_APQ8016_SBC | ||
37 | tristate "SoC Audio support for APQ8016 SBC platforms" | ||
38 | depends on SND_SOC_QCOM && (ARCH_QCOM || COMPILE_TEST) | ||
39 | select SND_SOC_LPASS_APQ8016 | ||
40 | help | ||
41 | Support for Qualcomm Technologies LPASS audio block in | ||
42 | APQ8016 SOC-based systems. | ||
43 | Say Y if you want to use audio devices on MI2S. | ||
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile index ac7630833fe5..79e5c50a8f71 100644 --- a/sound/soc/qcom/Makefile +++ b/sound/soc/qcom/Makefile | |||
@@ -11,5 +11,7 @@ obj-$(CONFIG_SND_SOC_LPASS_APQ8016) += snd-soc-lpass-apq8016.o | |||
11 | 11 | ||
12 | # Machine | 12 | # Machine |
13 | snd-soc-storm-objs := storm.o | 13 | snd-soc-storm-objs := storm.o |
14 | snd-soc-apq8016-sbc-objs := apq8016_sbc.o | ||
14 | 15 | ||
15 | obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o | 16 | obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o |
17 | obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o | ||
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c new file mode 100644 index 000000000000..1efdf0088ecd --- /dev/null +++ b/sound/soc/qcom/apq8016_sbc.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 The Linux Foundation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 and | ||
6 | * only version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/device.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <sound/pcm.h> | ||
23 | #include <sound/pcm_params.h> | ||
24 | #include <sound/soc.h> | ||
25 | #include <dt-bindings/sound/apq8016-lpass.h> | ||
26 | |||
27 | struct apq8016_sbc_data { | ||
28 | void __iomem *mic_iomux; | ||
29 | void __iomem *spkr_iomux; | ||
30 | struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ | ||
31 | }; | ||
32 | |||
33 | #define MIC_CTRL_QUA_WS_SLAVE_SEL_10 BIT(17) | ||
34 | #define MIC_CTRL_TLMM_SCLK_EN BIT(1) | ||
35 | #define SPKR_CTL_PRI_WS_SLAVE_SEL_11 (BIT(17) | BIT(16)) | ||
36 | |||
37 | static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) | ||
38 | { | ||
39 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
40 | struct snd_soc_card *card = rtd->card; | ||
41 | struct apq8016_sbc_data *pdata = snd_soc_card_get_drvdata(card); | ||
42 | int rval = 0; | ||
43 | |||
44 | switch (cpu_dai->id) { | ||
45 | case MI2S_PRIMARY: | ||
46 | writel(readl(pdata->spkr_iomux) | SPKR_CTL_PRI_WS_SLAVE_SEL_11, | ||
47 | pdata->spkr_iomux); | ||
48 | break; | ||
49 | |||
50 | case MI2S_QUATERNARY: | ||
51 | /* Configure the Quat MI2S to TLMM */ | ||
52 | writel(readl(pdata->mic_iomux) | MIC_CTRL_QUA_WS_SLAVE_SEL_10 | | ||
53 | MIC_CTRL_TLMM_SCLK_EN, | ||
54 | pdata->mic_iomux); | ||
55 | break; | ||
56 | |||
57 | default: | ||
58 | dev_err(card->dev, "unsupported cpu dai configuration\n"); | ||
59 | rval = -EINVAL; | ||
60 | break; | ||
61 | |||
62 | } | ||
63 | |||
64 | return rval; | ||
65 | } | ||
66 | |||
67 | static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) | ||
68 | { | ||
69 | struct device *dev = card->dev; | ||
70 | struct snd_soc_dai_link *link; | ||
71 | struct device_node *np, *codec, *cpu, *node = dev->of_node; | ||
72 | struct apq8016_sbc_data *data; | ||
73 | int ret, num_links; | ||
74 | |||
75 | ret = snd_soc_of_parse_card_name(card, "qcom,model"); | ||
76 | if (ret) { | ||
77 | dev_err(dev, "Error parsing card name: %d\n", ret); | ||
78 | return ERR_PTR(ret); | ||
79 | } | ||
80 | |||
81 | /* Populate links */ | ||
82 | num_links = of_get_child_count(node); | ||
83 | |||
84 | /* Allocate the private data and the DAI link array */ | ||
85 | data = devm_kzalloc(dev, sizeof(*data) + sizeof(*link) * num_links, | ||
86 | GFP_KERNEL); | ||
87 | if (!data) | ||
88 | return ERR_PTR(-ENOMEM); | ||
89 | |||
90 | card->dai_link = &data->dai_link[0]; | ||
91 | card->num_links = num_links; | ||
92 | |||
93 | link = data->dai_link; | ||
94 | |||
95 | for_each_child_of_node(node, np) { | ||
96 | cpu = of_get_child_by_name(np, "cpu"); | ||
97 | codec = of_get_child_by_name(np, "codec"); | ||
98 | |||
99 | if (!cpu || !codec) { | ||
100 | dev_err(dev, "Can't find cpu/codec DT node\n"); | ||
101 | return ERR_PTR(-EINVAL); | ||
102 | } | ||
103 | |||
104 | link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0); | ||
105 | if (!link->cpu_of_node) { | ||
106 | dev_err(card->dev, "error getting cpu phandle\n"); | ||
107 | return ERR_PTR(-EINVAL); | ||
108 | } | ||
109 | |||
110 | link->codec_of_node = of_parse_phandle(codec, "sound-dai", 0); | ||
111 | if (!link->codec_of_node) { | ||
112 | dev_err(card->dev, "error getting codec phandle\n"); | ||
113 | return ERR_PTR(-EINVAL); | ||
114 | } | ||
115 | |||
116 | ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name); | ||
117 | if (ret) { | ||
118 | dev_err(card->dev, "error getting cpu dai name\n"); | ||
119 | return ERR_PTR(ret); | ||
120 | } | ||
121 | |||
122 | ret = snd_soc_of_get_dai_name(codec, &link->codec_dai_name); | ||
123 | if (ret) { | ||
124 | dev_err(card->dev, "error getting codec dai name\n"); | ||
125 | return ERR_PTR(ret); | ||
126 | } | ||
127 | |||
128 | link->platform_of_node = link->cpu_of_node; | ||
129 | /* For now we only support playback */ | ||
130 | link->playback_only = true; | ||
131 | |||
132 | ret = of_property_read_string(np, "link-name", &link->name); | ||
133 | if (ret) { | ||
134 | dev_err(card->dev, "error getting codec dai_link name\n"); | ||
135 | return ERR_PTR(ret); | ||
136 | } | ||
137 | |||
138 | link->stream_name = link->name; | ||
139 | link->init = apq8016_sbc_dai_init; | ||
140 | link++; | ||
141 | } | ||
142 | |||
143 | return data; | ||
144 | } | ||
145 | |||
146 | static int apq8016_sbc_platform_probe(struct platform_device *pdev) | ||
147 | { | ||
148 | struct device *dev = &pdev->dev; | ||
149 | struct snd_soc_card *card; | ||
150 | struct apq8016_sbc_data *data; | ||
151 | struct resource *res; | ||
152 | |||
153 | card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); | ||
154 | if (!card) | ||
155 | return -ENOMEM; | ||
156 | |||
157 | card->dev = dev; | ||
158 | data = apq8016_sbc_parse_of(card); | ||
159 | if (IS_ERR(data)) { | ||
160 | dev_err(&pdev->dev, "Error resolving dai links: %ld\n", | ||
161 | PTR_ERR(data)); | ||
162 | return PTR_ERR(data); | ||
163 | } | ||
164 | |||
165 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mic-iomux"); | ||
166 | data->mic_iomux = devm_ioremap_resource(dev, res); | ||
167 | if (IS_ERR(data->mic_iomux)) | ||
168 | return PTR_ERR(data->mic_iomux); | ||
169 | |||
170 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spkr-iomux"); | ||
171 | data->spkr_iomux = devm_ioremap_resource(dev, res); | ||
172 | if (IS_ERR(data->spkr_iomux)) | ||
173 | return PTR_ERR(data->spkr_iomux); | ||
174 | |||
175 | platform_set_drvdata(pdev, data); | ||
176 | snd_soc_card_set_drvdata(card, data); | ||
177 | |||
178 | return devm_snd_soc_register_card(&pdev->dev, card); | ||
179 | } | ||
180 | |||
181 | static const struct of_device_id apq8016_sbc_device_id[] = { | ||
182 | { .compatible = "qcom,apq8016-sbc-sndcard" }, | ||
183 | {}, | ||
184 | }; | ||
185 | MODULE_DEVICE_TABLE(of, apq8016_sbc_device_id); | ||
186 | |||
187 | static struct platform_driver apq8016_sbc_platform_driver = { | ||
188 | .driver = { | ||
189 | .name = "qcom-apq8016-sbc", | ||
190 | .of_match_table = of_match_ptr(apq8016_sbc_device_id), | ||
191 | }, | ||
192 | .probe = apq8016_sbc_platform_probe, | ||
193 | }; | ||
194 | module_platform_driver(apq8016_sbc_platform_driver); | ||
195 | |||
196 | MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org"); | ||
197 | MODULE_DESCRIPTION("APQ8016 ASoC Machine Driver"); | ||
198 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/qcom/storm.c b/sound/soc/qcom/storm.c index b8bd296190ad..2d833bffdba0 100644 --- a/sound/soc/qcom/storm.c +++ b/sound/soc/qcom/storm.c | |||
@@ -69,11 +69,6 @@ static struct snd_soc_dai_link storm_dai_link = { | |||
69 | .ops = &storm_soc_ops, | 69 | .ops = &storm_soc_ops, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static struct snd_soc_card storm_soc_card = { | ||
73 | .name = "ipq806x-storm", | ||
74 | .dev = NULL, | ||
75 | }; | ||
76 | |||
77 | static int storm_parse_of(struct snd_soc_card *card) | 72 | static int storm_parse_of(struct snd_soc_card *card) |
78 | { | 73 | { |
79 | struct snd_soc_dai_link *dai_link = card->dai_link; | 74 | struct snd_soc_dai_link *dai_link = card->dai_link; |
@@ -99,14 +94,13 @@ static int storm_parse_of(struct snd_soc_card *card) | |||
99 | 94 | ||
100 | static int storm_platform_probe(struct platform_device *pdev) | 95 | static int storm_platform_probe(struct platform_device *pdev) |
101 | { | 96 | { |
102 | struct snd_soc_card *card = &storm_soc_card; | 97 | struct snd_soc_card *card; |
103 | int ret; | 98 | int ret; |
104 | 99 | ||
105 | if (card->dev) { | 100 | card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL); |
106 | dev_err(&pdev->dev, "%s() error, existing soundcard\n", | 101 | if (!card) |
107 | __func__); | 102 | return -ENOMEM; |
108 | return -ENODEV; | 103 | |
109 | } | ||
110 | card->dev = &pdev->dev; | 104 | card->dev = &pdev->dev; |
111 | platform_set_drvdata(pdev, card); | 105 | platform_set_drvdata(pdev, card); |
112 | 106 | ||
@@ -128,16 +122,12 @@ static int storm_platform_probe(struct platform_device *pdev) | |||
128 | } | 122 | } |
129 | 123 | ||
130 | ret = devm_snd_soc_register_card(&pdev->dev, card); | 124 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
131 | if (ret == -EPROBE_DEFER) { | 125 | if (ret) |
132 | card->dev = NULL; | ||
133 | return ret; | ||
134 | } else if (ret) { | ||
135 | dev_err(&pdev->dev, "%s() error registering soundcard: %d\n", | 126 | dev_err(&pdev->dev, "%s() error registering soundcard: %d\n", |
136 | __func__, ret); | 127 | __func__, ret); |
137 | return ret; | ||
138 | } | ||
139 | 128 | ||
140 | return 0; | 129 | return ret; |
130 | |||
141 | } | 131 | } |
142 | 132 | ||
143 | #ifdef CONFIG_OF | 133 | #ifdef CONFIG_OF |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index d460d2aa82ee..f1e5920654f6 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -137,15 +137,17 @@ char *rsnd_mod_name(struct rsnd_mod *mod) | |||
137 | return mod->ops->name; | 137 | return mod->ops->name; |
138 | } | 138 | } |
139 | 139 | ||
140 | struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod) | 140 | struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io, |
141 | struct rsnd_mod *mod) | ||
141 | { | 142 | { |
142 | if (!mod || !mod->ops || !mod->ops->dma_req) | 143 | if (!mod || !mod->ops || !mod->ops->dma_req) |
143 | return NULL; | 144 | return NULL; |
144 | 145 | ||
145 | return mod->ops->dma_req(mod); | 146 | return mod->ops->dma_req(io, mod); |
146 | } | 147 | } |
147 | 148 | ||
148 | int rsnd_mod_init(struct rsnd_mod *mod, | 149 | int rsnd_mod_init(struct rsnd_priv *priv, |
150 | struct rsnd_mod *mod, | ||
149 | struct rsnd_mod_ops *ops, | 151 | struct rsnd_mod_ops *ops, |
150 | struct clk *clk, | 152 | struct clk *clk, |
151 | enum rsnd_mod_type type, | 153 | enum rsnd_mod_type type, |
@@ -160,6 +162,7 @@ int rsnd_mod_init(struct rsnd_mod *mod, | |||
160 | mod->ops = ops; | 162 | mod->ops = ops; |
161 | mod->type = type; | 163 | mod->type = type; |
162 | mod->clk = clk; | 164 | mod->clk = clk; |
165 | mod->priv = priv; | ||
163 | 166 | ||
164 | return ret; | 167 | return ret; |
165 | } | 168 | } |
@@ -170,10 +173,31 @@ void rsnd_mod_quit(struct rsnd_mod *mod) | |||
170 | clk_unprepare(mod->clk); | 173 | clk_unprepare(mod->clk); |
171 | } | 174 | } |
172 | 175 | ||
173 | int rsnd_mod_is_working(struct rsnd_mod *mod) | 176 | void rsnd_mod_interrupt(struct rsnd_mod *mod, |
177 | void (*callback)(struct rsnd_mod *mod, | ||
178 | struct rsnd_dai_stream *io)) | ||
174 | { | 179 | { |
175 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 180 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
181 | struct rsnd_dai_stream *io; | ||
182 | struct rsnd_dai *rdai; | ||
183 | int i, j; | ||
184 | |||
185 | for_each_rsnd_dai(rdai, priv, j) { | ||
186 | |||
187 | for (i = 0; i < RSND_MOD_MAX; i++) { | ||
188 | io = &rdai->playback; | ||
189 | if (mod == io->mod[i]) | ||
190 | callback(mod, io); | ||
191 | |||
192 | io = &rdai->capture; | ||
193 | if (mod == io->mod[i]) | ||
194 | callback(mod, io); | ||
195 | } | ||
196 | } | ||
197 | } | ||
176 | 198 | ||
199 | int rsnd_io_is_working(struct rsnd_dai_stream *io) | ||
200 | { | ||
177 | /* see rsnd_dai_stream_init/quit() */ | 201 | /* see rsnd_dai_stream_init/quit() */ |
178 | return !!io->substream; | 202 | return !!io->substream; |
179 | } | 203 | } |
@@ -181,10 +205,9 @@ int rsnd_mod_is_working(struct rsnd_mod *mod) | |||
181 | /* | 205 | /* |
182 | * settting function | 206 | * settting function |
183 | */ | 207 | */ |
184 | u32 rsnd_get_adinr(struct rsnd_mod *mod) | 208 | u32 rsnd_get_adinr(struct rsnd_mod *mod, struct rsnd_dai_stream *io) |
185 | { | 209 | { |
186 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 210 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
187 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
188 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 211 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
189 | struct device *dev = rsnd_priv_to_dev(priv); | 212 | struct device *dev = rsnd_priv_to_dev(priv); |
190 | u32 adinr = runtime->channels; | 213 | u32 adinr = runtime->channels; |
@@ -207,26 +230,31 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) | |||
207 | /* | 230 | /* |
208 | * rsnd_dai functions | 231 | * rsnd_dai functions |
209 | */ | 232 | */ |
210 | #define __rsnd_mod_call(mod, func, param...) \ | 233 | #define __rsnd_mod_call(mod, io, func, param...) \ |
211 | ({ \ | 234 | ({ \ |
212 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ | 235 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ |
213 | struct device *dev = rsnd_priv_to_dev(priv); \ | 236 | struct device *dev = rsnd_priv_to_dev(priv); \ |
214 | u32 mask = (1 << __rsnd_mod_shift_##func) & ~(1 << 31); \ | 237 | u32 mask = 0xF << __rsnd_mod_shift_##func; \ |
215 | u32 call = __rsnd_mod_call_##func << __rsnd_mod_shift_##func; \ | 238 | u8 val = (mod->status >> __rsnd_mod_shift_##func) & 0xF; \ |
239 | u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \ | ||
216 | int ret = 0; \ | 240 | int ret = 0; \ |
217 | if ((mod->status & mask) == call) { \ | 241 | int called = 0; \ |
218 | dev_dbg(dev, "%s[%d] %s\n", \ | 242 | if (val == __rsnd_mod_call_##func) { \ |
219 | rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ | 243 | called = 1; \ |
220 | ret = (mod)->ops->func(mod, param); \ | 244 | ret = (mod)->ops->func(mod, io, param); \ |
221 | mod->status = (mod->status & ~mask) | (~call & mask); \ | 245 | mod->status = (mod->status & ~mask) + \ |
246 | (add << __rsnd_mod_shift_##func); \ | ||
222 | } \ | 247 | } \ |
248 | dev_dbg(dev, "%s[%d] 0x%08x %s\n", \ | ||
249 | rsnd_mod_name(mod), rsnd_mod_id(mod), mod->status, \ | ||
250 | called ? #func : ""); \ | ||
223 | ret; \ | 251 | ret; \ |
224 | }) | 252 | }) |
225 | 253 | ||
226 | #define rsnd_mod_call(mod, func, param...) \ | 254 | #define rsnd_mod_call(mod, io, func, param...) \ |
227 | (!(mod) ? -ENODEV : \ | 255 | (!(mod) ? -ENODEV : \ |
228 | !((mod)->ops->func) ? 0 : \ | 256 | !((mod)->ops->func) ? 0 : \ |
229 | __rsnd_mod_call(mod, func, param)) | 257 | __rsnd_mod_call(mod, io, func, param)) |
230 | 258 | ||
231 | #define rsnd_dai_call(fn, io, param...) \ | 259 | #define rsnd_dai_call(fn, io, param...) \ |
232 | ({ \ | 260 | ({ \ |
@@ -236,7 +264,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) | |||
236 | mod = (io)->mod[i]; \ | 264 | mod = (io)->mod[i]; \ |
237 | if (!mod) \ | 265 | if (!mod) \ |
238 | continue; \ | 266 | continue; \ |
239 | ret = rsnd_mod_call(mod, fn, param); \ | 267 | ret = rsnd_mod_call(mod, io, fn, param); \ |
240 | if (ret < 0) \ | 268 | if (ret < 0) \ |
241 | break; \ | 269 | break; \ |
242 | } \ | 270 | } \ |
@@ -260,7 +288,6 @@ static int rsnd_dai_connect(struct rsnd_mod *mod, | |||
260 | } | 288 | } |
261 | 289 | ||
262 | io->mod[mod->type] = mod; | 290 | io->mod[mod->type] = mod; |
263 | mod->io = io; | ||
264 | 291 | ||
265 | return 0; | 292 | return 0; |
266 | } | 293 | } |
@@ -268,7 +295,6 @@ static int rsnd_dai_connect(struct rsnd_mod *mod, | |||
268 | static void rsnd_dai_disconnect(struct rsnd_mod *mod, | 295 | static void rsnd_dai_disconnect(struct rsnd_mod *mod, |
269 | struct rsnd_dai_stream *io) | 296 | struct rsnd_dai_stream *io) |
270 | { | 297 | { |
271 | mod->io = NULL; | ||
272 | io->mod[mod->type] = NULL; | 298 | io->mod[mod->type] = NULL; |
273 | } | 299 | } |
274 | 300 | ||
@@ -302,7 +328,7 @@ int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional) | |||
302 | return pos; | 328 | return pos; |
303 | } | 329 | } |
304 | 330 | ||
305 | void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int byte) | 331 | bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int byte) |
306 | { | 332 | { |
307 | io->byte_pos += byte; | 333 | io->byte_pos += byte; |
308 | 334 | ||
@@ -319,8 +345,24 @@ void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int byte) | |||
319 | io->next_period_byte = io->byte_per_period; | 345 | io->next_period_byte = io->byte_per_period; |
320 | } | 346 | } |
321 | 347 | ||
322 | snd_pcm_period_elapsed(substream); | 348 | return true; |
323 | } | 349 | } |
350 | |||
351 | return false; | ||
352 | } | ||
353 | |||
354 | void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io) | ||
355 | { | ||
356 | struct snd_pcm_substream *substream = io->substream; | ||
357 | |||
358 | /* | ||
359 | * this function should be called... | ||
360 | * | ||
361 | * - if rsnd_dai_pointer_update() returns true | ||
362 | * - without spin lock | ||
363 | */ | ||
364 | |||
365 | snd_pcm_period_elapsed(substream); | ||
324 | } | 366 | } |
325 | 367 | ||
326 | static void rsnd_dai_stream_init(struct rsnd_dai_stream *io, | 368 | static void rsnd_dai_stream_init(struct rsnd_dai_stream *io, |
@@ -834,16 +876,18 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, | |||
834 | } | 876 | } |
835 | 877 | ||
836 | if (change) | 878 | if (change) |
837 | cfg->update(mod); | 879 | cfg->update(cfg->io, mod); |
838 | 880 | ||
839 | return change; | 881 | return change; |
840 | } | 882 | } |
841 | 883 | ||
842 | static int __rsnd_kctrl_new(struct rsnd_mod *mod, | 884 | static int __rsnd_kctrl_new(struct rsnd_mod *mod, |
885 | struct rsnd_dai_stream *io, | ||
843 | struct snd_soc_pcm_runtime *rtd, | 886 | struct snd_soc_pcm_runtime *rtd, |
844 | const unsigned char *name, | 887 | const unsigned char *name, |
845 | struct rsnd_kctrl_cfg *cfg, | 888 | struct rsnd_kctrl_cfg *cfg, |
846 | void (*update)(struct rsnd_mod *mod)) | 889 | void (*update)(struct rsnd_dai_stream *io, |
890 | struct rsnd_mod *mod)) | ||
847 | { | 891 | { |
848 | struct snd_soc_card *soc_card = rtd->card; | 892 | struct snd_soc_card *soc_card = rtd->card; |
849 | struct snd_card *card = rtd->card->snd_card; | 893 | struct snd_card *card = rtd->card->snd_card; |
@@ -872,6 +916,7 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod, | |||
872 | cfg->update = update; | 916 | cfg->update = update; |
873 | cfg->card = card; | 917 | cfg->card = card; |
874 | cfg->kctrl = kctrl; | 918 | cfg->kctrl = kctrl; |
919 | cfg->io = io; | ||
875 | 920 | ||
876 | return 0; | 921 | return 0; |
877 | } | 922 | } |
@@ -882,36 +927,42 @@ void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg) | |||
882 | } | 927 | } |
883 | 928 | ||
884 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, | 929 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, |
930 | struct rsnd_dai_stream *io, | ||
885 | struct snd_soc_pcm_runtime *rtd, | 931 | struct snd_soc_pcm_runtime *rtd, |
886 | const unsigned char *name, | 932 | const unsigned char *name, |
887 | void (*update)(struct rsnd_mod *mod), | 933 | void (*update)(struct rsnd_dai_stream *io, |
934 | struct rsnd_mod *mod), | ||
888 | struct rsnd_kctrl_cfg_m *_cfg, | 935 | struct rsnd_kctrl_cfg_m *_cfg, |
889 | u32 max) | 936 | u32 max) |
890 | { | 937 | { |
891 | _cfg->cfg.max = max; | 938 | _cfg->cfg.max = max; |
892 | _cfg->cfg.size = RSND_DVC_CHANNELS; | 939 | _cfg->cfg.size = RSND_DVC_CHANNELS; |
893 | _cfg->cfg.val = _cfg->val; | 940 | _cfg->cfg.val = _cfg->val; |
894 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); | 941 | return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); |
895 | } | 942 | } |
896 | 943 | ||
897 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, | 944 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, |
945 | struct rsnd_dai_stream *io, | ||
898 | struct snd_soc_pcm_runtime *rtd, | 946 | struct snd_soc_pcm_runtime *rtd, |
899 | const unsigned char *name, | 947 | const unsigned char *name, |
900 | void (*update)(struct rsnd_mod *mod), | 948 | void (*update)(struct rsnd_dai_stream *io, |
949 | struct rsnd_mod *mod), | ||
901 | struct rsnd_kctrl_cfg_s *_cfg, | 950 | struct rsnd_kctrl_cfg_s *_cfg, |
902 | u32 max) | 951 | u32 max) |
903 | { | 952 | { |
904 | _cfg->cfg.max = max; | 953 | _cfg->cfg.max = max; |
905 | _cfg->cfg.size = 1; | 954 | _cfg->cfg.size = 1; |
906 | _cfg->cfg.val = &_cfg->val; | 955 | _cfg->cfg.val = &_cfg->val; |
907 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); | 956 | return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); |
908 | } | 957 | } |
909 | 958 | ||
910 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, | 959 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, |
960 | struct rsnd_dai_stream *io, | ||
911 | struct snd_soc_pcm_runtime *rtd, | 961 | struct snd_soc_pcm_runtime *rtd, |
912 | const unsigned char *name, | 962 | const unsigned char *name, |
913 | struct rsnd_kctrl_cfg_s *_cfg, | 963 | struct rsnd_kctrl_cfg_s *_cfg, |
914 | void (*update)(struct rsnd_mod *mod), | 964 | void (*update)(struct rsnd_dai_stream *io, |
965 | struct rsnd_mod *mod), | ||
915 | const char * const *texts, | 966 | const char * const *texts, |
916 | u32 max) | 967 | u32 max) |
917 | { | 968 | { |
@@ -919,7 +970,7 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod, | |||
919 | _cfg->cfg.size = 1; | 970 | _cfg->cfg.size = 1; |
920 | _cfg->cfg.val = &_cfg->val; | 971 | _cfg->cfg.val = &_cfg->val; |
921 | _cfg->cfg.texts = texts; | 972 | _cfg->cfg.texts = texts; |
922 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); | 973 | return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); |
923 | } | 974 | } |
924 | 975 | ||
925 | /* | 976 | /* |
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 144308f15fb3..d306e298c63d 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c | |||
@@ -32,11 +32,12 @@ struct rsnd_dma_ctrl { | |||
32 | /* | 32 | /* |
33 | * Audio DMAC | 33 | * Audio DMAC |
34 | */ | 34 | */ |
35 | static void rsnd_dmaen_complete(void *data) | 35 | static void __rsnd_dmaen_complete(struct rsnd_mod *mod, |
36 | struct rsnd_dai_stream *io) | ||
36 | { | 37 | { |
37 | struct rsnd_dma *dma = (struct rsnd_dma *)data; | 38 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
38 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); | 39 | bool elapsed = false; |
39 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 40 | unsigned long flags; |
40 | 41 | ||
41 | /* | 42 | /* |
42 | * Renesas sound Gen1 needs 1 DMAC, | 43 | * Renesas sound Gen1 needs 1 DMAC, |
@@ -49,23 +50,36 @@ static void rsnd_dmaen_complete(void *data) | |||
49 | * rsnd_dai_pointer_update() will be called twice, | 50 | * rsnd_dai_pointer_update() will be called twice, |
50 | * ant it will breaks io->byte_pos | 51 | * ant it will breaks io->byte_pos |
51 | */ | 52 | */ |
53 | spin_lock_irqsave(&priv->lock, flags); | ||
54 | |||
55 | if (rsnd_io_is_working(io)) | ||
56 | elapsed = rsnd_dai_pointer_update(io, io->byte_per_period); | ||
52 | 57 | ||
53 | rsnd_dai_pointer_update(io, io->byte_per_period); | 58 | spin_unlock_irqrestore(&priv->lock, flags); |
59 | |||
60 | if (elapsed) | ||
61 | rsnd_dai_period_elapsed(io); | ||
54 | } | 62 | } |
55 | 63 | ||
56 | static void rsnd_dmaen_stop(struct rsnd_dma *dma) | 64 | static void rsnd_dmaen_complete(void *data) |
65 | { | ||
66 | struct rsnd_mod *mod = data; | ||
67 | |||
68 | rsnd_mod_interrupt(mod, __rsnd_dmaen_complete); | ||
69 | } | ||
70 | |||
71 | static void rsnd_dmaen_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) | ||
57 | { | 72 | { |
58 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); | 73 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); |
59 | 74 | ||
60 | dmaengine_terminate_all(dmaen->chan); | 75 | dmaengine_terminate_all(dmaen->chan); |
61 | } | 76 | } |
62 | 77 | ||
63 | static void rsnd_dmaen_start(struct rsnd_dma *dma) | 78 | static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
64 | { | 79 | { |
65 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); | 80 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); |
66 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); | 81 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); |
67 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 82 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
68 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
69 | struct snd_pcm_substream *substream = io->substream; | 83 | struct snd_pcm_substream *substream = io->substream; |
70 | struct device *dev = rsnd_priv_to_dev(priv); | 84 | struct device *dev = rsnd_priv_to_dev(priv); |
71 | struct dma_async_tx_descriptor *desc; | 85 | struct dma_async_tx_descriptor *desc; |
@@ -84,7 +98,7 @@ static void rsnd_dmaen_start(struct rsnd_dma *dma) | |||
84 | } | 98 | } |
85 | 99 | ||
86 | desc->callback = rsnd_dmaen_complete; | 100 | desc->callback = rsnd_dmaen_complete; |
87 | desc->callback_param = dma; | 101 | desc->callback_param = mod; |
88 | 102 | ||
89 | if (dmaengine_submit(desc) < 0) { | 103 | if (dmaengine_submit(desc) < 0) { |
90 | dev_err(dev, "dmaengine_submit() fail\n"); | 104 | dev_err(dev, "dmaengine_submit() fail\n"); |
@@ -115,7 +129,8 @@ struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, | |||
115 | return chan; | 129 | return chan; |
116 | } | 130 | } |
117 | 131 | ||
118 | static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_mod *mod_from, | 132 | static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io, |
133 | struct rsnd_mod *mod_from, | ||
119 | struct rsnd_mod *mod_to) | 134 | struct rsnd_mod *mod_to) |
120 | { | 135 | { |
121 | if ((!mod_from && !mod_to) || | 136 | if ((!mod_from && !mod_to) || |
@@ -123,19 +138,19 @@ static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_mod *mod_from, | |||
123 | return NULL; | 138 | return NULL; |
124 | 139 | ||
125 | if (mod_from) | 140 | if (mod_from) |
126 | return rsnd_mod_dma_req(mod_from); | 141 | return rsnd_mod_dma_req(io, mod_from); |
127 | else | 142 | else |
128 | return rsnd_mod_dma_req(mod_to); | 143 | return rsnd_mod_dma_req(io, mod_to); |
129 | } | 144 | } |
130 | 145 | ||
131 | static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | 146 | static int rsnd_dmaen_init(struct rsnd_dai_stream *io, |
147 | struct rsnd_dma *dma, int id, | ||
132 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) | 148 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) |
133 | { | 149 | { |
134 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); | 150 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); |
151 | struct rsnd_priv *priv = rsnd_io_to_priv(io); | ||
135 | struct device *dev = rsnd_priv_to_dev(priv); | 152 | struct device *dev = rsnd_priv_to_dev(priv); |
136 | struct dma_slave_config cfg = {}; | 153 | struct dma_slave_config cfg = {}; |
137 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); | ||
138 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
139 | int is_play = rsnd_io_is_play(io); | 154 | int is_play = rsnd_io_is_play(io); |
140 | int ret; | 155 | int ret; |
141 | 156 | ||
@@ -145,7 +160,7 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | |||
145 | } | 160 | } |
146 | 161 | ||
147 | if (dev->of_node) { | 162 | if (dev->of_node) { |
148 | dmaen->chan = rsnd_dmaen_request_channel(mod_from, mod_to); | 163 | dmaen->chan = rsnd_dmaen_request_channel(io, mod_from, mod_to); |
149 | } else { | 164 | } else { |
150 | dma_cap_mask_t mask; | 165 | dma_cap_mask_t mask; |
151 | 166 | ||
@@ -177,7 +192,7 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | |||
177 | return 0; | 192 | return 0; |
178 | 193 | ||
179 | rsnd_dma_init_err: | 194 | rsnd_dma_init_err: |
180 | rsnd_dma_quit(dma); | 195 | rsnd_dma_quit(io, dma); |
181 | rsnd_dma_channel_err: | 196 | rsnd_dma_channel_err: |
182 | 197 | ||
183 | /* | 198 | /* |
@@ -189,7 +204,7 @@ rsnd_dma_channel_err: | |||
189 | return -EAGAIN; | 204 | return -EAGAIN; |
190 | } | 205 | } |
191 | 206 | ||
192 | static void rsnd_dmaen_quit(struct rsnd_dma *dma) | 207 | static void rsnd_dmaen_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
193 | { | 208 | { |
194 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); | 209 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); |
195 | 210 | ||
@@ -238,9 +253,9 @@ static const u8 gen2_id_table_cmd[] = { | |||
238 | 0x38, /* SCU_CMD1 */ | 253 | 0x38, /* SCU_CMD1 */ |
239 | }; | 254 | }; |
240 | 255 | ||
241 | static u32 rsnd_dmapp_get_id(struct rsnd_mod *mod) | 256 | static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io, |
257 | struct rsnd_mod *mod) | ||
242 | { | 258 | { |
243 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
244 | struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); | 259 | struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); |
245 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); | 260 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); |
246 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); | 261 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); |
@@ -268,11 +283,12 @@ static u32 rsnd_dmapp_get_id(struct rsnd_mod *mod) | |||
268 | return entry[id]; | 283 | return entry[id]; |
269 | } | 284 | } |
270 | 285 | ||
271 | static u32 rsnd_dmapp_get_chcr(struct rsnd_mod *mod_from, | 286 | static u32 rsnd_dmapp_get_chcr(struct rsnd_dai_stream *io, |
287 | struct rsnd_mod *mod_from, | ||
272 | struct rsnd_mod *mod_to) | 288 | struct rsnd_mod *mod_to) |
273 | { | 289 | { |
274 | return (rsnd_dmapp_get_id(mod_from) << 24) + | 290 | return (rsnd_dmapp_get_id(io, mod_from) << 24) + |
275 | (rsnd_dmapp_get_id(mod_to) << 16); | 291 | (rsnd_dmapp_get_id(io, mod_to) << 16); |
276 | } | 292 | } |
277 | 293 | ||
278 | #define rsnd_dmapp_addr(dmac, dma, reg) \ | 294 | #define rsnd_dmapp_addr(dmac, dma, reg) \ |
@@ -299,7 +315,7 @@ static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg) | |||
299 | return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); | 315 | return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); |
300 | } | 316 | } |
301 | 317 | ||
302 | static void rsnd_dmapp_stop(struct rsnd_dma *dma) | 318 | static void rsnd_dmapp_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
303 | { | 319 | { |
304 | int i; | 320 | int i; |
305 | 321 | ||
@@ -312,7 +328,7 @@ static void rsnd_dmapp_stop(struct rsnd_dma *dma) | |||
312 | } | 328 | } |
313 | } | 329 | } |
314 | 330 | ||
315 | static void rsnd_dmapp_start(struct rsnd_dma *dma) | 331 | static void rsnd_dmapp_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
316 | { | 332 | { |
317 | struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); | 333 | struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); |
318 | 334 | ||
@@ -321,19 +337,21 @@ static void rsnd_dmapp_start(struct rsnd_dma *dma) | |||
321 | rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR); | 337 | rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR); |
322 | } | 338 | } |
323 | 339 | ||
324 | static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | 340 | static int rsnd_dmapp_init(struct rsnd_dai_stream *io, |
341 | struct rsnd_dma *dma, int id, | ||
325 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) | 342 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) |
326 | { | 343 | { |
327 | struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); | 344 | struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); |
345 | struct rsnd_priv *priv = rsnd_io_to_priv(io); | ||
328 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); | 346 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); |
329 | struct device *dev = rsnd_priv_to_dev(priv); | 347 | struct device *dev = rsnd_priv_to_dev(priv); |
330 | 348 | ||
331 | dmapp->dmapp_id = dmac->dmapp_num; | 349 | dmapp->dmapp_id = dmac->dmapp_num; |
332 | dmapp->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE; | 350 | dmapp->chcr = rsnd_dmapp_get_chcr(io, mod_from, mod_to) | PDMACHCR_DE; |
333 | 351 | ||
334 | dmac->dmapp_num++; | 352 | dmac->dmapp_num++; |
335 | 353 | ||
336 | rsnd_dmapp_stop(dma); | 354 | rsnd_dmapp_stop(io, dma); |
337 | 355 | ||
338 | dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n", | 356 | dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n", |
339 | dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr); | 357 | dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr); |
@@ -386,12 +404,12 @@ static struct rsnd_dma_ops rsnd_dmapp_ops = { | |||
386 | #define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) | 404 | #define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) |
387 | 405 | ||
388 | static dma_addr_t | 406 | static dma_addr_t |
389 | rsnd_gen2_dma_addr(struct rsnd_priv *priv, | 407 | rsnd_gen2_dma_addr(struct rsnd_dai_stream *io, |
390 | struct rsnd_mod *mod, | 408 | struct rsnd_mod *mod, |
391 | int is_play, int is_from) | 409 | int is_play, int is_from) |
392 | { | 410 | { |
411 | struct rsnd_priv *priv = rsnd_io_to_priv(io); | ||
393 | struct device *dev = rsnd_priv_to_dev(priv); | 412 | struct device *dev = rsnd_priv_to_dev(priv); |
394 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
395 | phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI); | 413 | phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI); |
396 | phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU); | 414 | phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU); |
397 | int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod); | 415 | int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod); |
@@ -438,7 +456,7 @@ rsnd_gen2_dma_addr(struct rsnd_priv *priv, | |||
438 | dev_err(dev, "DVC is selected without SRC\n"); | 456 | dev_err(dev, "DVC is selected without SRC\n"); |
439 | 457 | ||
440 | /* use SSIU or SSI ? */ | 458 | /* use SSIU or SSI ? */ |
441 | if (is_ssi && rsnd_ssi_use_busif(mod)) | 459 | if (is_ssi && rsnd_ssi_use_busif(io, mod)) |
442 | is_ssi++; | 460 | is_ssi++; |
443 | 461 | ||
444 | return (is_from) ? | 462 | return (is_from) ? |
@@ -446,10 +464,12 @@ rsnd_gen2_dma_addr(struct rsnd_priv *priv, | |||
446 | dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr; | 464 | dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr; |
447 | } | 465 | } |
448 | 466 | ||
449 | static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv, | 467 | static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io, |
450 | struct rsnd_mod *mod, | 468 | struct rsnd_mod *mod, |
451 | int is_play, int is_from) | 469 | int is_play, int is_from) |
452 | { | 470 | { |
471 | struct rsnd_priv *priv = rsnd_io_to_priv(io); | ||
472 | |||
453 | /* | 473 | /* |
454 | * gen1 uses default DMA addr | 474 | * gen1 uses default DMA addr |
455 | */ | 475 | */ |
@@ -459,17 +479,17 @@ static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv, | |||
459 | if (!mod) | 479 | if (!mod) |
460 | return 0; | 480 | return 0; |
461 | 481 | ||
462 | return rsnd_gen2_dma_addr(priv, mod, is_play, is_from); | 482 | return rsnd_gen2_dma_addr(io, mod, is_play, is_from); |
463 | } | 483 | } |
464 | 484 | ||
465 | #define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ | 485 | #define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ |
466 | static void rsnd_dma_of_path(struct rsnd_dma *dma, | 486 | static void rsnd_dma_of_path(struct rsnd_dma *dma, |
487 | struct rsnd_dai_stream *io, | ||
467 | int is_play, | 488 | int is_play, |
468 | struct rsnd_mod **mod_from, | 489 | struct rsnd_mod **mod_from, |
469 | struct rsnd_mod **mod_to) | 490 | struct rsnd_mod **mod_to) |
470 | { | 491 | { |
471 | struct rsnd_mod *this = rsnd_dma_to_mod(dma); | 492 | struct rsnd_mod *this = rsnd_dma_to_mod(dma); |
472 | struct rsnd_dai_stream *io = rsnd_mod_to_io(this); | ||
473 | struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); | 493 | struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); |
474 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); | 494 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); |
475 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); | 495 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); |
@@ -524,17 +544,17 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma, | |||
524 | } | 544 | } |
525 | } | 545 | } |
526 | 546 | ||
527 | void rsnd_dma_stop(struct rsnd_dma *dma) | 547 | void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
528 | { | 548 | { |
529 | dma->ops->stop(dma); | 549 | dma->ops->stop(io, dma); |
530 | } | 550 | } |
531 | 551 | ||
532 | void rsnd_dma_start(struct rsnd_dma *dma) | 552 | void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
533 | { | 553 | { |
534 | dma->ops->start(dma); | 554 | dma->ops->start(io, dma); |
535 | } | 555 | } |
536 | 556 | ||
537 | void rsnd_dma_quit(struct rsnd_dma *dma) | 557 | void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
538 | { | 558 | { |
539 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); | 559 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); |
540 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 560 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
@@ -543,15 +563,14 @@ void rsnd_dma_quit(struct rsnd_dma *dma) | |||
543 | if (!dmac) | 563 | if (!dmac) |
544 | return; | 564 | return; |
545 | 565 | ||
546 | dma->ops->quit(dma); | 566 | dma->ops->quit(io, dma); |
547 | } | 567 | } |
548 | 568 | ||
549 | int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) | 569 | int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id) |
550 | { | 570 | { |
551 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); | ||
552 | struct rsnd_mod *mod_from; | 571 | struct rsnd_mod *mod_from; |
553 | struct rsnd_mod *mod_to; | 572 | struct rsnd_mod *mod_to; |
554 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 573 | struct rsnd_priv *priv = rsnd_io_to_priv(io); |
555 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); | 574 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); |
556 | int is_play = rsnd_io_is_play(io); | 575 | int is_play = rsnd_io_is_play(io); |
557 | 576 | ||
@@ -564,10 +583,10 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) | |||
564 | if (!dmac) | 583 | if (!dmac) |
565 | return -EAGAIN; | 584 | return -EAGAIN; |
566 | 585 | ||
567 | rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to); | 586 | rsnd_dma_of_path(dma, io, is_play, &mod_from, &mod_to); |
568 | 587 | ||
569 | dma->src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1); | 588 | dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1); |
570 | dma->dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0); | 589 | dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0); |
571 | 590 | ||
572 | /* for Gen2 */ | 591 | /* for Gen2 */ |
573 | if (mod_from && mod_to) | 592 | if (mod_from && mod_to) |
@@ -579,7 +598,7 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) | |||
579 | if (rsnd_is_gen1(priv)) | 598 | if (rsnd_is_gen1(priv)) |
580 | dma->ops = &rsnd_dmaen_ops; | 599 | dma->ops = &rsnd_dmaen_ops; |
581 | 600 | ||
582 | return dma->ops->init(priv, dma, id, mod_from, mod_to); | 601 | return dma->ops->init(io, dma, id, mod_from, mod_to); |
583 | } | 602 | } |
584 | 603 | ||
585 | int rsnd_dma_probe(struct platform_device *pdev, | 604 | int rsnd_dma_probe(struct platform_device *pdev, |
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index e5fcb062ad77..36fc020cbc18 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c | |||
@@ -63,7 +63,8 @@ static const char * const dvc_ramp_rate[] = { | |||
63 | "0.125 dB/8192 steps", /* 10111 */ | 63 | "0.125 dB/8192 steps", /* 10111 */ |
64 | }; | 64 | }; |
65 | 65 | ||
66 | static void rsnd_dvc_volume_update(struct rsnd_mod *mod) | 66 | static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io, |
67 | struct rsnd_mod *mod) | ||
67 | { | 68 | { |
68 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | 69 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); |
69 | u32 val[RSND_DVC_CHANNELS]; | 70 | u32 val[RSND_DVC_CHANNELS]; |
@@ -120,6 +121,7 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) | |||
120 | } | 121 | } |
121 | 122 | ||
122 | static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, | 123 | static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, |
124 | struct rsnd_dai_stream *io, | ||
123 | struct rsnd_priv *priv) | 125 | struct rsnd_priv *priv) |
124 | { | 126 | { |
125 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | 127 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); |
@@ -134,9 +136,9 @@ static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, | |||
134 | } | 136 | } |
135 | 137 | ||
136 | static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | 138 | static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, |
139 | struct rsnd_dai_stream *io, | ||
137 | struct rsnd_priv *priv) | 140 | struct rsnd_priv *priv) |
138 | { | 141 | { |
139 | struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod); | ||
140 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); | 142 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); |
141 | struct device *dev = rsnd_priv_to_dev(priv); | 143 | struct device *dev = rsnd_priv_to_dev(priv); |
142 | int dvc_id = rsnd_mod_id(dvc_mod); | 144 | int dvc_id = rsnd_mod_id(dvc_mod); |
@@ -168,10 +170,10 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | |||
168 | 170 | ||
169 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 1); | 171 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 1); |
170 | 172 | ||
171 | rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod)); | 173 | rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod, io)); |
172 | 174 | ||
173 | /* ch0/ch1 Volume */ | 175 | /* ch0/ch1 Volume */ |
174 | rsnd_dvc_volume_update(dvc_mod); | 176 | rsnd_dvc_volume_update(io, dvc_mod); |
175 | 177 | ||
176 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); | 178 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); |
177 | 179 | ||
@@ -181,6 +183,7 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | |||
181 | } | 183 | } |
182 | 184 | ||
183 | static int rsnd_dvc_quit(struct rsnd_mod *mod, | 185 | static int rsnd_dvc_quit(struct rsnd_mod *mod, |
186 | struct rsnd_dai_stream *io, | ||
184 | struct rsnd_priv *priv) | 187 | struct rsnd_priv *priv) |
185 | { | 188 | { |
186 | rsnd_mod_hw_stop(mod); | 189 | rsnd_mod_hw_stop(mod); |
@@ -189,6 +192,7 @@ static int rsnd_dvc_quit(struct rsnd_mod *mod, | |||
189 | } | 192 | } |
190 | 193 | ||
191 | static int rsnd_dvc_start(struct rsnd_mod *mod, | 194 | static int rsnd_dvc_start(struct rsnd_mod *mod, |
195 | struct rsnd_dai_stream *io, | ||
192 | struct rsnd_priv *priv) | 196 | struct rsnd_priv *priv) |
193 | { | 197 | { |
194 | rsnd_mod_write(mod, CMD_CTRL, 0x10); | 198 | rsnd_mod_write(mod, CMD_CTRL, 0x10); |
@@ -197,6 +201,7 @@ static int rsnd_dvc_start(struct rsnd_mod *mod, | |||
197 | } | 201 | } |
198 | 202 | ||
199 | static int rsnd_dvc_stop(struct rsnd_mod *mod, | 203 | static int rsnd_dvc_stop(struct rsnd_mod *mod, |
204 | struct rsnd_dai_stream *io, | ||
200 | struct rsnd_priv *priv) | 205 | struct rsnd_priv *priv) |
201 | { | 206 | { |
202 | rsnd_mod_write(mod, CMD_CTRL, 0); | 207 | rsnd_mod_write(mod, CMD_CTRL, 0); |
@@ -205,15 +210,15 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod, | |||
205 | } | 210 | } |
206 | 211 | ||
207 | static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | 212 | static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, |
213 | struct rsnd_dai_stream *io, | ||
208 | struct snd_soc_pcm_runtime *rtd) | 214 | struct snd_soc_pcm_runtime *rtd) |
209 | { | 215 | { |
210 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
211 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | 216 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); |
212 | int is_play = rsnd_io_is_play(io); | 217 | int is_play = rsnd_io_is_play(io); |
213 | int ret; | 218 | int ret; |
214 | 219 | ||
215 | /* Volume */ | 220 | /* Volume */ |
216 | ret = rsnd_kctrl_new_m(mod, rtd, | 221 | ret = rsnd_kctrl_new_m(mod, io, rtd, |
217 | is_play ? | 222 | is_play ? |
218 | "DVC Out Playback Volume" : "DVC In Capture Volume", | 223 | "DVC Out Playback Volume" : "DVC In Capture Volume", |
219 | rsnd_dvc_volume_update, | 224 | rsnd_dvc_volume_update, |
@@ -222,7 +227,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
222 | return ret; | 227 | return ret; |
223 | 228 | ||
224 | /* Mute */ | 229 | /* Mute */ |
225 | ret = rsnd_kctrl_new_m(mod, rtd, | 230 | ret = rsnd_kctrl_new_m(mod, io, rtd, |
226 | is_play ? | 231 | is_play ? |
227 | "DVC Out Mute Switch" : "DVC In Mute Switch", | 232 | "DVC Out Mute Switch" : "DVC In Mute Switch", |
228 | rsnd_dvc_volume_update, | 233 | rsnd_dvc_volume_update, |
@@ -231,7 +236,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
231 | return ret; | 236 | return ret; |
232 | 237 | ||
233 | /* Ramp */ | 238 | /* Ramp */ |
234 | ret = rsnd_kctrl_new_s(mod, rtd, | 239 | ret = rsnd_kctrl_new_s(mod, io, rtd, |
235 | is_play ? | 240 | is_play ? |
236 | "DVC Out Ramp Switch" : "DVC In Ramp Switch", | 241 | "DVC Out Ramp Switch" : "DVC In Ramp Switch", |
237 | rsnd_dvc_volume_update, | 242 | rsnd_dvc_volume_update, |
@@ -239,7 +244,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
239 | if (ret < 0) | 244 | if (ret < 0) |
240 | return ret; | 245 | return ret; |
241 | 246 | ||
242 | ret = rsnd_kctrl_new_e(mod, rtd, | 247 | ret = rsnd_kctrl_new_e(mod, io, rtd, |
243 | is_play ? | 248 | is_play ? |
244 | "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", | 249 | "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", |
245 | &dvc->rup, | 250 | &dvc->rup, |
@@ -248,7 +253,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
248 | if (ret < 0) | 253 | if (ret < 0) |
249 | return ret; | 254 | return ret; |
250 | 255 | ||
251 | ret = rsnd_kctrl_new_e(mod, rtd, | 256 | ret = rsnd_kctrl_new_e(mod, io, rtd, |
252 | is_play ? | 257 | is_play ? |
253 | "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", | 258 | "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", |
254 | &dvc->rdown, | 259 | &dvc->rdown, |
@@ -261,7 +266,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
261 | return 0; | 266 | return 0; |
262 | } | 267 | } |
263 | 268 | ||
264 | static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_mod *mod) | 269 | static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io, |
270 | struct rsnd_mod *mod) | ||
265 | { | 271 | { |
266 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 272 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
267 | 273 | ||
@@ -366,7 +372,7 @@ int rsnd_dvc_probe(struct platform_device *pdev, | |||
366 | 372 | ||
367 | dvc->info = &info->dvc_info[i]; | 373 | dvc->info = &info->dvc_info[i]; |
368 | 374 | ||
369 | ret = rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops, | 375 | ret = rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, |
370 | clk, RSND_MOD_DVC, i); | 376 | clk, RSND_MOD_DVC, i); |
371 | if (ret) | 377 | if (ret) |
372 | return ret; | 378 | return ret; |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 03ff071d012f..09fcc54a8ee0 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -165,18 +165,18 @@ void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod, | |||
165 | enum rsnd_reg reg, u32 data); | 165 | enum rsnd_reg reg, u32 data); |
166 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, | 166 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, |
167 | u32 mask, u32 data); | 167 | u32 mask, u32 data); |
168 | u32 rsnd_get_adinr(struct rsnd_mod *mod); | 168 | u32 rsnd_get_adinr(struct rsnd_mod *mod, struct rsnd_dai_stream *io); |
169 | 169 | ||
170 | /* | 170 | /* |
171 | * R-Car DMA | 171 | * R-Car DMA |
172 | */ | 172 | */ |
173 | struct rsnd_dma; | 173 | struct rsnd_dma; |
174 | struct rsnd_dma_ops { | 174 | struct rsnd_dma_ops { |
175 | void (*start)(struct rsnd_dma *dma); | 175 | void (*start)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
176 | void (*stop)(struct rsnd_dma *dma); | 176 | void (*stop)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
177 | int (*init)(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | 177 | int (*init)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id, |
178 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to); | 178 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to); |
179 | void (*quit)(struct rsnd_dma *dma); | 179 | void (*quit)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
180 | }; | 180 | }; |
181 | 181 | ||
182 | struct rsnd_dmaen { | 182 | struct rsnd_dmaen { |
@@ -200,10 +200,10 @@ struct rsnd_dma { | |||
200 | #define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) | 200 | #define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) |
201 | #define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) | 201 | #define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) |
202 | 202 | ||
203 | void rsnd_dma_start(struct rsnd_dma *dma); | 203 | void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
204 | void rsnd_dma_stop(struct rsnd_dma *dma); | 204 | void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
205 | int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id); | 205 | int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id); |
206 | void rsnd_dma_quit(struct rsnd_dma *dma); | 206 | void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
207 | int rsnd_dma_probe(struct platform_device *pdev, | 207 | int rsnd_dma_probe(struct platform_device *pdev, |
208 | const struct rsnd_of_data *of_data, | 208 | const struct rsnd_of_data *of_data, |
209 | struct rsnd_priv *priv); | 209 | struct rsnd_priv *priv); |
@@ -224,25 +224,35 @@ enum rsnd_mod_type { | |||
224 | 224 | ||
225 | struct rsnd_mod_ops { | 225 | struct rsnd_mod_ops { |
226 | char *name; | 226 | char *name; |
227 | struct dma_chan* (*dma_req)(struct rsnd_mod *mod); | 227 | struct dma_chan* (*dma_req)(struct rsnd_dai_stream *io, |
228 | struct rsnd_mod *mod); | ||
228 | int (*probe)(struct rsnd_mod *mod, | 229 | int (*probe)(struct rsnd_mod *mod, |
230 | struct rsnd_dai_stream *io, | ||
229 | struct rsnd_priv *priv); | 231 | struct rsnd_priv *priv); |
230 | int (*remove)(struct rsnd_mod *mod, | 232 | int (*remove)(struct rsnd_mod *mod, |
233 | struct rsnd_dai_stream *io, | ||
231 | struct rsnd_priv *priv); | 234 | struct rsnd_priv *priv); |
232 | int (*init)(struct rsnd_mod *mod, | 235 | int (*init)(struct rsnd_mod *mod, |
236 | struct rsnd_dai_stream *io, | ||
233 | struct rsnd_priv *priv); | 237 | struct rsnd_priv *priv); |
234 | int (*quit)(struct rsnd_mod *mod, | 238 | int (*quit)(struct rsnd_mod *mod, |
239 | struct rsnd_dai_stream *io, | ||
235 | struct rsnd_priv *priv); | 240 | struct rsnd_priv *priv); |
236 | int (*start)(struct rsnd_mod *mod, | 241 | int (*start)(struct rsnd_mod *mod, |
242 | struct rsnd_dai_stream *io, | ||
237 | struct rsnd_priv *priv); | 243 | struct rsnd_priv *priv); |
238 | int (*stop)(struct rsnd_mod *mod, | 244 | int (*stop)(struct rsnd_mod *mod, |
245 | struct rsnd_dai_stream *io, | ||
239 | struct rsnd_priv *priv); | 246 | struct rsnd_priv *priv); |
240 | int (*pcm_new)(struct rsnd_mod *mod, | 247 | int (*pcm_new)(struct rsnd_mod *mod, |
248 | struct rsnd_dai_stream *io, | ||
241 | struct snd_soc_pcm_runtime *rtd); | 249 | struct snd_soc_pcm_runtime *rtd); |
242 | int (*hw_params)(struct rsnd_mod *mod, | 250 | int (*hw_params)(struct rsnd_mod *mod, |
251 | struct rsnd_dai_stream *io, | ||
243 | struct snd_pcm_substream *substream, | 252 | struct snd_pcm_substream *substream, |
244 | struct snd_pcm_hw_params *hw_params); | 253 | struct snd_pcm_hw_params *hw_params); |
245 | int (*fallback)(struct rsnd_mod *mod, | 254 | int (*fallback)(struct rsnd_mod *mod, |
255 | struct rsnd_dai_stream *io, | ||
246 | struct rsnd_priv *priv); | 256 | struct rsnd_priv *priv); |
247 | }; | 257 | }; |
248 | 258 | ||
@@ -252,32 +262,43 @@ struct rsnd_mod { | |||
252 | enum rsnd_mod_type type; | 262 | enum rsnd_mod_type type; |
253 | struct rsnd_mod_ops *ops; | 263 | struct rsnd_mod_ops *ops; |
254 | struct rsnd_dma dma; | 264 | struct rsnd_dma dma; |
255 | struct rsnd_dai_stream *io; | 265 | struct rsnd_priv *priv; |
256 | struct clk *clk; | 266 | struct clk *clk; |
257 | u32 status; | 267 | u32 status; |
258 | }; | 268 | }; |
259 | /* | 269 | /* |
260 | * status | 270 | * status |
261 | * | 271 | * |
262 | * bit | 272 | * 0xH0000CBA |
263 | * 0 0: probe 1: remove | 273 | * |
264 | * 1 0: init 1: quit | 274 | * A 0: probe 1: remove |
265 | * 2 0: start 1: stop | 275 | * B 0: init 1: quit |
266 | * 3 0: pcm_new | 276 | * C 0: start 1: stop |
267 | * 4 0: fallback | ||
268 | * | 277 | * |
269 | * 31 bit is always called (see __rsnd_mod_call) | 278 | * H is always called (see __rsnd_mod_call) |
270 | * 31 0: hw_params | 279 | * H 0: pcm_new |
280 | * H 0: fallback | ||
281 | * H 0: hw_params | ||
271 | */ | 282 | */ |
272 | #define __rsnd_mod_shift_probe 0 | 283 | #define __rsnd_mod_shift_probe 0 |
273 | #define __rsnd_mod_shift_remove 0 | 284 | #define __rsnd_mod_shift_remove 0 |
274 | #define __rsnd_mod_shift_init 1 | 285 | #define __rsnd_mod_shift_init 4 |
275 | #define __rsnd_mod_shift_quit 1 | 286 | #define __rsnd_mod_shift_quit 4 |
276 | #define __rsnd_mod_shift_start 2 | 287 | #define __rsnd_mod_shift_start 8 |
277 | #define __rsnd_mod_shift_stop 2 | 288 | #define __rsnd_mod_shift_stop 8 |
278 | #define __rsnd_mod_shift_pcm_new 3 | 289 | #define __rsnd_mod_shift_pcm_new 28 /* always called */ |
279 | #define __rsnd_mod_shift_fallback 4 | 290 | #define __rsnd_mod_shift_fallback 28 /* always called */ |
280 | #define __rsnd_mod_shift_hw_params 31 /* always called */ | 291 | #define __rsnd_mod_shift_hw_params 28 /* always called */ |
292 | |||
293 | #define __rsnd_mod_add_probe 1 | ||
294 | #define __rsnd_mod_add_remove -1 | ||
295 | #define __rsnd_mod_add_init 1 | ||
296 | #define __rsnd_mod_add_quit -1 | ||
297 | #define __rsnd_mod_add_start 1 | ||
298 | #define __rsnd_mod_add_stop -1 | ||
299 | #define __rsnd_mod_add_pcm_new 0 | ||
300 | #define __rsnd_mod_add_fallback 0 | ||
301 | #define __rsnd_mod_add_hw_params 0 | ||
281 | 302 | ||
282 | #define __rsnd_mod_call_probe 0 | 303 | #define __rsnd_mod_call_probe 0 |
283 | #define __rsnd_mod_call_remove 1 | 304 | #define __rsnd_mod_call_remove 1 |
@@ -289,22 +310,25 @@ struct rsnd_mod { | |||
289 | #define __rsnd_mod_call_fallback 0 | 310 | #define __rsnd_mod_call_fallback 0 |
290 | #define __rsnd_mod_call_hw_params 0 | 311 | #define __rsnd_mod_call_hw_params 0 |
291 | 312 | ||
292 | #define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod))) | 313 | #define rsnd_mod_to_priv(mod) ((mod)->priv) |
293 | #define rsnd_mod_to_dma(mod) (&(mod)->dma) | 314 | #define rsnd_mod_to_dma(mod) (&(mod)->dma) |
294 | #define rsnd_mod_to_io(mod) ((mod)->io) | ||
295 | #define rsnd_mod_id(mod) ((mod)->id) | 315 | #define rsnd_mod_id(mod) ((mod)->id) |
296 | #define rsnd_mod_hw_start(mod) clk_enable((mod)->clk) | 316 | #define rsnd_mod_hw_start(mod) clk_enable((mod)->clk) |
297 | #define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk) | 317 | #define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk) |
298 | 318 | ||
299 | int rsnd_mod_init(struct rsnd_mod *mod, | 319 | int rsnd_mod_init(struct rsnd_priv *priv, |
320 | struct rsnd_mod *mod, | ||
300 | struct rsnd_mod_ops *ops, | 321 | struct rsnd_mod_ops *ops, |
301 | struct clk *clk, | 322 | struct clk *clk, |
302 | enum rsnd_mod_type type, | 323 | enum rsnd_mod_type type, |
303 | int id); | 324 | int id); |
304 | void rsnd_mod_quit(struct rsnd_mod *mod); | 325 | void rsnd_mod_quit(struct rsnd_mod *mod); |
305 | char *rsnd_mod_name(struct rsnd_mod *mod); | 326 | char *rsnd_mod_name(struct rsnd_mod *mod); |
306 | int rsnd_mod_is_working(struct rsnd_mod *mod); | 327 | struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io, |
307 | struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod); | 328 | struct rsnd_mod *mod); |
329 | void rsnd_mod_interrupt(struct rsnd_mod *mod, | ||
330 | void (*callback)(struct rsnd_mod *mod, | ||
331 | struct rsnd_dai_stream *io)); | ||
308 | 332 | ||
309 | /* | 333 | /* |
310 | * R-Car sound DAI | 334 | * R-Car sound DAI |
@@ -329,7 +353,7 @@ struct rsnd_dai_stream { | |||
329 | #define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) | 353 | #define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) |
330 | #define rsnd_io_to_runtime(io) ((io)->substream ? \ | 354 | #define rsnd_io_to_runtime(io) ((io)->substream ? \ |
331 | (io)->substream->runtime : NULL) | 355 | (io)->substream->runtime : NULL) |
332 | 356 | int rsnd_io_is_working(struct rsnd_dai_stream *io); | |
333 | 357 | ||
334 | struct rsnd_dai { | 358 | struct rsnd_dai { |
335 | char name[RSND_DAI_NAME_SIZE]; | 359 | char name[RSND_DAI_NAME_SIZE]; |
@@ -355,7 +379,8 @@ struct rsnd_dai { | |||
355 | 379 | ||
356 | struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id); | 380 | struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id); |
357 | 381 | ||
358 | void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); | 382 | bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); |
383 | void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io); | ||
359 | int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); | 384 | int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); |
360 | 385 | ||
361 | /* | 386 | /* |
@@ -459,7 +484,8 @@ struct rsnd_kctrl_cfg { | |||
459 | unsigned int size; | 484 | unsigned int size; |
460 | u32 *val; | 485 | u32 *val; |
461 | const char * const *texts; | 486 | const char * const *texts; |
462 | void (*update)(struct rsnd_mod *mod); | 487 | void (*update)(struct rsnd_dai_stream *io, struct rsnd_mod *mod); |
488 | struct rsnd_dai_stream *io; | ||
463 | struct snd_card *card; | 489 | struct snd_card *card; |
464 | struct snd_kcontrol *kctrl; | 490 | struct snd_kcontrol *kctrl; |
465 | }; | 491 | }; |
@@ -479,22 +505,28 @@ void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg); | |||
479 | #define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg)) | 505 | #define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg)) |
480 | 506 | ||
481 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, | 507 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, |
508 | struct rsnd_dai_stream *io, | ||
482 | struct snd_soc_pcm_runtime *rtd, | 509 | struct snd_soc_pcm_runtime *rtd, |
483 | const unsigned char *name, | 510 | const unsigned char *name, |
484 | void (*update)(struct rsnd_mod *mod), | 511 | void (*update)(struct rsnd_dai_stream *io, |
512 | struct rsnd_mod *mod), | ||
485 | struct rsnd_kctrl_cfg_m *_cfg, | 513 | struct rsnd_kctrl_cfg_m *_cfg, |
486 | u32 max); | 514 | u32 max); |
487 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, | 515 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, |
516 | struct rsnd_dai_stream *io, | ||
488 | struct snd_soc_pcm_runtime *rtd, | 517 | struct snd_soc_pcm_runtime *rtd, |
489 | const unsigned char *name, | 518 | const unsigned char *name, |
490 | void (*update)(struct rsnd_mod *mod), | 519 | void (*update)(struct rsnd_dai_stream *io, |
520 | struct rsnd_mod *mod), | ||
491 | struct rsnd_kctrl_cfg_s *_cfg, | 521 | struct rsnd_kctrl_cfg_s *_cfg, |
492 | u32 max); | 522 | u32 max); |
493 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, | 523 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, |
524 | struct rsnd_dai_stream *io, | ||
494 | struct snd_soc_pcm_runtime *rtd, | 525 | struct snd_soc_pcm_runtime *rtd, |
495 | const unsigned char *name, | 526 | const unsigned char *name, |
496 | struct rsnd_kctrl_cfg_s *_cfg, | 527 | struct rsnd_kctrl_cfg_s *_cfg, |
497 | void (*update)(struct rsnd_mod *mod), | 528 | void (*update)(struct rsnd_dai_stream *io, |
529 | struct rsnd_mod *mod), | ||
498 | const char * const *texts, | 530 | const char * const *texts, |
499 | u32 max); | 531 | u32 max); |
500 | 532 | ||
@@ -511,8 +543,10 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
511 | struct rsnd_dai_stream *io, | 543 | struct rsnd_dai_stream *io, |
512 | struct snd_pcm_runtime *runtime); | 544 | struct snd_pcm_runtime *runtime); |
513 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | 545 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, |
546 | struct rsnd_dai_stream *io, | ||
514 | int use_busif); | 547 | int use_busif); |
515 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod); | 548 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, |
549 | struct rsnd_dai_stream *io); | ||
516 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod); | 550 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod); |
517 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod); | 551 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod); |
518 | 552 | ||
@@ -529,7 +563,7 @@ void rsnd_ssi_remove(struct platform_device *pdev, | |||
529 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); | 563 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); |
530 | int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); | 564 | int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); |
531 | int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); | 565 | int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); |
532 | int rsnd_ssi_use_busif(struct rsnd_mod *mod); | 566 | int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod); |
533 | 567 | ||
534 | /* | 568 | /* |
535 | * R-Car DVC | 569 | * R-Car DVC |
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c index 050b0dbcee65..8caca2e180c3 100644 --- a/sound/soc/sh/rcar/rsrc-card.c +++ b/sound/soc/sh/rcar/rsrc-card.c | |||
@@ -45,61 +45,50 @@ static const struct of_device_id rsrc_card_of_match[] = { | |||
45 | }; | 45 | }; |
46 | MODULE_DEVICE_TABLE(of, rsrc_card_of_match); | 46 | MODULE_DEVICE_TABLE(of, rsrc_card_of_match); |
47 | 47 | ||
48 | #define DAI_NAME_NUM 32 | ||
48 | struct rsrc_card_dai { | 49 | struct rsrc_card_dai { |
49 | const char *name; | ||
50 | unsigned int fmt; | 50 | unsigned int fmt; |
51 | unsigned int sysclk; | 51 | unsigned int sysclk; |
52 | struct clk *clk; | 52 | struct clk *clk; |
53 | char dai_name[DAI_NAME_NUM]; | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | #define RSRC_FB_NUM 2 /* FE/BE */ | ||
56 | #define IDX_CPU 0 | 56 | #define IDX_CPU 0 |
57 | #define IDX_CODEC 1 | 57 | #define IDX_CODEC 1 |
58 | struct rsrc_card_priv { | 58 | struct rsrc_card_priv { |
59 | struct snd_soc_card snd_card; | 59 | struct snd_soc_card snd_card; |
60 | struct rsrc_card_dai_props { | ||
61 | struct rsrc_card_dai cpu_dai; | ||
62 | struct rsrc_card_dai codec_dai; | ||
63 | } dai_props[RSRC_FB_NUM]; | ||
64 | struct snd_soc_codec_conf codec_conf; | 60 | struct snd_soc_codec_conf codec_conf; |
65 | struct snd_soc_dai_link dai_link[RSRC_FB_NUM]; | 61 | struct rsrc_card_dai *dai_props; |
62 | struct snd_soc_dai_link *dai_link; | ||
63 | int dai_num; | ||
66 | u32 convert_rate; | 64 | u32 convert_rate; |
67 | }; | 65 | }; |
68 | 66 | ||
69 | #define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev) | 67 | #define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev) |
70 | #define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i) | 68 | #define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i)) |
71 | #define rsrc_priv_to_props(priv, i) ((priv)->dai_props + i) | 69 | #define rsrc_priv_to_props(priv, i) ((priv)->dai_props + (i)) |
72 | #define rsrc_dev_to_of_data(dev) (of_match_device(rsrc_card_of_match, (dev))->data) | 70 | #define rsrc_dev_to_of_data(dev) (of_match_device(rsrc_card_of_match, (dev))->data) |
73 | 71 | ||
74 | static int rsrc_card_startup(struct snd_pcm_substream *substream) | 72 | static int rsrc_card_startup(struct snd_pcm_substream *substream) |
75 | { | 73 | { |
76 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 74 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
77 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | 75 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); |
78 | struct rsrc_card_dai_props *dai_props = | 76 | struct rsrc_card_dai *dai_props = |
79 | &priv->dai_props[rtd - rtd->card->rtd]; | 77 | rsrc_priv_to_props(priv, rtd - rtd->card->rtd); |
80 | int ret; | 78 | int ret; |
81 | 79 | ||
82 | ret = clk_prepare_enable(dai_props->cpu_dai.clk); | ||
83 | if (ret) | ||
84 | return ret; | ||
85 | |||
86 | ret = clk_prepare_enable(dai_props->codec_dai.clk); | ||
87 | if (ret) | ||
88 | clk_disable_unprepare(dai_props->cpu_dai.clk); | ||
89 | 80 | ||
90 | return ret; | 81 | return clk_prepare_enable(dai_props->clk); |
91 | } | 82 | } |
92 | 83 | ||
93 | static void rsrc_card_shutdown(struct snd_pcm_substream *substream) | 84 | static void rsrc_card_shutdown(struct snd_pcm_substream *substream) |
94 | { | 85 | { |
95 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 86 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
96 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | 87 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); |
97 | struct rsrc_card_dai_props *dai_props = | 88 | struct rsrc_card_dai *dai_props = |
98 | &priv->dai_props[rtd - rtd->card->rtd]; | 89 | rsrc_priv_to_props(priv, rtd - rtd->card->rtd); |
99 | |||
100 | clk_disable_unprepare(dai_props->cpu_dai.clk); | ||
101 | 90 | ||
102 | clk_disable_unprepare(dai_props->codec_dai.clk); | 91 | clk_disable_unprepare(dai_props->clk); |
103 | } | 92 | } |
104 | 93 | ||
105 | static struct snd_soc_ops rsrc_card_ops = { | 94 | static struct snd_soc_ops rsrc_card_ops = { |
@@ -107,21 +96,31 @@ static struct snd_soc_ops rsrc_card_ops = { | |||
107 | .shutdown = rsrc_card_shutdown, | 96 | .shutdown = rsrc_card_shutdown, |
108 | }; | 97 | }; |
109 | 98 | ||
110 | static int __rsrc_card_dai_init(struct snd_soc_dai *dai, | 99 | static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd) |
111 | struct rsrc_card_dai *set) | ||
112 | { | 100 | { |
101 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
102 | struct snd_soc_dai *dai; | ||
103 | struct snd_soc_dai_link *dai_link; | ||
104 | struct rsrc_card_dai *dai_props; | ||
105 | int num = rtd - rtd->card->rtd; | ||
113 | int ret; | 106 | int ret; |
114 | 107 | ||
115 | if (set->fmt) { | 108 | dai_link = rsrc_priv_to_link(priv, num); |
116 | ret = snd_soc_dai_set_fmt(dai, set->fmt); | 109 | dai_props = rsrc_priv_to_props(priv, num); |
110 | dai = dai_link->dynamic ? | ||
111 | rtd->cpu_dai : | ||
112 | rtd->codec_dai; | ||
113 | |||
114 | if (dai_props->fmt) { | ||
115 | ret = snd_soc_dai_set_fmt(dai, dai_props->fmt); | ||
117 | if (ret && ret != -ENOTSUPP) { | 116 | if (ret && ret != -ENOTSUPP) { |
118 | dev_err(dai->dev, "set_fmt error\n"); | 117 | dev_err(dai->dev, "set_fmt error\n"); |
119 | goto err; | 118 | goto err; |
120 | } | 119 | } |
121 | } | 120 | } |
122 | 121 | ||
123 | if (set->sysclk) { | 122 | if (dai_props->sysclk) { |
124 | ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0); | 123 | ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0); |
125 | if (ret && ret != -ENOTSUPP) { | 124 | if (ret && ret != -ENOTSUPP) { |
126 | dev_err(dai->dev, "set_sysclk error\n"); | 125 | dev_err(dai->dev, "set_sysclk error\n"); |
127 | goto err; | 126 | goto err; |
@@ -134,27 +133,6 @@ err: | |||
134 | return ret; | 133 | return ret; |
135 | } | 134 | } |
136 | 135 | ||
137 | static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd) | ||
138 | { | ||
139 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
140 | struct snd_soc_dai *codec = rtd->codec_dai; | ||
141 | struct snd_soc_dai *cpu = rtd->cpu_dai; | ||
142 | struct rsrc_card_dai_props *dai_props; | ||
143 | int num, ret; | ||
144 | |||
145 | num = rtd - rtd->card->rtd; | ||
146 | dai_props = &priv->dai_props[num]; | ||
147 | ret = __rsrc_card_dai_init(codec, &dai_props->codec_dai); | ||
148 | if (ret < 0) | ||
149 | return ret; | ||
150 | |||
151 | ret = __rsrc_card_dai_init(cpu, &dai_props->cpu_dai); | ||
152 | if (ret < 0) | ||
153 | return ret; | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, | 136 | static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, |
159 | struct snd_pcm_hw_params *params) | 137 | struct snd_pcm_hw_params *params) |
160 | { | 138 | { |
@@ -170,40 +148,47 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, | |||
170 | return 0; | 148 | return 0; |
171 | } | 149 | } |
172 | 150 | ||
173 | static int | 151 | static int rsrc_card_parse_daifmt(struct device_node *node, |
174 | rsrc_card_sub_parse_of(struct rsrc_card_priv *priv, | 152 | struct device_node *np, |
175 | struct device_node *np, | 153 | struct rsrc_card_priv *priv, |
176 | struct rsrc_card_dai *dai, | 154 | int idx, bool is_fe) |
177 | struct snd_soc_dai_link *dai_link, | ||
178 | int *args_count) | ||
179 | { | 155 | { |
180 | struct device *dev = rsrc_priv_to_dev(priv); | 156 | struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); |
181 | const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); | 157 | struct device_node *bitclkmaster = NULL; |
182 | struct of_phandle_args args; | 158 | struct device_node *framemaster = NULL; |
183 | struct device_node **p_node; | 159 | struct device_node *codec = is_fe ? NULL : np; |
184 | struct clk *clk; | 160 | unsigned int daifmt; |
185 | const char **dai_name; | ||
186 | const char **name; | ||
187 | u32 val; | ||
188 | int ret; | ||
189 | 161 | ||
190 | if (args_count) { | 162 | daifmt = snd_soc_of_parse_daifmt(node, NULL, |
191 | p_node = &dai_link->cpu_of_node; | 163 | &bitclkmaster, &framemaster); |
192 | dai_name = &dai_link->cpu_dai_name; | 164 | daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; |
193 | name = &dai_link->cpu_name; | ||
194 | } else { | ||
195 | p_node = &dai_link->codec_of_node; | ||
196 | dai_name = &dai_link->codec_dai_name; | ||
197 | name = &dai_link->codec_name; | ||
198 | } | ||
199 | 165 | ||
200 | if (!np) { | 166 | if (!bitclkmaster && !framemaster) |
201 | /* use snd-soc-dummy */ | 167 | return -EINVAL; |
202 | *p_node = NULL; | 168 | |
203 | *dai_name = "snd-soc-dummy-dai"; | 169 | if (codec == bitclkmaster) |
204 | *name = "snd-soc-dummy"; | 170 | daifmt |= (codec == framemaster) ? |
205 | return 0; | 171 | SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS; |
206 | } | 172 | else |
173 | daifmt |= (codec == framemaster) ? | ||
174 | SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; | ||
175 | |||
176 | dai_props->fmt = daifmt; | ||
177 | |||
178 | of_node_put(bitclkmaster); | ||
179 | of_node_put(framemaster); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int rsrc_card_parse_links(struct device_node *np, | ||
185 | struct rsrc_card_priv *priv, | ||
186 | int idx, bool is_fe) | ||
187 | { | ||
188 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | ||
189 | struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); | ||
190 | struct of_phandle_args args; | ||
191 | int ret; | ||
207 | 192 | ||
208 | /* | 193 | /* |
209 | * Get node via "sound-dai = <&phandle port>" | 194 | * Get node via "sound-dai = <&phandle port>" |
@@ -214,31 +199,82 @@ rsrc_card_sub_parse_of(struct rsrc_card_priv *priv, | |||
214 | if (ret) | 199 | if (ret) |
215 | return ret; | 200 | return ret; |
216 | 201 | ||
217 | *p_node = args.np; | 202 | if (is_fe) { |
203 | /* BE is dummy */ | ||
204 | dai_link->codec_of_node = NULL; | ||
205 | dai_link->codec_dai_name = "snd-soc-dummy-dai"; | ||
206 | dai_link->codec_name = "snd-soc-dummy"; | ||
207 | |||
208 | /* FE settings */ | ||
209 | dai_link->dynamic = 1; | ||
210 | dai_link->dpcm_merged_format = 1; | ||
211 | dai_link->cpu_of_node = args.np; | ||
212 | snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name); | ||
213 | |||
214 | /* set dai_name */ | ||
215 | snprintf(dai_props->dai_name, DAI_NAME_NUM, "fe.%s", | ||
216 | dai_link->cpu_dai_name); | ||
217 | |||
218 | /* | ||
219 | * In soc_bind_dai_link() will check cpu name after | ||
220 | * of_node matching if dai_link has cpu_dai_name. | ||
221 | * but, it will never match if name was created by | ||
222 | * fmt_single_name() remove cpu_dai_name if cpu_args | ||
223 | * was 0. See: | ||
224 | * fmt_single_name() | ||
225 | * fmt_multiple_name() | ||
226 | */ | ||
227 | if (!args.args_count) | ||
228 | dai_link->cpu_dai_name = NULL; | ||
229 | } else { | ||
230 | struct device *dev = rsrc_priv_to_dev(priv); | ||
231 | const struct rsrc_card_of_data *of_data; | ||
218 | 232 | ||
219 | /* Get dai->name */ | 233 | of_data = rsrc_dev_to_of_data(dev); |
220 | ret = snd_soc_of_get_dai_name(np, dai_name); | ||
221 | if (ret < 0) | ||
222 | return ret; | ||
223 | 234 | ||
224 | /* | 235 | /* FE is dummy */ |
225 | * FIXME | 236 | dai_link->cpu_of_node = NULL; |
226 | * | 237 | dai_link->cpu_dai_name = "snd-soc-dummy-dai"; |
227 | * rsrc assumes DPCM playback/capture | 238 | dai_link->cpu_name = "snd-soc-dummy"; |
228 | */ | ||
229 | dai_link->dpcm_playback = 1; | ||
230 | dai_link->dpcm_capture = 1; | ||
231 | 239 | ||
232 | if (args_count) { | 240 | /* BE settings */ |
233 | *args_count = args.args_count; | 241 | dai_link->no_pcm = 1; |
234 | dai_link->dynamic = 1; | 242 | dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup; |
235 | dai_link->dpcm_merged_format = 1; | 243 | dai_link->codec_of_node = args.np; |
236 | } else { | 244 | snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name); |
237 | dai_link->no_pcm = 1; | 245 | |
238 | priv->codec_conf.of_node = (*p_node); | 246 | /* additional name prefix */ |
239 | priv->codec_conf.name_prefix = of_data->prefix; | 247 | priv->codec_conf.of_node = dai_link->codec_of_node; |
248 | priv->codec_conf.name_prefix = of_data->prefix; | ||
249 | |||
250 | /* set dai_name */ | ||
251 | snprintf(dai_props->dai_name, DAI_NAME_NUM, "be.%s", | ||
252 | dai_link->codec_dai_name); | ||
240 | } | 253 | } |
241 | 254 | ||
255 | /* Simple Card assumes platform == cpu */ | ||
256 | dai_link->platform_of_node = dai_link->cpu_of_node; | ||
257 | dai_link->dpcm_playback = 1; | ||
258 | dai_link->dpcm_capture = 1; | ||
259 | dai_link->name = dai_props->dai_name; | ||
260 | dai_link->stream_name = dai_props->dai_name; | ||
261 | dai_link->ops = &rsrc_card_ops; | ||
262 | dai_link->init = rsrc_card_dai_init; | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static int rsrc_card_parse_clk(struct device_node *np, | ||
268 | struct rsrc_card_priv *priv, | ||
269 | int idx, bool is_fe) | ||
270 | { | ||
271 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | ||
272 | struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); | ||
273 | struct clk *clk; | ||
274 | struct device_node *of_np = is_fe ? dai_link->cpu_of_node : | ||
275 | dai_link->codec_of_node; | ||
276 | u32 val; | ||
277 | |||
242 | /* | 278 | /* |
243 | * Parse dai->sysclk come from "clocks = <&xxx>" | 279 | * Parse dai->sysclk come from "clocks = <&xxx>" |
244 | * (if system has common clock) | 280 | * (if system has common clock) |
@@ -247,173 +283,92 @@ rsrc_card_sub_parse_of(struct rsrc_card_priv *priv, | |||
247 | */ | 283 | */ |
248 | if (of_property_read_bool(np, "clocks")) { | 284 | if (of_property_read_bool(np, "clocks")) { |
249 | clk = of_clk_get(np, 0); | 285 | clk = of_clk_get(np, 0); |
250 | if (IS_ERR(clk)) { | 286 | if (IS_ERR(clk)) |
251 | ret = PTR_ERR(clk); | 287 | return PTR_ERR(clk); |
252 | return ret; | ||
253 | } | ||
254 | 288 | ||
255 | dai->sysclk = clk_get_rate(clk); | 289 | dai_props->sysclk = clk_get_rate(clk); |
256 | dai->clk = clk; | 290 | dai_props->clk = clk; |
257 | } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { | 291 | } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { |
258 | dai->sysclk = val; | 292 | dai_props->sysclk = val; |
259 | } else { | 293 | } else { |
260 | clk = of_clk_get(args.np, 0); | 294 | clk = of_clk_get(of_np, 0); |
261 | if (!IS_ERR(clk)) | 295 | if (!IS_ERR(clk)) |
262 | dai->sysclk = clk_get_rate(clk); | 296 | dai_props->sysclk = clk_get_rate(clk); |
263 | } | 297 | } |
264 | 298 | ||
265 | return 0; | 299 | return 0; |
266 | } | 300 | } |
267 | 301 | ||
268 | static int rsrc_card_parse_daifmt(struct device_node *node, | ||
269 | struct rsrc_card_priv *priv, | ||
270 | struct device_node *codec, | ||
271 | int idx) | ||
272 | { | ||
273 | struct device_node *bitclkmaster = NULL; | ||
274 | struct device_node *framemaster = NULL; | ||
275 | struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx); | ||
276 | struct rsrc_card_dai *cpu_dai = &dai_props->cpu_dai; | ||
277 | struct rsrc_card_dai *codec_dai = &dai_props->codec_dai; | ||
278 | unsigned int daifmt; | ||
279 | |||
280 | daifmt = snd_soc_of_parse_daifmt(node, NULL, | ||
281 | &bitclkmaster, &framemaster); | ||
282 | daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; | ||
283 | |||
284 | if (!bitclkmaster && !framemaster) | ||
285 | return -EINVAL; | ||
286 | |||
287 | if (codec == bitclkmaster) | ||
288 | daifmt |= (codec == framemaster) ? | ||
289 | SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS; | ||
290 | else | ||
291 | daifmt |= (codec == framemaster) ? | ||
292 | SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; | ||
293 | |||
294 | cpu_dai->fmt = daifmt; | ||
295 | codec_dai->fmt = daifmt; | ||
296 | |||
297 | of_node_put(bitclkmaster); | ||
298 | of_node_put(framemaster); | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static int rsrc_card_dai_link_of(struct device_node *node, | 302 | static int rsrc_card_dai_link_of(struct device_node *node, |
303 | struct device_node *np, | ||
304 | struct rsrc_card_priv *priv, | 304 | struct rsrc_card_priv *priv, |
305 | int idx) | 305 | int idx) |
306 | { | 306 | { |
307 | struct device *dev = rsrc_priv_to_dev(priv); | 307 | struct device *dev = rsrc_priv_to_dev(priv); |
308 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | 308 | struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); |
309 | struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx); | 309 | bool is_fe = false; |
310 | struct device_node *cpu = NULL; | 310 | int ret; |
311 | struct device_node *codec = NULL; | ||
312 | char *name; | ||
313 | char prop[128]; | ||
314 | int ret, cpu_args; | ||
315 | |||
316 | cpu = of_get_child_by_name(node, "cpu"); | ||
317 | codec = of_get_child_by_name(node, "codec"); | ||
318 | |||
319 | if (!cpu || !codec) { | ||
320 | ret = -EINVAL; | ||
321 | dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); | ||
322 | goto dai_link_of_err; | ||
323 | } | ||
324 | 311 | ||
325 | ret = rsrc_card_parse_daifmt(node, priv, codec, idx); | 312 | if (0 == strcmp(np->name, "cpu")) |
326 | if (ret < 0) | 313 | is_fe = true; |
327 | goto dai_link_of_err; | ||
328 | 314 | ||
329 | ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CPU) ? cpu : NULL, | 315 | ret = rsrc_card_parse_daifmt(node, np, priv, idx, is_fe); |
330 | &dai_props->cpu_dai, | ||
331 | dai_link, | ||
332 | &cpu_args); | ||
333 | if (ret < 0) | 316 | if (ret < 0) |
334 | goto dai_link_of_err; | 317 | return ret; |
335 | 318 | ||
336 | ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CODEC) ? codec : NULL, | 319 | ret = rsrc_card_parse_links(np, priv, idx, is_fe); |
337 | &dai_props->codec_dai, | ||
338 | dai_link, | ||
339 | NULL); | ||
340 | if (ret < 0) | 320 | if (ret < 0) |
341 | goto dai_link_of_err; | 321 | return ret; |
342 | |||
343 | if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { | ||
344 | ret = -EINVAL; | ||
345 | goto dai_link_of_err; | ||
346 | } | ||
347 | |||
348 | /* Simple Card assumes platform == cpu */ | ||
349 | dai_link->platform_of_node = dai_link->cpu_of_node; | ||
350 | |||
351 | /* DAI link name is created from CPU/CODEC dai name */ | ||
352 | name = devm_kzalloc(dev, | ||
353 | strlen(dai_link->cpu_dai_name) + | ||
354 | strlen(dai_link->codec_dai_name) + 2, | ||
355 | GFP_KERNEL); | ||
356 | if (!name) { | ||
357 | ret = -ENOMEM; | ||
358 | goto dai_link_of_err; | ||
359 | } | ||
360 | |||
361 | sprintf(name, "%s-%s", dai_link->cpu_dai_name, | ||
362 | dai_link->codec_dai_name); | ||
363 | dai_link->name = dai_link->stream_name = name; | ||
364 | dai_link->ops = &rsrc_card_ops; | ||
365 | dai_link->init = rsrc_card_dai_init; | ||
366 | |||
367 | if (idx == IDX_CODEC) | ||
368 | dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup; | ||
369 | |||
370 | dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); | ||
371 | dev_dbg(dev, "\tcpu : %s / %04x / %d\n", | ||
372 | dai_link->cpu_dai_name, | ||
373 | dai_props->cpu_dai.fmt, | ||
374 | dai_props->cpu_dai.sysclk); | ||
375 | dev_dbg(dev, "\tcodec : %s / %04x / %d\n", | ||
376 | dai_link->codec_dai_name, | ||
377 | dai_props->codec_dai.fmt, | ||
378 | dai_props->codec_dai.sysclk); | ||
379 | 322 | ||
380 | /* | 323 | ret = rsrc_card_parse_clk(np, priv, idx, is_fe); |
381 | * In soc_bind_dai_link() will check cpu name after | 324 | if (ret < 0) |
382 | * of_node matching if dai_link has cpu_dai_name. | 325 | return ret; |
383 | * but, it will never match if name was created by | ||
384 | * fmt_single_name() remove cpu_dai_name if cpu_args | ||
385 | * was 0. See: | ||
386 | * fmt_single_name() | ||
387 | * fmt_multiple_name() | ||
388 | */ | ||
389 | if (!cpu_args) | ||
390 | dai_link->cpu_dai_name = NULL; | ||
391 | 326 | ||
392 | dai_link_of_err: | 327 | dev_dbg(dev, "\t%s / %04x / %d\n", |
393 | of_node_put(cpu); | 328 | dai_props->dai_name, |
394 | of_node_put(codec); | 329 | dai_props->fmt, |
330 | dai_props->sysclk); | ||
395 | 331 | ||
396 | return ret; | 332 | return ret; |
397 | } | 333 | } |
398 | 334 | ||
399 | static int rsrc_card_parse_of(struct device_node *node, | 335 | static int rsrc_card_parse_of(struct device_node *node, |
400 | struct rsrc_card_priv *priv) | 336 | struct rsrc_card_priv *priv, |
337 | struct device *dev) | ||
401 | { | 338 | { |
402 | struct device *dev = rsrc_priv_to_dev(priv); | ||
403 | const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); | 339 | const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); |
340 | struct rsrc_card_dai *props; | ||
341 | struct snd_soc_dai_link *links; | ||
342 | struct device_node *np; | ||
404 | int ret; | 343 | int ret; |
405 | int i; | 344 | int i, num; |
406 | 345 | ||
407 | if (!node) | 346 | if (!node) |
408 | return -EINVAL; | 347 | return -EINVAL; |
409 | 348 | ||
410 | /* Parse the card name from DT */ | 349 | num = of_get_child_count(node); |
411 | snd_soc_of_parse_card_name(&priv->snd_card, "card-name"); | 350 | props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL); |
351 | links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL); | ||
352 | if (!props || !links) | ||
353 | return -ENOMEM; | ||
354 | |||
355 | priv->dai_props = props; | ||
356 | priv->dai_link = links; | ||
357 | priv->dai_num = num; | ||
412 | 358 | ||
413 | /* DAPM routes */ | 359 | /* Init snd_soc_card */ |
360 | priv->snd_card.owner = THIS_MODULE; | ||
361 | priv->snd_card.dev = dev; | ||
362 | priv->snd_card.dai_link = priv->dai_link; | ||
363 | priv->snd_card.num_links = num; | ||
364 | priv->snd_card.codec_conf = &priv->codec_conf; | ||
365 | priv->snd_card.num_configs = 1; | ||
414 | priv->snd_card.of_dapm_routes = of_data->routes; | 366 | priv->snd_card.of_dapm_routes = of_data->routes; |
415 | priv->snd_card.num_of_dapm_routes = of_data->num_routes; | 367 | priv->snd_card.num_of_dapm_routes = of_data->num_routes; |
416 | 368 | ||
369 | /* Parse the card name from DT */ | ||
370 | snd_soc_of_parse_card_name(&priv->snd_card, "card-name"); | ||
371 | |||
417 | /* sampling rate convert */ | 372 | /* sampling rate convert */ |
418 | of_property_read_u32(node, "convert-rate", &priv->convert_rate); | 373 | of_property_read_u32(node, "convert-rate", &priv->convert_rate); |
419 | 374 | ||
@@ -421,11 +376,12 @@ static int rsrc_card_parse_of(struct device_node *node, | |||
421 | priv->snd_card.name ? priv->snd_card.name : "", | 376 | priv->snd_card.name ? priv->snd_card.name : "", |
422 | priv->convert_rate); | 377 | priv->convert_rate); |
423 | 378 | ||
424 | /* FE/BE */ | 379 | i = 0; |
425 | for (i = 0; i < RSRC_FB_NUM; i++) { | 380 | for_each_child_of_node(node, np) { |
426 | ret = rsrc_card_dai_link_of(node, priv, i); | 381 | ret = rsrc_card_dai_link_of(node, np, priv, i); |
427 | if (ret < 0) | 382 | if (ret < 0) |
428 | return ret; | 383 | return ret; |
384 | i++; | ||
429 | } | 385 | } |
430 | 386 | ||
431 | if (!priv->snd_card.name) | 387 | if (!priv->snd_card.name) |
@@ -452,7 +408,6 @@ static int rsrc_card_unref(struct snd_soc_card *card) | |||
452 | static int rsrc_card_probe(struct platform_device *pdev) | 408 | static int rsrc_card_probe(struct platform_device *pdev) |
453 | { | 409 | { |
454 | struct rsrc_card_priv *priv; | 410 | struct rsrc_card_priv *priv; |
455 | struct snd_soc_dai_link *dai_link; | ||
456 | struct device_node *np = pdev->dev.of_node; | 411 | struct device_node *np = pdev->dev.of_node; |
457 | struct device *dev = &pdev->dev; | 412 | struct device *dev = &pdev->dev; |
458 | int ret; | 413 | int ret; |
@@ -462,16 +417,7 @@ static int rsrc_card_probe(struct platform_device *pdev) | |||
462 | if (!priv) | 417 | if (!priv) |
463 | return -ENOMEM; | 418 | return -ENOMEM; |
464 | 419 | ||
465 | /* Init snd_soc_card */ | 420 | ret = rsrc_card_parse_of(np, priv, dev); |
466 | priv->snd_card.owner = THIS_MODULE; | ||
467 | priv->snd_card.dev = dev; | ||
468 | dai_link = priv->dai_link; | ||
469 | priv->snd_card.dai_link = dai_link; | ||
470 | priv->snd_card.num_links = RSRC_FB_NUM; | ||
471 | priv->snd_card.codec_conf = &priv->codec_conf; | ||
472 | priv->snd_card.num_configs = 1; | ||
473 | |||
474 | ret = rsrc_card_parse_of(np, priv); | ||
475 | if (ret < 0) { | 421 | if (ret < 0) { |
476 | if (ret != -EPROBE_DEFER) | 422 | if (ret != -EPROBE_DEFER) |
477 | dev_err(dev, "parse error %d\n", ret); | 423 | dev_err(dev, "parse error %d\n", ret); |
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index fbe9166e26d1..c61c17180142 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -117,10 +117,10 @@ struct rsnd_src { | |||
117 | /* | 117 | /* |
118 | * Gen1/Gen2 common functions | 118 | * Gen1/Gen2 common functions |
119 | */ | 119 | */ |
120 | static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod) | 120 | static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io, |
121 | struct rsnd_mod *mod) | ||
121 | { | 122 | { |
122 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 123 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
123 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
124 | int is_play = rsnd_io_is_play(io); | 124 | int is_play = rsnd_io_is_play(io); |
125 | 125 | ||
126 | return rsnd_dma_request_channel(rsnd_src_of_node(priv), | 126 | return rsnd_dma_request_channel(rsnd_src_of_node(priv), |
@@ -129,9 +129,9 @@ static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod) | |||
129 | } | 129 | } |
130 | 130 | ||
131 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | 131 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, |
132 | struct rsnd_dai_stream *io, | ||
132 | int use_busif) | 133 | int use_busif) |
133 | { | 134 | { |
134 | struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); | ||
135 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | 135 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); |
136 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 136 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
137 | int ssi_id = rsnd_mod_id(ssi_mod); | 137 | int ssi_id = rsnd_mod_id(ssi_mod); |
@@ -174,7 +174,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | |||
174 | u32 mask = ~0; | 174 | u32 mask = ~0; |
175 | 175 | ||
176 | rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR, | 176 | rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR, |
177 | rsnd_get_adinr(ssi_mod)); | 177 | rsnd_get_adinr(ssi_mod, io)); |
178 | rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1); | 178 | rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1); |
179 | rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1); | 179 | rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1); |
180 | 180 | ||
@@ -196,7 +196,8 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | |||
196 | return 0; | 196 | return 0; |
197 | } | 197 | } |
198 | 198 | ||
199 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod) | 199 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, |
200 | struct rsnd_dai_stream *io) | ||
200 | { | 201 | { |
201 | /* | 202 | /* |
202 | * DMA settings for SSIU | 203 | * DMA settings for SSIU |
@@ -235,10 +236,9 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod) | |||
235 | return 0; | 236 | return 0; |
236 | } | 237 | } |
237 | 238 | ||
238 | static u32 rsnd_src_convert_rate(struct rsnd_src *src) | 239 | static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io, |
240 | struct rsnd_src *src) | ||
239 | { | 241 | { |
240 | struct rsnd_mod *mod = &src->mod; | ||
241 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
242 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 242 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
243 | u32 convert_rate; | 243 | u32 convert_rate; |
244 | 244 | ||
@@ -274,7 +274,7 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
274 | * return convert rate if SRC is used, | 274 | * return convert rate if SRC is used, |
275 | * otherwise, return runtime->rate as usual | 275 | * otherwise, return runtime->rate as usual |
276 | */ | 276 | */ |
277 | rate = rsnd_src_convert_rate(src); | 277 | rate = rsnd_src_convert_rate(io, src); |
278 | } | 278 | } |
279 | 279 | ||
280 | if (!rate) | 280 | if (!rate) |
@@ -283,12 +283,12 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
283 | return rate; | 283 | return rate; |
284 | } | 284 | } |
285 | 285 | ||
286 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod) | 286 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, |
287 | struct rsnd_dai_stream *io) | ||
287 | { | 288 | { |
288 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
289 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 289 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
290 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 290 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
291 | u32 convert_rate = rsnd_src_convert_rate(src); | 291 | u32 convert_rate = rsnd_src_convert_rate(io, src); |
292 | u32 fsrate = 0; | 292 | u32 fsrate = 0; |
293 | 293 | ||
294 | if (convert_rate) | 294 | if (convert_rate) |
@@ -299,7 +299,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod) | |||
299 | rsnd_mod_write(mod, SRC_SWRSR, 1); | 299 | rsnd_mod_write(mod, SRC_SWRSR, 1); |
300 | 300 | ||
301 | /* Set channel number and output bit length */ | 301 | /* Set channel number and output bit length */ |
302 | rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod)); | 302 | rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod, io)); |
303 | 303 | ||
304 | /* Enable the initial value of IFS */ | 304 | /* Enable the initial value of IFS */ |
305 | if (fsrate) { | 305 | if (fsrate) { |
@@ -316,6 +316,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod) | |||
316 | } | 316 | } |
317 | 317 | ||
318 | static int rsnd_src_hw_params(struct rsnd_mod *mod, | 318 | static int rsnd_src_hw_params(struct rsnd_mod *mod, |
319 | struct rsnd_dai_stream *io, | ||
319 | struct snd_pcm_substream *substream, | 320 | struct snd_pcm_substream *substream, |
320 | struct snd_pcm_hw_params *fe_params) | 321 | struct snd_pcm_hw_params *fe_params) |
321 | { | 322 | { |
@@ -372,6 +373,7 @@ static int rsnd_src_init(struct rsnd_mod *mod, | |||
372 | } | 373 | } |
373 | 374 | ||
374 | static int rsnd_src_quit(struct rsnd_mod *mod, | 375 | static int rsnd_src_quit(struct rsnd_mod *mod, |
376 | struct rsnd_dai_stream *io, | ||
375 | struct rsnd_priv *priv) | 377 | struct rsnd_priv *priv) |
376 | { | 378 | { |
377 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 379 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
@@ -411,9 +413,9 @@ static int rsnd_src_stop(struct rsnd_mod *mod) | |||
411 | /* | 413 | /* |
412 | * Gen1 functions | 414 | * Gen1 functions |
413 | */ | 415 | */ |
414 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod) | 416 | static int rsnd_src_set_route_gen1(struct rsnd_dai_stream *io, |
417 | struct rsnd_mod *mod) | ||
415 | { | 418 | { |
416 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
417 | struct src_route_config { | 419 | struct src_route_config { |
418 | u32 mask; | 420 | u32 mask; |
419 | int shift; | 421 | int shift; |
@@ -448,13 +450,13 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod) | |||
448 | return 0; | 450 | return 0; |
449 | } | 451 | } |
450 | 452 | ||
451 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod) | 453 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_dai_stream *io, |
454 | struct rsnd_mod *mod) | ||
452 | { | 455 | { |
453 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
454 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 456 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
455 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 457 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
456 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 458 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
457 | u32 convert_rate = rsnd_src_convert_rate(src); | 459 | u32 convert_rate = rsnd_src_convert_rate(io, src); |
458 | u32 mask; | 460 | u32 mask; |
459 | u32 val; | 461 | u32 val; |
460 | int shift; | 462 | int shift; |
@@ -506,12 +508,13 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod) | |||
506 | return 0; | 508 | return 0; |
507 | } | 509 | } |
508 | 510 | ||
509 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod) | 511 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, |
512 | struct rsnd_dai_stream *io) | ||
510 | { | 513 | { |
511 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 514 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
512 | int ret; | 515 | int ret; |
513 | 516 | ||
514 | ret = rsnd_src_set_convert_rate(mod); | 517 | ret = rsnd_src_set_convert_rate(mod, io); |
515 | if (ret < 0) | 518 | if (ret < 0) |
516 | return ret; | 519 | return ret; |
517 | 520 | ||
@@ -523,7 +526,7 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod) | |||
523 | rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98); | 526 | rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98); |
524 | 527 | ||
525 | /* Gen1/Gen2 are not compatible */ | 528 | /* Gen1/Gen2 are not compatible */ |
526 | if (rsnd_src_convert_rate(src)) | 529 | if (rsnd_src_convert_rate(io, src)) |
527 | rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); | 530 | rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); |
528 | 531 | ||
529 | /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ | 532 | /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ |
@@ -532,6 +535,7 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod) | |||
532 | } | 535 | } |
533 | 536 | ||
534 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, | 537 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, |
538 | struct rsnd_dai_stream *io, | ||
535 | struct rsnd_priv *priv) | 539 | struct rsnd_priv *priv) |
536 | { | 540 | { |
537 | int ret; | 541 | int ret; |
@@ -540,15 +544,15 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod, | |||
540 | if (ret < 0) | 544 | if (ret < 0) |
541 | return ret; | 545 | return ret; |
542 | 546 | ||
543 | ret = rsnd_src_set_route_gen1(mod); | 547 | ret = rsnd_src_set_route_gen1(io, mod); |
544 | if (ret < 0) | 548 | if (ret < 0) |
545 | return ret; | 549 | return ret; |
546 | 550 | ||
547 | ret = rsnd_src_set_convert_rate_gen1(mod); | 551 | ret = rsnd_src_set_convert_rate_gen1(mod, io); |
548 | if (ret < 0) | 552 | if (ret < 0) |
549 | return ret; | 553 | return ret; |
550 | 554 | ||
551 | ret = rsnd_src_set_convert_timing_gen1(mod); | 555 | ret = rsnd_src_set_convert_timing_gen1(io, mod); |
552 | if (ret < 0) | 556 | if (ret < 0) |
553 | return ret; | 557 | return ret; |
554 | 558 | ||
@@ -556,6 +560,7 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod, | |||
556 | } | 560 | } |
557 | 561 | ||
558 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, | 562 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, |
563 | struct rsnd_dai_stream *io, | ||
559 | struct rsnd_priv *priv) | 564 | struct rsnd_priv *priv) |
560 | { | 565 | { |
561 | int id = rsnd_mod_id(mod); | 566 | int id = rsnd_mod_id(mod); |
@@ -566,6 +571,7 @@ static int rsnd_src_start_gen1(struct rsnd_mod *mod, | |||
566 | } | 571 | } |
567 | 572 | ||
568 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, | 573 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, |
574 | struct rsnd_dai_stream *io, | ||
569 | struct rsnd_priv *priv) | 575 | struct rsnd_priv *priv) |
570 | { | 576 | { |
571 | int id = rsnd_mod_id(mod); | 577 | int id = rsnd_mod_id(mod); |
@@ -643,9 +649,9 @@ static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod) | |||
643 | return ret; | 649 | return ret; |
644 | } | 650 | } |
645 | 651 | ||
646 | static int _rsnd_src_start_gen2(struct rsnd_mod *mod) | 652 | static int _rsnd_src_start_gen2(struct rsnd_mod *mod, |
653 | struct rsnd_dai_stream *io) | ||
647 | { | 654 | { |
648 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
649 | u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; | 655 | u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; |
650 | 656 | ||
651 | rsnd_mod_write(mod, SRC_CTRL, val); | 657 | rsnd_mod_write(mod, SRC_CTRL, val); |
@@ -670,15 +676,15 @@ static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) | |||
670 | return rsnd_src_stop(mod); | 676 | return rsnd_src_stop(mod); |
671 | } | 677 | } |
672 | 678 | ||
673 | static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) | 679 | static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, |
680 | struct rsnd_dai_stream *io) | ||
674 | { | 681 | { |
675 | struct rsnd_mod *mod = data; | ||
676 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 682 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
677 | 683 | ||
678 | spin_lock(&priv->lock); | 684 | spin_lock(&priv->lock); |
679 | 685 | ||
680 | /* ignore all cases if not working */ | 686 | /* ignore all cases if not working */ |
681 | if (!rsnd_mod_is_working(mod)) | 687 | if (!rsnd_io_is_working(io)) |
682 | goto rsnd_src_interrupt_gen2_out; | 688 | goto rsnd_src_interrupt_gen2_out; |
683 | 689 | ||
684 | if (rsnd_src_error_record_gen2(mod)) { | 690 | if (rsnd_src_error_record_gen2(mod)) { |
@@ -691,24 +697,32 @@ static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) | |||
691 | 697 | ||
692 | _rsnd_src_stop_gen2(mod); | 698 | _rsnd_src_stop_gen2(mod); |
693 | if (src->err < 1024) | 699 | if (src->err < 1024) |
694 | _rsnd_src_start_gen2(mod); | 700 | _rsnd_src_start_gen2(mod, io); |
695 | else | 701 | else |
696 | dev_warn(dev, "no more SRC restart\n"); | 702 | dev_warn(dev, "no more SRC restart\n"); |
697 | } | 703 | } |
704 | |||
698 | rsnd_src_interrupt_gen2_out: | 705 | rsnd_src_interrupt_gen2_out: |
699 | spin_unlock(&priv->lock); | 706 | spin_unlock(&priv->lock); |
707 | } | ||
708 | |||
709 | static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) | ||
710 | { | ||
711 | struct rsnd_mod *mod = data; | ||
712 | |||
713 | rsnd_mod_interrupt(mod, __rsnd_src_interrupt_gen2); | ||
700 | 714 | ||
701 | return IRQ_HANDLED; | 715 | return IRQ_HANDLED; |
702 | } | 716 | } |
703 | 717 | ||
704 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod) | 718 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, |
719 | struct rsnd_dai_stream *io) | ||
705 | { | 720 | { |
706 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 721 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
707 | struct device *dev = rsnd_priv_to_dev(priv); | 722 | struct device *dev = rsnd_priv_to_dev(priv); |
708 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
709 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 723 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
710 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 724 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
711 | u32 convert_rate = rsnd_src_convert_rate(src); | 725 | u32 convert_rate = rsnd_src_convert_rate(io, src); |
712 | u32 cr, route; | 726 | u32 cr, route; |
713 | uint ratio; | 727 | uint ratio; |
714 | int ret; | 728 | int ret; |
@@ -726,7 +740,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod) | |||
726 | return -EINVAL; | 740 | return -EINVAL; |
727 | } | 741 | } |
728 | 742 | ||
729 | ret = rsnd_src_set_convert_rate(mod); | 743 | ret = rsnd_src_set_convert_rate(mod, io); |
730 | if (ret < 0) | 744 | if (ret < 0) |
731 | return ret; | 745 | return ret; |
732 | 746 | ||
@@ -762,12 +776,12 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod) | |||
762 | return 0; | 776 | return 0; |
763 | } | 777 | } |
764 | 778 | ||
765 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod) | 779 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_dai_stream *io, |
780 | struct rsnd_mod *mod) | ||
766 | { | 781 | { |
767 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
768 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 782 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
769 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 783 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
770 | u32 convert_rate = rsnd_src_convert_rate(src); | 784 | u32 convert_rate = rsnd_src_convert_rate(io, src); |
771 | int ret; | 785 | int ret; |
772 | 786 | ||
773 | if (convert_rate) | 787 | if (convert_rate) |
@@ -781,6 +795,7 @@ static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod) | |||
781 | } | 795 | } |
782 | 796 | ||
783 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | 797 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, |
798 | struct rsnd_dai_stream *io, | ||
784 | struct rsnd_priv *priv) | 799 | struct rsnd_priv *priv) |
785 | { | 800 | { |
786 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 801 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
@@ -802,7 +817,7 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | |||
802 | return ret; | 817 | return ret; |
803 | } | 818 | } |
804 | 819 | ||
805 | ret = rsnd_dma_init(priv, | 820 | ret = rsnd_dma_init(io, |
806 | rsnd_mod_to_dma(mod), | 821 | rsnd_mod_to_dma(mod), |
807 | src->info->dma_id); | 822 | src->info->dma_id); |
808 | 823 | ||
@@ -810,14 +825,16 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | |||
810 | } | 825 | } |
811 | 826 | ||
812 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, | 827 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, |
828 | struct rsnd_dai_stream *io, | ||
813 | struct rsnd_priv *priv) | 829 | struct rsnd_priv *priv) |
814 | { | 830 | { |
815 | rsnd_dma_quit(rsnd_mod_to_dma(mod)); | 831 | rsnd_dma_quit(io, rsnd_mod_to_dma(mod)); |
816 | 832 | ||
817 | return 0; | 833 | return 0; |
818 | } | 834 | } |
819 | 835 | ||
820 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, | 836 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, |
837 | struct rsnd_dai_stream *io, | ||
821 | struct rsnd_priv *priv) | 838 | struct rsnd_priv *priv) |
822 | { | 839 | { |
823 | int ret; | 840 | int ret; |
@@ -826,11 +843,11 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod, | |||
826 | if (ret < 0) | 843 | if (ret < 0) |
827 | return ret; | 844 | return ret; |
828 | 845 | ||
829 | ret = rsnd_src_set_convert_rate_gen2(mod); | 846 | ret = rsnd_src_set_convert_rate_gen2(mod, io); |
830 | if (ret < 0) | 847 | if (ret < 0) |
831 | return ret; | 848 | return ret; |
832 | 849 | ||
833 | ret = rsnd_src_set_convert_timing_gen2(mod); | 850 | ret = rsnd_src_set_convert_timing_gen2(io, mod); |
834 | if (ret < 0) | 851 | if (ret < 0) |
835 | return ret; | 852 | return ret; |
836 | 853 | ||
@@ -838,31 +855,33 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod, | |||
838 | } | 855 | } |
839 | 856 | ||
840 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, | 857 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, |
858 | struct rsnd_dai_stream *io, | ||
841 | struct rsnd_priv *priv) | 859 | struct rsnd_priv *priv) |
842 | { | 860 | { |
843 | rsnd_dma_start(rsnd_mod_to_dma(mod)); | 861 | rsnd_dma_start(io, rsnd_mod_to_dma(mod)); |
844 | 862 | ||
845 | return _rsnd_src_start_gen2(mod); | 863 | return _rsnd_src_start_gen2(mod, io); |
846 | } | 864 | } |
847 | 865 | ||
848 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, | 866 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, |
867 | struct rsnd_dai_stream *io, | ||
849 | struct rsnd_priv *priv) | 868 | struct rsnd_priv *priv) |
850 | { | 869 | { |
851 | int ret; | 870 | int ret; |
852 | 871 | ||
853 | ret = _rsnd_src_stop_gen2(mod); | 872 | ret = _rsnd_src_stop_gen2(mod); |
854 | 873 | ||
855 | rsnd_dma_stop(rsnd_mod_to_dma(mod)); | 874 | rsnd_dma_stop(io, rsnd_mod_to_dma(mod)); |
856 | 875 | ||
857 | return ret; | 876 | return ret; |
858 | } | 877 | } |
859 | 878 | ||
860 | static void rsnd_src_reconvert_update(struct rsnd_mod *mod) | 879 | static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io, |
880 | struct rsnd_mod *mod) | ||
861 | { | 881 | { |
862 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
863 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 882 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
864 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 883 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
865 | u32 convert_rate = rsnd_src_convert_rate(src); | 884 | u32 convert_rate = rsnd_src_convert_rate(io, src); |
866 | u32 fsrate; | 885 | u32 fsrate; |
867 | 886 | ||
868 | if (!runtime) | 887 | if (!runtime) |
@@ -878,10 +897,10 @@ static void rsnd_src_reconvert_update(struct rsnd_mod *mod) | |||
878 | } | 897 | } |
879 | 898 | ||
880 | static int rsnd_src_pcm_new(struct rsnd_mod *mod, | 899 | static int rsnd_src_pcm_new(struct rsnd_mod *mod, |
900 | struct rsnd_dai_stream *io, | ||
881 | struct snd_soc_pcm_runtime *rtd) | 901 | struct snd_soc_pcm_runtime *rtd) |
882 | { | 902 | { |
883 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 903 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
884 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
885 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | 904 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); |
886 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 905 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
887 | int ret; | 906 | int ret; |
@@ -912,7 +931,7 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod, | |||
912 | /* | 931 | /* |
913 | * enable sync convert | 932 | * enable sync convert |
914 | */ | 933 | */ |
915 | ret = rsnd_kctrl_new_s(mod, rtd, | 934 | ret = rsnd_kctrl_new_s(mod, io, rtd, |
916 | rsnd_io_is_play(io) ? | 935 | rsnd_io_is_play(io) ? |
917 | "SRC Out Rate Switch" : | 936 | "SRC Out Rate Switch" : |
918 | "SRC In Rate Switch", | 937 | "SRC In Rate Switch", |
@@ -921,7 +940,7 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod, | |||
921 | if (ret < 0) | 940 | if (ret < 0) |
922 | return ret; | 941 | return ret; |
923 | 942 | ||
924 | ret = rsnd_kctrl_new_s(mod, rtd, | 943 | ret = rsnd_kctrl_new_s(mod, io, rtd, |
925 | rsnd_io_is_play(io) ? | 944 | rsnd_io_is_play(io) ? |
926 | "SRC Out Rate" : | 945 | "SRC Out Rate" : |
927 | "SRC In Rate", | 946 | "SRC In Rate", |
@@ -1046,7 +1065,7 @@ int rsnd_src_probe(struct platform_device *pdev, | |||
1046 | 1065 | ||
1047 | src->info = &info->src_info[i]; | 1066 | src->info = &info->src_info[i]; |
1048 | 1067 | ||
1049 | ret = rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i); | 1068 | ret = rsnd_mod_init(priv, &src->mod, ops, clk, RSND_MOD_SRC, i); |
1050 | if (ret) | 1069 | if (ret) |
1051 | return ret; | 1070 | return ret; |
1052 | } | 1071 | } |
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 50fa3928a003..2fbe59f7f9b5 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -87,10 +87,9 @@ struct rsnd_ssi { | |||
87 | #define rsnd_ssi_of_node(priv) \ | 87 | #define rsnd_ssi_of_node(priv) \ |
88 | of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") | 88 | of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") |
89 | 89 | ||
90 | int rsnd_ssi_use_busif(struct rsnd_mod *mod) | 90 | int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod) |
91 | { | 91 | { |
92 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 92 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
93 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
94 | int use_busif = 0; | 93 | int use_busif = 0; |
95 | 94 | ||
96 | if (!rsnd_ssi_is_dma_mode(mod)) | 95 | if (!rsnd_ssi_is_dma_mode(mod)) |
@@ -199,15 +198,17 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | |||
199 | } | 198 | } |
200 | } | 199 | } |
201 | 200 | ||
202 | cr_mode = rsnd_ssi_is_dma_mode(&ssi->mod) ? | 201 | if (rsnd_ssi_is_dma_mode(&ssi->mod)) { |
203 | DMEN : /* DMA : enable DMA */ | 202 | cr_mode = UIEN | OIEN | /* over/under run */ |
204 | DIEN; /* PIO : enable Data interrupt */ | 203 | DMEN; /* DMA : enable DMA */ |
205 | 204 | } else { | |
205 | cr_mode = DIEN; /* PIO : enable Data interrupt */ | ||
206 | } | ||
206 | 207 | ||
207 | cr = ssi->cr_own | | 208 | cr = ssi->cr_own | |
208 | ssi->cr_clk | | 209 | ssi->cr_clk | |
209 | cr_mode | | 210 | cr_mode | |
210 | UIEN | OIEN | EN; | 211 | EN; |
211 | 212 | ||
212 | rsnd_mod_write(&ssi->mod, SSICR, cr); | 213 | rsnd_mod_write(&ssi->mod, SSICR, cr); |
213 | 214 | ||
@@ -224,10 +225,9 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | |||
224 | rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); | 225 | rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); |
225 | } | 226 | } |
226 | 227 | ||
227 | static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi) | 228 | static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi) |
228 | { | 229 | { |
229 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); | 230 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); |
230 | struct rsnd_dai_stream *io = rsnd_mod_to_io(&ssi->mod); | ||
231 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | 231 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); |
232 | struct device *dev = rsnd_priv_to_dev(priv); | 232 | struct device *dev = rsnd_priv_to_dev(priv); |
233 | u32 cr; | 233 | u32 cr; |
@@ -261,7 +261,7 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi) | |||
261 | struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); | 261 | struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); |
262 | 262 | ||
263 | if (ssi_parent) | 263 | if (ssi_parent) |
264 | rsnd_ssi_hw_stop(ssi_parent); | 264 | rsnd_ssi_hw_stop(io, ssi_parent); |
265 | else | 265 | else |
266 | rsnd_ssi_master_clk_stop(ssi); | 266 | rsnd_ssi_master_clk_stop(ssi); |
267 | } | 267 | } |
@@ -279,10 +279,10 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi) | |||
279 | * SSI mod common functions | 279 | * SSI mod common functions |
280 | */ | 280 | */ |
281 | static int rsnd_ssi_init(struct rsnd_mod *mod, | 281 | static int rsnd_ssi_init(struct rsnd_mod *mod, |
282 | struct rsnd_dai_stream *io, | ||
282 | struct rsnd_priv *priv) | 283 | struct rsnd_priv *priv) |
283 | { | 284 | { |
284 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 285 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
285 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
286 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | 286 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); |
287 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 287 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
288 | u32 cr; | 288 | u32 cr; |
@@ -330,6 +330,7 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, | |||
330 | } | 330 | } |
331 | 331 | ||
332 | static int rsnd_ssi_quit(struct rsnd_mod *mod, | 332 | static int rsnd_ssi_quit(struct rsnd_mod *mod, |
333 | struct rsnd_dai_stream *io, | ||
333 | struct rsnd_priv *priv) | 334 | struct rsnd_priv *priv) |
334 | { | 335 | { |
335 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 336 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
@@ -346,6 +347,7 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod, | |||
346 | } | 347 | } |
347 | 348 | ||
348 | static int rsnd_ssi_hw_params(struct rsnd_mod *mod, | 349 | static int rsnd_ssi_hw_params(struct rsnd_mod *mod, |
350 | struct rsnd_dai_stream *io, | ||
349 | struct snd_pcm_substream *substream, | 351 | struct snd_pcm_substream *substream, |
350 | struct snd_pcm_hw_params *params) | 352 | struct snd_pcm_hw_params *params) |
351 | { | 353 | { |
@@ -369,7 +371,8 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod, | |||
369 | /* It will be removed on rsnd_ssi_hw_stop */ | 371 | /* It will be removed on rsnd_ssi_hw_stop */ |
370 | ssi->chan = chan; | 372 | ssi->chan = chan; |
371 | if (ssi_parent) | 373 | if (ssi_parent) |
372 | return rsnd_ssi_hw_params(&ssi_parent->mod, substream, params); | 374 | return rsnd_ssi_hw_params(&ssi_parent->mod, io, |
375 | substream, params); | ||
373 | 376 | ||
374 | return 0; | 377 | return 0; |
375 | } | 378 | } |
@@ -386,12 +389,12 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) | |||
386 | } | 389 | } |
387 | 390 | ||
388 | static int rsnd_ssi_start(struct rsnd_mod *mod, | 391 | static int rsnd_ssi_start(struct rsnd_mod *mod, |
392 | struct rsnd_dai_stream *io, | ||
389 | struct rsnd_priv *priv) | 393 | struct rsnd_priv *priv) |
390 | { | 394 | { |
391 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 395 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
392 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
393 | 396 | ||
394 | rsnd_src_ssiu_start(mod, rsnd_ssi_use_busif(mod)); | 397 | rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(io, mod)); |
395 | 398 | ||
396 | rsnd_ssi_hw_start(ssi, io); | 399 | rsnd_ssi_hw_start(ssi, io); |
397 | 400 | ||
@@ -401,6 +404,7 @@ static int rsnd_ssi_start(struct rsnd_mod *mod, | |||
401 | } | 404 | } |
402 | 405 | ||
403 | static int rsnd_ssi_stop(struct rsnd_mod *mod, | 406 | static int rsnd_ssi_stop(struct rsnd_mod *mod, |
407 | struct rsnd_dai_stream *io, | ||
404 | struct rsnd_priv *priv) | 408 | struct rsnd_priv *priv) |
405 | { | 409 | { |
406 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 410 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
@@ -409,26 +413,26 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, | |||
409 | 413 | ||
410 | rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); | 414 | rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); |
411 | 415 | ||
412 | rsnd_ssi_hw_stop(ssi); | 416 | rsnd_ssi_hw_stop(io, ssi); |
413 | 417 | ||
414 | rsnd_src_ssiu_stop(mod); | 418 | rsnd_src_ssiu_stop(mod, io); |
415 | 419 | ||
416 | return 0; | 420 | return 0; |
417 | } | 421 | } |
418 | 422 | ||
419 | static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | 423 | static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, |
424 | struct rsnd_dai_stream *io) | ||
420 | { | 425 | { |
421 | struct rsnd_ssi *ssi = data; | 426 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
422 | struct rsnd_mod *mod = &ssi->mod; | ||
423 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 427 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
424 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
425 | int is_dma = rsnd_ssi_is_dma_mode(mod); | 428 | int is_dma = rsnd_ssi_is_dma_mode(mod); |
426 | u32 status; | 429 | u32 status; |
430 | bool elapsed = false; | ||
427 | 431 | ||
428 | spin_lock(&priv->lock); | 432 | spin_lock(&priv->lock); |
429 | 433 | ||
430 | /* ignore all cases if not working */ | 434 | /* ignore all cases if not working */ |
431 | if (!rsnd_mod_is_working(mod)) | 435 | if (!rsnd_io_is_working(io)) |
432 | goto rsnd_ssi_interrupt_out; | 436 | goto rsnd_ssi_interrupt_out; |
433 | 437 | ||
434 | status = rsnd_mod_read(mod, SSISR); | 438 | status = rsnd_mod_read(mod, SSISR); |
@@ -449,11 +453,11 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
449 | else | 453 | else |
450 | *buf = rsnd_mod_read(mod, SSIRDR); | 454 | *buf = rsnd_mod_read(mod, SSIRDR); |
451 | 455 | ||
452 | rsnd_dai_pointer_update(io, sizeof(*buf)); | 456 | elapsed = rsnd_dai_pointer_update(io, sizeof(*buf)); |
453 | } | 457 | } |
454 | 458 | ||
455 | /* PIO / DMA */ | 459 | /* DMA only */ |
456 | if (status & (UIRQ | OIRQ)) { | 460 | if (is_dma && (status & (UIRQ | OIRQ))) { |
457 | struct device *dev = rsnd_priv_to_dev(priv); | 461 | struct device *dev = rsnd_priv_to_dev(priv); |
458 | 462 | ||
459 | /* | 463 | /* |
@@ -462,9 +466,9 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
462 | dev_dbg(dev, "%s[%d] restart\n", | 466 | dev_dbg(dev, "%s[%d] restart\n", |
463 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | 467 | rsnd_mod_name(mod), rsnd_mod_id(mod)); |
464 | 468 | ||
465 | rsnd_ssi_stop(mod, priv); | 469 | rsnd_ssi_stop(mod, io, priv); |
466 | if (ssi->err < 1024) | 470 | if (ssi->err < 1024) |
467 | rsnd_ssi_start(mod, priv); | 471 | rsnd_ssi_start(mod, io, priv); |
468 | else | 472 | else |
469 | dev_warn(dev, "no more SSI restart\n"); | 473 | dev_warn(dev, "no more SSI restart\n"); |
470 | } | 474 | } |
@@ -474,6 +478,16 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
474 | rsnd_ssi_interrupt_out: | 478 | rsnd_ssi_interrupt_out: |
475 | spin_unlock(&priv->lock); | 479 | spin_unlock(&priv->lock); |
476 | 480 | ||
481 | if (elapsed) | ||
482 | rsnd_dai_period_elapsed(io); | ||
483 | } | ||
484 | |||
485 | static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | ||
486 | { | ||
487 | struct rsnd_mod *mod = data; | ||
488 | |||
489 | rsnd_mod_interrupt(mod, __rsnd_ssi_interrupt); | ||
490 | |||
477 | return IRQ_HANDLED; | 491 | return IRQ_HANDLED; |
478 | } | 492 | } |
479 | 493 | ||
@@ -481,6 +495,7 @@ rsnd_ssi_interrupt_out: | |||
481 | * SSI PIO | 495 | * SSI PIO |
482 | */ | 496 | */ |
483 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, | 497 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, |
498 | struct rsnd_dai_stream *io, | ||
484 | struct rsnd_priv *priv) | 499 | struct rsnd_priv *priv) |
485 | { | 500 | { |
486 | struct device *dev = rsnd_priv_to_dev(priv); | 501 | struct device *dev = rsnd_priv_to_dev(priv); |
@@ -490,7 +505,7 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, | |||
490 | ret = devm_request_irq(dev, ssi->info->irq, | 505 | ret = devm_request_irq(dev, ssi->info->irq, |
491 | rsnd_ssi_interrupt, | 506 | rsnd_ssi_interrupt, |
492 | IRQF_SHARED, | 507 | IRQF_SHARED, |
493 | dev_name(dev), ssi); | 508 | dev_name(dev), mod); |
494 | 509 | ||
495 | return ret; | 510 | return ret; |
496 | } | 511 | } |
@@ -506,6 +521,7 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = { | |||
506 | }; | 521 | }; |
507 | 522 | ||
508 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, | 523 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, |
524 | struct rsnd_dai_stream *io, | ||
509 | struct rsnd_priv *priv) | 525 | struct rsnd_priv *priv) |
510 | { | 526 | { |
511 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 527 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
@@ -516,25 +532,26 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, | |||
516 | ret = devm_request_irq(dev, ssi->info->irq, | 532 | ret = devm_request_irq(dev, ssi->info->irq, |
517 | rsnd_ssi_interrupt, | 533 | rsnd_ssi_interrupt, |
518 | IRQF_SHARED, | 534 | IRQF_SHARED, |
519 | dev_name(dev), ssi); | 535 | dev_name(dev), mod); |
520 | if (ret) | 536 | if (ret) |
521 | return ret; | 537 | return ret; |
522 | 538 | ||
523 | ret = rsnd_dma_init( | 539 | ret = rsnd_dma_init( |
524 | priv, rsnd_mod_to_dma(mod), | 540 | io, rsnd_mod_to_dma(mod), |
525 | dma_id); | 541 | dma_id); |
526 | 542 | ||
527 | return ret; | 543 | return ret; |
528 | } | 544 | } |
529 | 545 | ||
530 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | 546 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, |
547 | struct rsnd_dai_stream *io, | ||
531 | struct rsnd_priv *priv) | 548 | struct rsnd_priv *priv) |
532 | { | 549 | { |
533 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 550 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
534 | struct device *dev = rsnd_priv_to_dev(priv); | 551 | struct device *dev = rsnd_priv_to_dev(priv); |
535 | int irq = ssi->info->irq; | 552 | int irq = ssi->info->irq; |
536 | 553 | ||
537 | rsnd_dma_quit(rsnd_mod_to_dma(mod)); | 554 | rsnd_dma_quit(io, rsnd_mod_to_dma(mod)); |
538 | 555 | ||
539 | /* PIO will request IRQ again */ | 556 | /* PIO will request IRQ again */ |
540 | devm_free_irq(dev, irq, ssi); | 557 | devm_free_irq(dev, irq, ssi); |
@@ -543,6 +560,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | |||
543 | } | 560 | } |
544 | 561 | ||
545 | static int rsnd_ssi_fallback(struct rsnd_mod *mod, | 562 | static int rsnd_ssi_fallback(struct rsnd_mod *mod, |
563 | struct rsnd_dai_stream *io, | ||
546 | struct rsnd_priv *priv) | 564 | struct rsnd_priv *priv) |
547 | { | 565 | { |
548 | struct device *dev = rsnd_priv_to_dev(priv); | 566 | struct device *dev = rsnd_priv_to_dev(priv); |
@@ -563,37 +581,39 @@ static int rsnd_ssi_fallback(struct rsnd_mod *mod, | |||
563 | } | 581 | } |
564 | 582 | ||
565 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, | 583 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, |
584 | struct rsnd_dai_stream *io, | ||
566 | struct rsnd_priv *priv) | 585 | struct rsnd_priv *priv) |
567 | { | 586 | { |
568 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); | 587 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); |
569 | 588 | ||
570 | rsnd_dma_start(dma); | 589 | rsnd_dma_start(io, dma); |
571 | 590 | ||
572 | rsnd_ssi_start(mod, priv); | 591 | rsnd_ssi_start(mod, io, priv); |
573 | 592 | ||
574 | return 0; | 593 | return 0; |
575 | } | 594 | } |
576 | 595 | ||
577 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, | 596 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, |
597 | struct rsnd_dai_stream *io, | ||
578 | struct rsnd_priv *priv) | 598 | struct rsnd_priv *priv) |
579 | { | 599 | { |
580 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); | 600 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); |
581 | 601 | ||
582 | rsnd_ssi_stop(mod, priv); | 602 | rsnd_ssi_stop(mod, io, priv); |
583 | 603 | ||
584 | rsnd_dma_stop(dma); | 604 | rsnd_dma_stop(io, dma); |
585 | 605 | ||
586 | return 0; | 606 | return 0; |
587 | } | 607 | } |
588 | 608 | ||
589 | static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_mod *mod) | 609 | static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io, |
610 | struct rsnd_mod *mod) | ||
590 | { | 611 | { |
591 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 612 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
592 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
593 | int is_play = rsnd_io_is_play(io); | 613 | int is_play = rsnd_io_is_play(io); |
594 | char *name; | 614 | char *name; |
595 | 615 | ||
596 | if (rsnd_ssi_use_busif(mod)) | 616 | if (rsnd_ssi_use_busif(io, mod)) |
597 | name = is_play ? "rxu" : "txu"; | 617 | name = is_play ? "rxu" : "txu"; |
598 | else | 618 | else |
599 | name = is_play ? "rx" : "tx"; | 619 | name = is_play ? "rx" : "tx"; |
@@ -776,7 +796,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, | |||
776 | else if (rsnd_ssi_pio_available(ssi)) | 796 | else if (rsnd_ssi_pio_available(ssi)) |
777 | ops = &rsnd_ssi_pio_ops; | 797 | ops = &rsnd_ssi_pio_ops; |
778 | 798 | ||
779 | ret = rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i); | 799 | ret = rsnd_mod_init(priv, &ssi->mod, ops, clk, RSND_MOD_SSI, i); |
780 | if (ret) | 800 | if (ret) |
781 | return ret; | 801 | return ret; |
782 | 802 | ||