diff options
author | Mark Brown <broonie@kernel.org> | 2016-07-16 08:05:05 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-07-16 08:05:05 -0400 |
commit | 0efd7248091aad03ecefaa52c51440ddb780cc2e (patch) | |
tree | 3741da09b016a37b5b4c01dc87775f9cc7acf04f | |
parent | cc9bdcf2a4f0cedf7b7425a54578a82bf31dd8f9 (diff) | |
parent | 3527d85b85e65401b7d93073b3ab4e687cdd2521 (diff) |
Merge branch 'topic/simple' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-rcar
-rw-r--r-- | include/sound/simple_card.h | 11 | ||||
-rw-r--r-- | include/sound/simple_card_utils.h | 36 | ||||
-rw-r--r-- | sound/soc/generic/Kconfig | 4 | ||||
-rw-r--r-- | sound/soc/generic/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/generic/simple-card-utils.c | 97 | ||||
-rw-r--r-- | sound/soc/generic/simple-card.c | 276 | ||||
-rw-r--r-- | sound/soc/sh/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsrc-card.c | 38 |
8 files changed, 262 insertions, 203 deletions
diff --git a/include/sound/simple_card.h b/include/sound/simple_card.h index 0399352f3a62..a6a2e1547092 100644 --- a/include/sound/simple_card.h +++ b/include/sound/simple_card.h | |||
@@ -13,16 +13,7 @@ | |||
13 | #define __SIMPLE_CARD_H | 13 | #define __SIMPLE_CARD_H |
14 | 14 | ||
15 | #include <sound/soc.h> | 15 | #include <sound/soc.h> |
16 | 16 | #include <sound/simple_card_utils.h> | |
17 | struct asoc_simple_dai { | ||
18 | const char *name; | ||
19 | unsigned int sysclk; | ||
20 | int slots; | ||
21 | int slot_width; | ||
22 | unsigned int tx_slot_mask; | ||
23 | unsigned int rx_slot_mask; | ||
24 | struct clk *clk; | ||
25 | }; | ||
26 | 17 | ||
27 | struct asoc_simple_card_info { | 18 | struct asoc_simple_card_info { |
28 | const char *name; | 19 | const char *name; |
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h new file mode 100644 index 000000000000..86088aed9002 --- /dev/null +++ b/include/sound/simple_card_utils.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * simple_card_core.h | ||
3 | * | ||
4 | * Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #ifndef __SIMPLE_CARD_CORE_H | ||
11 | #define __SIMPLE_CARD_CORE_H | ||
12 | |||
13 | #include <sound/soc.h> | ||
14 | |||
15 | struct asoc_simple_dai { | ||
16 | const char *name; | ||
17 | unsigned int sysclk; | ||
18 | int slots; | ||
19 | int slot_width; | ||
20 | unsigned int tx_slot_mask; | ||
21 | unsigned int rx_slot_mask; | ||
22 | struct clk *clk; | ||
23 | }; | ||
24 | |||
25 | int asoc_simple_card_parse_daifmt(struct device *dev, | ||
26 | struct device_node *node, | ||
27 | struct device_node *codec, | ||
28 | char *prefix, | ||
29 | unsigned int *retfmt); | ||
30 | int asoc_simple_card_set_dailink_name(struct device *dev, | ||
31 | struct snd_soc_dai_link *dai_link, | ||
32 | const char *fmt, ...); | ||
33 | int asoc_simple_card_parse_card_name(struct snd_soc_card *card, | ||
34 | char *prefix); | ||
35 | |||
36 | #endif /* __SIMPLE_CARD_CORE_H */ | ||
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig index 610f61251640..c01c5dd68601 100644 --- a/sound/soc/generic/Kconfig +++ b/sound/soc/generic/Kconfig | |||
@@ -1,4 +1,8 @@ | |||
1 | config SND_SIMPLE_CARD_UTILS | ||
2 | tristate | ||
3 | |||
1 | config SND_SIMPLE_CARD | 4 | config SND_SIMPLE_CARD |
2 | tristate "ASoC Simple sound card support" | 5 | tristate "ASoC Simple sound card support" |
6 | select SND_SIMPLE_CARD_UTILS | ||
3 | help | 7 | help |
4 | This option enables generic simple sound card support | 8 | This option enables generic simple sound card support |
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile index 9c3b246792bf..45602ca8536e 100644 --- a/sound/soc/generic/Makefile +++ b/sound/soc/generic/Makefile | |||
@@ -1,3 +1,5 @@ | |||
1 | obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) := simple-card-utils.o | ||
2 | |||
1 | snd-soc-simple-card-objs := simple-card.o | 3 | snd-soc-simple-card-objs := simple-card.o |
2 | 4 | ||
3 | obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o | 5 | obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o |
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c new file mode 100644 index 000000000000..d89a9a1b2471 --- /dev/null +++ b/sound/soc/generic/simple-card-utils.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* | ||
2 | * simple-card-core.c | ||
3 | * | ||
4 | * Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/of.h> | ||
11 | #include <sound/simple_card_utils.h> | ||
12 | |||
13 | int asoc_simple_card_parse_daifmt(struct device *dev, | ||
14 | struct device_node *node, | ||
15 | struct device_node *codec, | ||
16 | char *prefix, | ||
17 | unsigned int *retfmt) | ||
18 | { | ||
19 | struct device_node *bitclkmaster = NULL; | ||
20 | struct device_node *framemaster = NULL; | ||
21 | int prefix_len = prefix ? strlen(prefix) : 0; | ||
22 | unsigned int daifmt; | ||
23 | |||
24 | daifmt = snd_soc_of_parse_daifmt(node, prefix, | ||
25 | &bitclkmaster, &framemaster); | ||
26 | daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; | ||
27 | |||
28 | if (prefix_len && !bitclkmaster && !framemaster) { | ||
29 | /* | ||
30 | * No dai-link level and master setting was not found from | ||
31 | * sound node level, revert back to legacy DT parsing and | ||
32 | * take the settings from codec node. | ||
33 | */ | ||
34 | dev_dbg(dev, "Revert to legacy daifmt parsing\n"); | ||
35 | |||
36 | daifmt = snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) | | ||
37 | (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK); | ||
38 | } else { | ||
39 | if (codec == bitclkmaster) | ||
40 | daifmt |= (codec == framemaster) ? | ||
41 | SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS; | ||
42 | else | ||
43 | daifmt |= (codec == framemaster) ? | ||
44 | SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; | ||
45 | } | ||
46 | |||
47 | of_node_put(bitclkmaster); | ||
48 | of_node_put(framemaster); | ||
49 | |||
50 | *retfmt = daifmt; | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | EXPORT_SYMBOL_GPL(asoc_simple_card_parse_daifmt); | ||
55 | |||
56 | int asoc_simple_card_set_dailink_name(struct device *dev, | ||
57 | struct snd_soc_dai_link *dai_link, | ||
58 | const char *fmt, ...) | ||
59 | { | ||
60 | va_list ap; | ||
61 | char *name = NULL; | ||
62 | int ret = -ENOMEM; | ||
63 | |||
64 | va_start(ap, fmt); | ||
65 | name = devm_kvasprintf(dev, GFP_KERNEL, fmt, ap); | ||
66 | va_end(ap); | ||
67 | |||
68 | if (name) { | ||
69 | ret = 0; | ||
70 | |||
71 | dai_link->name = name; | ||
72 | dai_link->stream_name = name; | ||
73 | } | ||
74 | |||
75 | return ret; | ||
76 | } | ||
77 | EXPORT_SYMBOL_GPL(asoc_simple_card_set_dailink_name); | ||
78 | |||
79 | int asoc_simple_card_parse_card_name(struct snd_soc_card *card, | ||
80 | char *prefix) | ||
81 | { | ||
82 | char prop[128]; | ||
83 | int ret; | ||
84 | |||
85 | snprintf(prop, sizeof(prop), "%sname", prefix); | ||
86 | |||
87 | /* Parse the card name from DT */ | ||
88 | ret = snd_soc_of_parse_card_name(card, prop); | ||
89 | if (ret < 0) | ||
90 | return ret; | ||
91 | |||
92 | if (!card->name && card->dai_link) | ||
93 | card->name = card->dai_link->name; | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name); | ||
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 466492b7d4f5..43295f024982 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c | |||
@@ -21,6 +21,12 @@ | |||
21 | #include <sound/soc-dai.h> | 21 | #include <sound/soc-dai.h> |
22 | #include <sound/soc.h> | 22 | #include <sound/soc.h> |
23 | 23 | ||
24 | struct asoc_simple_jack { | ||
25 | struct snd_soc_jack jack; | ||
26 | struct snd_soc_jack_pin pin; | ||
27 | struct snd_soc_jack_gpio gpio; | ||
28 | }; | ||
29 | |||
24 | struct simple_card_data { | 30 | struct simple_card_data { |
25 | struct snd_soc_card snd_card; | 31 | struct snd_soc_card snd_card; |
26 | struct simple_dai_props { | 32 | struct simple_dai_props { |
@@ -29,10 +35,8 @@ struct simple_card_data { | |||
29 | unsigned int mclk_fs; | 35 | unsigned int mclk_fs; |
30 | } *dai_props; | 36 | } *dai_props; |
31 | unsigned int mclk_fs; | 37 | unsigned int mclk_fs; |
32 | int gpio_hp_det; | 38 | struct asoc_simple_jack hp_jack; |
33 | int gpio_hp_det_invert; | 39 | struct asoc_simple_jack mic_jack; |
34 | int gpio_mic_det; | ||
35 | int gpio_mic_det_invert; | ||
36 | struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ | 40 | struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ |
37 | }; | 41 | }; |
38 | 42 | ||
@@ -40,6 +44,69 @@ struct simple_card_data { | |||
40 | #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i) | 44 | #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i) |
41 | #define simple_priv_to_props(priv, i) ((priv)->dai_props + i) | 45 | #define simple_priv_to_props(priv, i) ((priv)->dai_props + i) |
42 | 46 | ||
47 | #define PREFIX "simple-audio-card," | ||
48 | |||
49 | #define asoc_simple_card_init_hp(card, sjack, prefix)\ | ||
50 | asoc_simple_card_init_jack(card, sjack, 1, prefix) | ||
51 | #define asoc_simple_card_init_mic(card, sjack, prefix)\ | ||
52 | asoc_simple_card_init_jack(card, sjack, 0, prefix) | ||
53 | static int asoc_simple_card_init_jack(struct snd_soc_card *card, | ||
54 | struct asoc_simple_jack *sjack, | ||
55 | int is_hp, char *prefix) | ||
56 | { | ||
57 | struct device *dev = card->dev; | ||
58 | enum of_gpio_flags flags; | ||
59 | char prop[128]; | ||
60 | char *pin_name; | ||
61 | char *gpio_name; | ||
62 | int mask; | ||
63 | int det; | ||
64 | |||
65 | sjack->gpio.gpio = -ENOENT; | ||
66 | |||
67 | if (is_hp) { | ||
68 | snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix); | ||
69 | pin_name = "Headphones"; | ||
70 | gpio_name = "Headphone detection"; | ||
71 | mask = SND_JACK_HEADPHONE; | ||
72 | } else { | ||
73 | snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix); | ||
74 | pin_name = "Mic Jack"; | ||
75 | gpio_name = "Mic detection"; | ||
76 | mask = SND_JACK_MICROPHONE; | ||
77 | } | ||
78 | |||
79 | det = of_get_named_gpio_flags(dev->of_node, prop, 0, &flags); | ||
80 | if (det == -EPROBE_DEFER) | ||
81 | return -EPROBE_DEFER; | ||
82 | |||
83 | if (gpio_is_valid(det)) { | ||
84 | sjack->pin.pin = pin_name; | ||
85 | sjack->pin.mask = mask; | ||
86 | |||
87 | sjack->gpio.name = gpio_name; | ||
88 | sjack->gpio.report = mask; | ||
89 | sjack->gpio.gpio = det; | ||
90 | sjack->gpio.invert = !!(flags & OF_GPIO_ACTIVE_LOW); | ||
91 | sjack->gpio.debounce_time = 150; | ||
92 | |||
93 | snd_soc_card_jack_new(card, pin_name, mask, | ||
94 | &sjack->jack, | ||
95 | &sjack->pin, 1); | ||
96 | |||
97 | snd_soc_jack_add_gpios(&sjack->jack, 1, | ||
98 | &sjack->gpio); | ||
99 | } | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static void asoc_simple_card_remove_jack(struct asoc_simple_jack *sjack) | ||
105 | { | ||
106 | if (gpio_is_valid(sjack->gpio.gpio)) | ||
107 | snd_soc_jack_free_gpios(&sjack->jack, 1, &sjack->gpio); | ||
108 | } | ||
109 | |||
43 | static int asoc_simple_card_startup(struct snd_pcm_substream *substream) | 110 | static int asoc_simple_card_startup(struct snd_pcm_substream *substream) |
44 | { | 111 | { |
45 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 112 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
@@ -110,32 +177,6 @@ static struct snd_soc_ops asoc_simple_card_ops = { | |||
110 | .hw_params = asoc_simple_card_hw_params, | 177 | .hw_params = asoc_simple_card_hw_params, |
111 | }; | 178 | }; |
112 | 179 | ||
113 | static struct snd_soc_jack simple_card_hp_jack; | ||
114 | static struct snd_soc_jack_pin simple_card_hp_jack_pins[] = { | ||
115 | { | ||
116 | .pin = "Headphones", | ||
117 | .mask = SND_JACK_HEADPHONE, | ||
118 | }, | ||
119 | }; | ||
120 | static struct snd_soc_jack_gpio simple_card_hp_jack_gpio = { | ||
121 | .name = "Headphone detection", | ||
122 | .report = SND_JACK_HEADPHONE, | ||
123 | .debounce_time = 150, | ||
124 | }; | ||
125 | |||
126 | static struct snd_soc_jack simple_card_mic_jack; | ||
127 | static struct snd_soc_jack_pin simple_card_mic_jack_pins[] = { | ||
128 | { | ||
129 | .pin = "Mic Jack", | ||
130 | .mask = SND_JACK_MICROPHONE, | ||
131 | }, | ||
132 | }; | ||
133 | static struct snd_soc_jack_gpio simple_card_mic_jack_gpio = { | ||
134 | .name = "Mic detection", | ||
135 | .report = SND_JACK_MICROPHONE, | ||
136 | .debounce_time = 150, | ||
137 | }; | ||
138 | |||
139 | static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, | 180 | static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, |
140 | struct asoc_simple_dai *set) | 181 | struct asoc_simple_dai *set) |
141 | { | 182 | { |
@@ -184,30 +225,14 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) | |||
184 | if (ret < 0) | 225 | if (ret < 0) |
185 | return ret; | 226 | return ret; |
186 | 227 | ||
187 | if (gpio_is_valid(priv->gpio_hp_det)) { | 228 | ret = asoc_simple_card_init_hp(rtd->card, &priv->hp_jack, PREFIX); |
188 | snd_soc_card_jack_new(rtd->card, "Headphones", | 229 | if (ret < 0) |
189 | SND_JACK_HEADPHONE, | 230 | return ret; |
190 | &simple_card_hp_jack, | 231 | |
191 | simple_card_hp_jack_pins, | 232 | ret = asoc_simple_card_init_mic(rtd->card, &priv->hp_jack, PREFIX); |
192 | ARRAY_SIZE(simple_card_hp_jack_pins)); | 233 | if (ret < 0) |
193 | 234 | return ret; | |
194 | simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det; | ||
195 | simple_card_hp_jack_gpio.invert = priv->gpio_hp_det_invert; | ||
196 | snd_soc_jack_add_gpios(&simple_card_hp_jack, 1, | ||
197 | &simple_card_hp_jack_gpio); | ||
198 | } | ||
199 | 235 | ||
200 | if (gpio_is_valid(priv->gpio_mic_det)) { | ||
201 | snd_soc_card_jack_new(rtd->card, "Mic Jack", | ||
202 | SND_JACK_MICROPHONE, | ||
203 | &simple_card_mic_jack, | ||
204 | simple_card_mic_jack_pins, | ||
205 | ARRAY_SIZE(simple_card_mic_jack_pins)); | ||
206 | simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det; | ||
207 | simple_card_mic_jack_gpio.invert = priv->gpio_mic_det_invert; | ||
208 | snd_soc_jack_add_gpios(&simple_card_mic_jack, 1, | ||
209 | &simple_card_mic_jack_gpio); | ||
210 | } | ||
211 | return 0; | 236 | return 0; |
212 | } | 237 | } |
213 | 238 | ||
@@ -223,6 +248,9 @@ asoc_simple_card_sub_parse_of(struct device_node *np, | |||
223 | u32 val; | 248 | u32 val; |
224 | int ret; | 249 | int ret; |
225 | 250 | ||
251 | if (!np) | ||
252 | return 0; | ||
253 | |||
226 | /* | 254 | /* |
227 | * Get node via "sound-dai = <&phandle port>" | 255 | * Get node via "sound-dai = <&phandle port>" |
228 | * it will be used as xxx_of_node on soc_bind_dai_link() | 256 | * it will be used as xxx_of_node on soc_bind_dai_link() |
@@ -238,9 +266,14 @@ asoc_simple_card_sub_parse_of(struct device_node *np, | |||
238 | *args_count = args.args_count; | 266 | *args_count = args.args_count; |
239 | 267 | ||
240 | /* Get dai->name */ | 268 | /* Get dai->name */ |
241 | ret = snd_soc_of_get_dai_name(np, name); | 269 | if (name) { |
242 | if (ret < 0) | 270 | ret = snd_soc_of_get_dai_name(np, name); |
243 | return ret; | 271 | if (ret < 0) |
272 | return ret; | ||
273 | } | ||
274 | |||
275 | if (!dai) | ||
276 | return 0; | ||
244 | 277 | ||
245 | /* Parse TDM slot */ | 278 | /* Parse TDM slot */ |
246 | ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask, | 279 | ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask, |
@@ -275,48 +308,6 @@ asoc_simple_card_sub_parse_of(struct device_node *np, | |||
275 | return 0; | 308 | return 0; |
276 | } | 309 | } |
277 | 310 | ||
278 | static int asoc_simple_card_parse_daifmt(struct device_node *node, | ||
279 | struct simple_card_data *priv, | ||
280 | struct device_node *codec, | ||
281 | char *prefix, int idx) | ||
282 | { | ||
283 | struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); | ||
284 | struct device *dev = simple_priv_to_dev(priv); | ||
285 | struct device_node *bitclkmaster = NULL; | ||
286 | struct device_node *framemaster = NULL; | ||
287 | unsigned int daifmt; | ||
288 | |||
289 | daifmt = snd_soc_of_parse_daifmt(node, prefix, | ||
290 | &bitclkmaster, &framemaster); | ||
291 | daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; | ||
292 | |||
293 | if (strlen(prefix) && !bitclkmaster && !framemaster) { | ||
294 | /* | ||
295 | * No dai-link level and master setting was not found from | ||
296 | * sound node level, revert back to legacy DT parsing and | ||
297 | * take the settings from codec node. | ||
298 | */ | ||
299 | dev_dbg(dev, "Revert to legacy daifmt parsing\n"); | ||
300 | |||
301 | daifmt = snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) | | ||
302 | (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK); | ||
303 | } else { | ||
304 | if (codec == bitclkmaster) | ||
305 | daifmt |= (codec == framemaster) ? | ||
306 | SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS; | ||
307 | else | ||
308 | daifmt |= (codec == framemaster) ? | ||
309 | SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; | ||
310 | } | ||
311 | |||
312 | dai_link->dai_fmt = daifmt; | ||
313 | |||
314 | of_node_put(bitclkmaster); | ||
315 | of_node_put(framemaster); | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int asoc_simple_card_dai_link_of(struct device_node *node, | 311 | static int asoc_simple_card_dai_link_of(struct device_node *node, |
321 | struct simple_card_data *priv, | 312 | struct simple_card_data *priv, |
322 | int idx, | 313 | int idx, |
@@ -328,7 +319,6 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
328 | struct device_node *cpu = NULL; | 319 | struct device_node *cpu = NULL; |
329 | struct device_node *plat = NULL; | 320 | struct device_node *plat = NULL; |
330 | struct device_node *codec = NULL; | 321 | struct device_node *codec = NULL; |
331 | char *name; | ||
332 | char prop[128]; | 322 | char prop[128]; |
333 | char *prefix = ""; | 323 | char *prefix = ""; |
334 | int ret, cpu_args; | 324 | int ret, cpu_args; |
@@ -336,7 +326,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
336 | 326 | ||
337 | /* For single DAI link & old style of DT node */ | 327 | /* For single DAI link & old style of DT node */ |
338 | if (is_top_level_node) | 328 | if (is_top_level_node) |
339 | prefix = "simple-audio-card,"; | 329 | prefix = PREFIX; |
340 | 330 | ||
341 | snprintf(prop, sizeof(prop), "%scpu", prefix); | 331 | snprintf(prop, sizeof(prop), "%scpu", prefix); |
342 | cpu = of_get_child_by_name(node, prop); | 332 | cpu = of_get_child_by_name(node, prop); |
@@ -353,8 +343,8 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
353 | goto dai_link_of_err; | 343 | goto dai_link_of_err; |
354 | } | 344 | } |
355 | 345 | ||
356 | ret = asoc_simple_card_parse_daifmt(node, priv, | 346 | ret = asoc_simple_card_parse_daifmt(dev, node, codec, |
357 | codec, prefix, idx); | 347 | prefix, &dai_link->dai_fmt); |
358 | if (ret < 0) | 348 | if (ret < 0) |
359 | goto dai_link_of_err; | 349 | goto dai_link_of_err; |
360 | 350 | ||
@@ -374,35 +364,28 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
374 | if (ret < 0) | 364 | if (ret < 0) |
375 | goto dai_link_of_err; | 365 | goto dai_link_of_err; |
376 | 366 | ||
367 | ret = asoc_simple_card_sub_parse_of(plat, NULL, | ||
368 | &dai_link->platform_of_node, | ||
369 | NULL, NULL); | ||
370 | if (ret < 0) | ||
371 | goto dai_link_of_err; | ||
372 | |||
377 | if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { | 373 | if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { |
378 | ret = -EINVAL; | 374 | ret = -EINVAL; |
379 | goto dai_link_of_err; | 375 | goto dai_link_of_err; |
380 | } | 376 | } |
381 | 377 | ||
382 | if (plat) { | 378 | /* Assumes platform == cpu */ |
383 | struct of_phandle_args args; | 379 | if (!dai_link->platform_of_node) |
384 | |||
385 | ret = of_parse_phandle_with_args(plat, "sound-dai", | ||
386 | "#sound-dai-cells", 0, &args); | ||
387 | dai_link->platform_of_node = args.np; | ||
388 | } else { | ||
389 | /* Assumes platform == cpu */ | ||
390 | dai_link->platform_of_node = dai_link->cpu_of_node; | 380 | dai_link->platform_of_node = dai_link->cpu_of_node; |
391 | } | ||
392 | 381 | ||
393 | /* DAI link name is created from CPU/CODEC dai name */ | 382 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, |
394 | name = devm_kzalloc(dev, | 383 | "%s-%s", |
395 | strlen(dai_link->cpu_dai_name) + | 384 | dai_link->cpu_dai_name, |
396 | strlen(dai_link->codec_dai_name) + 2, | 385 | dai_link->codec_dai_name); |
397 | GFP_KERNEL); | 386 | if (ret < 0) |
398 | if (!name) { | ||
399 | ret = -ENOMEM; | ||
400 | goto dai_link_of_err; | 387 | goto dai_link_of_err; |
401 | } | ||
402 | 388 | ||
403 | sprintf(name, "%s-%s", dai_link->cpu_dai_name, | ||
404 | dai_link->codec_dai_name); | ||
405 | dai_link->name = dai_link->stream_name = name; | ||
406 | dai_link->ops = &asoc_simple_card_ops; | 389 | dai_link->ops = &asoc_simple_card_ops; |
407 | dai_link->init = asoc_simple_card_dai_init; | 390 | dai_link->init = asoc_simple_card_dai_init; |
408 | 391 | ||
@@ -438,42 +421,35 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
438 | struct simple_card_data *priv) | 421 | struct simple_card_data *priv) |
439 | { | 422 | { |
440 | struct device *dev = simple_priv_to_dev(priv); | 423 | struct device *dev = simple_priv_to_dev(priv); |
441 | enum of_gpio_flags flags; | ||
442 | u32 val; | 424 | u32 val; |
443 | int ret; | 425 | int ret; |
444 | 426 | ||
445 | if (!node) | 427 | if (!node) |
446 | return -EINVAL; | 428 | return -EINVAL; |
447 | 429 | ||
448 | /* Parse the card name from DT */ | ||
449 | snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name"); | ||
450 | |||
451 | /* The off-codec widgets */ | 430 | /* The off-codec widgets */ |
452 | if (of_property_read_bool(node, "simple-audio-card,widgets")) { | 431 | if (of_property_read_bool(node, PREFIX "widgets")) { |
453 | ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, | 432 | ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, |
454 | "simple-audio-card,widgets"); | 433 | PREFIX "widgets"); |
455 | if (ret) | 434 | if (ret) |
456 | return ret; | 435 | return ret; |
457 | } | 436 | } |
458 | 437 | ||
459 | /* DAPM routes */ | 438 | /* DAPM routes */ |
460 | if (of_property_read_bool(node, "simple-audio-card,routing")) { | 439 | if (of_property_read_bool(node, PREFIX "routing")) { |
461 | ret = snd_soc_of_parse_audio_routing(&priv->snd_card, | 440 | ret = snd_soc_of_parse_audio_routing(&priv->snd_card, |
462 | "simple-audio-card,routing"); | 441 | PREFIX "routing"); |
463 | if (ret) | 442 | if (ret) |
464 | return ret; | 443 | return ret; |
465 | } | 444 | } |
466 | 445 | ||
467 | /* Factor to mclk, used in hw_params() */ | 446 | /* Factor to mclk, used in hw_params() */ |
468 | ret = of_property_read_u32(node, "simple-audio-card,mclk-fs", &val); | 447 | ret = of_property_read_u32(node, PREFIX "mclk-fs", &val); |
469 | if (ret == 0) | 448 | if (ret == 0) |
470 | priv->mclk_fs = val; | 449 | priv->mclk_fs = val; |
471 | 450 | ||
472 | dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ? | ||
473 | priv->snd_card.name : ""); | ||
474 | |||
475 | /* Single/Muti DAI link(s) & New style of DT node */ | 451 | /* Single/Muti DAI link(s) & New style of DT node */ |
476 | if (of_get_child_by_name(node, "simple-audio-card,dai-link")) { | 452 | if (of_get_child_by_name(node, PREFIX "dai-link")) { |
477 | struct device_node *np = NULL; | 453 | struct device_node *np = NULL; |
478 | int i = 0; | 454 | int i = 0; |
479 | 455 | ||
@@ -494,20 +470,9 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
494 | return ret; | 470 | return ret; |
495 | } | 471 | } |
496 | 472 | ||
497 | priv->gpio_hp_det = of_get_named_gpio_flags(node, | 473 | ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); |
498 | "simple-audio-card,hp-det-gpio", 0, &flags); | 474 | if (ret) |
499 | priv->gpio_hp_det_invert = !!(flags & OF_GPIO_ACTIVE_LOW); | 475 | return ret; |
500 | if (priv->gpio_hp_det == -EPROBE_DEFER) | ||
501 | return -EPROBE_DEFER; | ||
502 | |||
503 | priv->gpio_mic_det = of_get_named_gpio_flags(node, | ||
504 | "simple-audio-card,mic-det-gpio", 0, &flags); | ||
505 | priv->gpio_mic_det_invert = !!(flags & OF_GPIO_ACTIVE_LOW); | ||
506 | if (priv->gpio_mic_det == -EPROBE_DEFER) | ||
507 | return -EPROBE_DEFER; | ||
508 | |||
509 | if (!priv->snd_card.name) | ||
510 | priv->snd_card.name = priv->snd_card.dai_link->name; | ||
511 | 476 | ||
512 | return 0; | 477 | return 0; |
513 | } | 478 | } |
@@ -536,7 +501,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev) | |||
536 | int num_links, ret; | 501 | int num_links, ret; |
537 | 502 | ||
538 | /* Get the number of DAI links */ | 503 | /* Get the number of DAI links */ |
539 | if (np && of_get_child_by_name(np, "simple-audio-card,dai-link")) | 504 | if (np && of_get_child_by_name(np, PREFIX "dai-link")) |
540 | num_links = of_get_child_count(np); | 505 | num_links = of_get_child_count(np); |
541 | else | 506 | else |
542 | num_links = 1; | 507 | num_links = 1; |
@@ -555,9 +520,6 @@ static int asoc_simple_card_probe(struct platform_device *pdev) | |||
555 | priv->snd_card.dai_link = dai_link; | 520 | priv->snd_card.dai_link = dai_link; |
556 | priv->snd_card.num_links = num_links; | 521 | priv->snd_card.num_links = num_links; |
557 | 522 | ||
558 | priv->gpio_hp_det = -ENOENT; | ||
559 | priv->gpio_mic_det = -ENOENT; | ||
560 | |||
561 | /* Get room for the other properties */ | 523 | /* Get room for the other properties */ |
562 | priv->dai_props = devm_kzalloc(dev, | 524 | priv->dai_props = devm_kzalloc(dev, |
563 | sizeof(*priv->dai_props) * num_links, | 525 | sizeof(*priv->dai_props) * num_links, |
@@ -624,12 +586,8 @@ static int asoc_simple_card_remove(struct platform_device *pdev) | |||
624 | struct snd_soc_card *card = platform_get_drvdata(pdev); | 586 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
625 | struct simple_card_data *priv = snd_soc_card_get_drvdata(card); | 587 | struct simple_card_data *priv = snd_soc_card_get_drvdata(card); |
626 | 588 | ||
627 | if (gpio_is_valid(priv->gpio_hp_det)) | 589 | asoc_simple_card_remove_jack(&priv->hp_jack); |
628 | snd_soc_jack_free_gpios(&simple_card_hp_jack, 1, | 590 | asoc_simple_card_remove_jack(&priv->mic_jack); |
629 | &simple_card_hp_jack_gpio); | ||
630 | if (gpio_is_valid(priv->gpio_mic_det)) | ||
631 | snd_soc_jack_free_gpios(&simple_card_mic_jack, 1, | ||
632 | &simple_card_mic_jack_gpio); | ||
633 | 591 | ||
634 | return asoc_simple_card_unref(card); | 592 | return asoc_simple_card_unref(card); |
635 | } | 593 | } |
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index c9902a6d6fa0..9311f119feb5 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig | |||
@@ -44,6 +44,7 @@ config SND_SOC_RCAR | |||
44 | 44 | ||
45 | config SND_SOC_RSRC_CARD | 45 | config SND_SOC_RSRC_CARD |
46 | tristate "Renesas Sampling Rate Convert Sound Card" | 46 | tristate "Renesas Sampling Rate Convert Sound Card" |
47 | select SND_SIMPLE_CARD_UTILS | ||
47 | help | 48 | help |
48 | This option enables simple sound if you need sampling rate convert | 49 | This option enables simple sound if you need sampling rate convert |
49 | 50 | ||
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c index b85b5ee5fad4..c065a6df0680 100644 --- a/sound/soc/sh/rcar/rsrc-card.c +++ b/sound/soc/sh/rcar/rsrc-card.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <sound/jack.h> | 20 | #include <sound/jack.h> |
21 | #include <sound/soc.h> | 21 | #include <sound/soc.h> |
22 | #include <sound/soc-dai.h> | 22 | #include <sound/soc-dai.h> |
23 | #include <sound/simple_card_utils.h> | ||
23 | 24 | ||
24 | struct rsrc_card_of_data { | 25 | struct rsrc_card_of_data { |
25 | const char *prefix; | 26 | const char *prefix; |
@@ -158,38 +159,6 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, | |||
158 | return 0; | 159 | return 0; |
159 | } | 160 | } |
160 | 161 | ||
161 | static int rsrc_card_parse_daifmt(struct device_node *node, | ||
162 | struct device_node *codec, | ||
163 | struct rsrc_card_priv *priv, | ||
164 | struct snd_soc_dai_link *dai_link, | ||
165 | unsigned int *retfmt) | ||
166 | { | ||
167 | struct device_node *bitclkmaster = NULL; | ||
168 | struct device_node *framemaster = NULL; | ||
169 | unsigned int daifmt; | ||
170 | |||
171 | daifmt = snd_soc_of_parse_daifmt(node, NULL, | ||
172 | &bitclkmaster, &framemaster); | ||
173 | daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; | ||
174 | |||
175 | if (!bitclkmaster && !framemaster) | ||
176 | return -EINVAL; | ||
177 | |||
178 | if (codec == bitclkmaster) | ||
179 | daifmt |= (codec == framemaster) ? | ||
180 | SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS; | ||
181 | else | ||
182 | daifmt |= (codec == framemaster) ? | ||
183 | SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; | ||
184 | |||
185 | of_node_put(bitclkmaster); | ||
186 | of_node_put(framemaster); | ||
187 | |||
188 | *retfmt = daifmt; | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int rsrc_card_parse_links(struct device_node *np, | 162 | static int rsrc_card_parse_links(struct device_node *np, |
194 | struct rsrc_card_priv *priv, | 163 | struct rsrc_card_priv *priv, |
195 | int idx, bool is_fe) | 164 | int idx, bool is_fe) |
@@ -357,6 +326,7 @@ static int rsrc_card_dai_sub_link_of(struct device_node *node, | |||
357 | static int rsrc_card_dai_link_of(struct device_node *node, | 326 | static int rsrc_card_dai_link_of(struct device_node *node, |
358 | struct rsrc_card_priv *priv) | 327 | struct rsrc_card_priv *priv) |
359 | { | 328 | { |
329 | struct device *dev = rsrc_priv_to_dev(priv); | ||
360 | struct snd_soc_dai_link *dai_link; | 330 | struct snd_soc_dai_link *dai_link; |
361 | struct device_node *np; | 331 | struct device_node *np; |
362 | unsigned int daifmt = 0; | 332 | unsigned int daifmt = 0; |
@@ -369,8 +339,8 @@ static int rsrc_card_dai_link_of(struct device_node *node, | |||
369 | dai_link = rsrc_priv_to_link(priv, i); | 339 | dai_link = rsrc_priv_to_link(priv, i); |
370 | 340 | ||
371 | if (strcmp(np->name, "codec") == 0) { | 341 | if (strcmp(np->name, "codec") == 0) { |
372 | ret = rsrc_card_parse_daifmt(node, np, priv, | 342 | ret = asoc_simple_card_parse_daifmt(dev, node, np, |
373 | dai_link, &daifmt); | 343 | NULL, &daifmt); |
374 | if (ret < 0) | 344 | if (ret < 0) |
375 | return ret; | 345 | return ret; |
376 | break; | 346 | break; |