Merge tag 'docs-4.20' of git://git.lwn.net/linux
[linux-2.6-block.git] / drivers / staging / greybus / audio_topology.c
CommitLineData
eb50fd3a 1// SPDX-License-Identifier: GPL-2.0
6339d232
VA
2/*
3 * Greybus audio driver
4 * Copyright 2015-2016 Google Inc.
5 * Copyright 2015-2016 Linaro Ltd.
6339d232
VA
6 */
7
8#include "audio_codec.h"
9#include "greybus_protocols.h"
10
11#define GBAUDIO_INVALID_ID 0xFF
12
13/* mixer control */
14struct gb_mixer_control {
15 int min, max;
16 unsigned int reg, rreg, shift, rshift, invert;
17};
18
19struct gbaudio_ctl_pvt {
20 unsigned int ctl_id;
21 unsigned int data_cport;
22 unsigned int access;
23 unsigned int vcount;
24 struct gb_audio_ctl_elem_info *info;
25};
26
6dd67645
VA
27static struct gbaudio_module_info *find_gb_module(
28 struct gbaudio_codec_info *codec,
29 char const *name)
30{
31 int dev_id, ret;
32 char begin[NAME_SIZE];
33 struct gbaudio_module_info *module;
34
35 if (!name)
36 return NULL;
37
38 ret = sscanf(name, "%s %d", begin, &dev_id);
39 dev_dbg(codec->dev, "%s:Find module#%d\n", __func__, dev_id);
40
41 mutex_lock(&codec->lock);
42 list_for_each_entry(module, &codec->module_list, list) {
43 if (module->dev_id == dev_id) {
44 mutex_unlock(&codec->lock);
45 return module;
46 }
47 }
48 mutex_unlock(&codec->lock);
02f1c12c
VA
49 dev_warn(codec->dev, "%s: module#%d missing in codec list\n", name,
50 dev_id);
6dd67645
VA
51 return NULL;
52}
53
54static const char *gbaudio_map_controlid(struct gbaudio_module_info *module,
e65579e3 55 __u8 control_id, __u8 index)
6339d232
VA
56{
57 struct gbaudio_control *control;
58
59 if (control_id == GBAUDIO_INVALID_ID)
60 return NULL;
61
6dd67645 62 list_for_each_entry(control, &module->ctl_list, list) {
6339d232
VA
63 if (control->id == control_id) {
64 if (index == GBAUDIO_INVALID_ID)
65 return control->name;
15c726ea
VA
66 if (index >= control->items)
67 return NULL;
6339d232
VA
68 return control->texts[index];
69 }
70 }
6dd67645 71 list_for_each_entry(control, &module->widget_ctl_list, list) {
6339d232
VA
72 if (control->id == control_id) {
73 if (index == GBAUDIO_INVALID_ID)
74 return control->name;
15c726ea
VA
75 if (index >= control->items)
76 return NULL;
6339d232
VA
77 return control->texts[index];
78 }
79 }
80 return NULL;
81}
82
e65579e3
VA
83static int gbaudio_map_controlname(struct gbaudio_module_info *module,
84 const char *name)
85{
86 struct gbaudio_control *control;
87
88 list_for_each_entry(control, &module->ctl_list, list) {
89 if (!strncmp(control->name, name, NAME_SIZE))
90 return control->id;
91 }
92
93 dev_warn(module->dev, "%s: missing in modules controls list\n", name);
94
95 return -EINVAL;
96}
97
0c15a9e0 98static int gbaudio_map_wcontrolname(struct gbaudio_module_info *module,
e65579e3 99 const char *name)
0c15a9e0
VA
100{
101 struct gbaudio_control *control;
102
103 list_for_each_entry(control, &module->widget_ctl_list, list) {
104 if (!strncmp(control->wname, name, NAME_SIZE))
105 return control->id;
106 }
107 dev_warn(module->dev, "%s: missing in modules controls list\n", name);
108
109 return -EINVAL;
110}
111
6dd67645 112static int gbaudio_map_widgetname(struct gbaudio_module_info *module,
e65579e3 113 const char *name)
6339d232
VA
114{
115 struct gbaudio_widget *widget;
a2a87b22 116
6dd67645
VA
117 list_for_each_entry(widget, &module->widget_list, list) {
118 if (!strncmp(widget->name, name, NAME_SIZE))
6339d232
VA
119 return widget->id;
120 }
bb296b48
VA
121 dev_warn(module->dev, "%s: missing in modules widgets list\n", name);
122
6339d232
VA
123 return -EINVAL;
124}
125
6dd67645 126static const char *gbaudio_map_widgetid(struct gbaudio_module_info *module,
e65579e3 127 __u8 widget_id)
6339d232
VA
128{
129 struct gbaudio_widget *widget;
130
6dd67645 131 list_for_each_entry(widget, &module->widget_list, list) {
6339d232
VA
132 if (widget->id == widget_id)
133 return widget->name;
134 }
135 return NULL;
136}
137
a0de502e
VK
138static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb,
139 struct gb_audio_enumerated *gbenum)
e65579e3
VA
140{
141 const char **strings;
142 int i;
055fb9ce 143 unsigned int items;
e65579e3
VA
144 __u8 *data;
145
055fb9ce 146 items = le32_to_cpu(gbenum->items);
a86854d0 147 strings = devm_kcalloc(gb->dev, items, sizeof(char *), GFP_KERNEL);
e65579e3
VA
148 data = gbenum->names;
149
055fb9ce 150 for (i = 0; i < items; i++) {
e65579e3
VA
151 strings[i] = (const char *)data;
152 while (*data != '\0')
153 data++;
154 data++;
155 }
156
157 return strings;
158}
159
6339d232
VA
160static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol,
161 struct snd_ctl_elem_info *uinfo)
162{
163 unsigned int max;
164 const char *name;
165 struct gbaudio_ctl_pvt *data;
166 struct gb_audio_ctl_elem_info *info;
6dd67645 167 struct gbaudio_module_info *module;
6339d232 168 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
796fad44 169 struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec);
6339d232 170
6dd67645 171 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
6339d232
VA
172 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
173 info = (struct gb_audio_ctl_elem_info *)data->info;
174
175 if (!info) {
7224a2a5 176 dev_err(codec->dev, "NULL info for %s\n", uinfo->id.name);
6339d232
VA
177 return -EINVAL;
178 }
179
180 /* update uinfo */
181 uinfo->access = data->access;
182 uinfo->count = data->vcount;
183 uinfo->type = (snd_ctl_elem_type_t)info->type;
184
185 switch (info->type) {
186 case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
187 case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
055fb9ce
VA
188 uinfo->value.integer.min = le32_to_cpu(info->value.integer.min);
189 uinfo->value.integer.max = le32_to_cpu(info->value.integer.max);
6339d232
VA
190 break;
191 case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
055fb9ce 192 max = le32_to_cpu(info->value.enumerated.items);
6339d232
VA
193 uinfo->value.enumerated.items = max;
194 if (uinfo->value.enumerated.item > max - 1)
195 uinfo->value.enumerated.item = max - 1;
6dd67645
VA
196 module = find_gb_module(gbcodec, kcontrol->id.name);
197 if (!module)
198 return -EINVAL;
199 name = gbaudio_map_controlid(module, data->ctl_id,
6339d232
VA
200 uinfo->value.enumerated.item);
201 strlcpy(uinfo->value.enumerated.name, name, NAME_SIZE);
202 break;
203 default:
204 dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
205 info->type, kcontrol->id.name);
206 break;
207 }
208 return 0;
209}
210
211static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol,
212 struct snd_ctl_elem_value *ucontrol)
213{
214 int ret;
215 struct gb_audio_ctl_elem_info *info;
216 struct gbaudio_ctl_pvt *data;
217 struct gb_audio_ctl_elem_value gbvalue;
6dd67645 218 struct gbaudio_module_info *module;
6339d232 219 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
796fad44 220 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
6ba7fad4 221 struct gb_bundle *bundle;
6339d232 222
6dd67645
VA
223 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
224 module = find_gb_module(gb, kcontrol->id.name);
225 if (!module)
226 return -EINVAL;
3994e0b1 227
6339d232
VA
228 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
229 info = (struct gb_audio_ctl_elem_info *)data->info;
6ba7fad4
DL
230 bundle = to_gb_bundle(module->dev);
231
232 ret = gb_pm_runtime_get_sync(bundle);
233 if (ret)
234 return ret;
6339d232 235
6dd67645 236 ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
6339d232 237 GB_AUDIO_INVALID_INDEX, &gbvalue);
6ba7fad4
DL
238
239 gb_pm_runtime_put_autosuspend(bundle);
240
6339d232 241 if (ret) {
c6722ab5
VA
242 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
243 __func__, kcontrol->id.name);
6339d232
VA
244 return ret;
245 }
246
247 /* update ucontrol */
248 switch (info->type) {
249 case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
250 case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
251 ucontrol->value.integer.value[0] =
055fb9ce 252 le32_to_cpu(gbvalue.value.integer_value[0]);
6339d232
VA
253 if (data->vcount == 2)
254 ucontrol->value.integer.value[1] =
055fb9ce 255 le32_to_cpu(gbvalue.value.integer_value[1]);
6339d232
VA
256 break;
257 case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
258 ucontrol->value.enumerated.item[0] =
055fb9ce 259 le32_to_cpu(gbvalue.value.enumerated_item[0]);
6339d232
VA
260 if (data->vcount == 2)
261 ucontrol->value.enumerated.item[1] =
055fb9ce 262 le32_to_cpu(gbvalue.value.enumerated_item[1]);
6339d232
VA
263 break;
264 default:
265 dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
266 info->type, kcontrol->id.name);
267 ret = -EINVAL;
268 break;
269 }
270 return ret;
271}
272
273static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol,
274 struct snd_ctl_elem_value *ucontrol)
275{
276 int ret = 0;
277 struct gb_audio_ctl_elem_info *info;
278 struct gbaudio_ctl_pvt *data;
279 struct gb_audio_ctl_elem_value gbvalue;
6dd67645 280 struct gbaudio_module_info *module;
6339d232 281 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
796fad44 282 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
6ba7fad4 283 struct gb_bundle *bundle;
6339d232 284
6dd67645
VA
285 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
286 module = find_gb_module(gb, kcontrol->id.name);
287 if (!module)
288 return -EINVAL;
3994e0b1 289
6339d232
VA
290 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
291 info = (struct gb_audio_ctl_elem_info *)data->info;
6ba7fad4 292 bundle = to_gb_bundle(module->dev);
6339d232
VA
293
294 /* update ucontrol */
295 switch (info->type) {
296 case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
297 case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
298 gbvalue.value.integer_value[0] =
055fb9ce 299 cpu_to_le32(ucontrol->value.integer.value[0]);
6339d232
VA
300 if (data->vcount == 2)
301 gbvalue.value.integer_value[1] =
055fb9ce 302 cpu_to_le32(ucontrol->value.integer.value[1]);
6339d232
VA
303 break;
304 case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
305 gbvalue.value.enumerated_item[0] =
055fb9ce 306 cpu_to_le32(ucontrol->value.enumerated.item[0]);
6339d232
VA
307 if (data->vcount == 2)
308 gbvalue.value.enumerated_item[1] =
055fb9ce 309 cpu_to_le32(ucontrol->value.enumerated.item[1]);
6339d232
VA
310 break;
311 default:
312 dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
313 info->type, kcontrol->id.name);
314 ret = -EINVAL;
315 break;
316 }
317
6ba7fad4
DL
318 if (ret)
319 return ret;
320
321 ret = gb_pm_runtime_get_sync(bundle);
6339d232
VA
322 if (ret)
323 return ret;
324
6dd67645 325 ret = gb_audio_gb_set_control(module->mgmt_connection, data->ctl_id,
6339d232 326 GB_AUDIO_INVALID_INDEX, &gbvalue);
6ba7fad4
DL
327
328 gb_pm_runtime_put_autosuspend(bundle);
329
6339d232 330 if (ret) {
c6722ab5
VA
331 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
332 __func__, kcontrol->id.name);
6339d232
VA
333 }
334
335 return ret;
336}
337
338#define SOC_MIXER_GB(xname, kcount, data) \
339{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
340 .count = kcount, .info = gbcodec_mixer_ctl_info, \
341 .get = gbcodec_mixer_ctl_get, .put = gbcodec_mixer_ctl_put, \
342 .private_value = (unsigned long)data }
343
344/*
345 * although below callback functions seems redundant to above functions.
346 * same are kept to allow provision for different handling in case
347 * of DAPM related sequencing, etc.
348 */
349static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol,
350 struct snd_ctl_elem_info *uinfo)
351{
352 int platform_max, platform_min;
353 struct gbaudio_ctl_pvt *data;
354 struct gb_audio_ctl_elem_info *info;
6dd67645
VA
355 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
356 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
357 struct snd_soc_codec *codec = widget->codec;
6339d232 358
6dd67645 359 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
6339d232
VA
360 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
361 info = (struct gb_audio_ctl_elem_info *)data->info;
362
363 /* update uinfo */
055fb9ce
VA
364 platform_max = le32_to_cpu(info->value.integer.max);
365 platform_min = le32_to_cpu(info->value.integer.min);
6339d232
VA
366
367 if (platform_max == 1 &&
368 !strnstr(kcontrol->id.name, " Volume", NAME_SIZE))
369 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
370 else
371 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
372
373 uinfo->count = data->vcount;
84510052
VA
374 uinfo->value.integer.min = platform_min;
375 uinfo->value.integer.max = platform_max;
6339d232
VA
376
377 return 0;
378}
379
380static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
382{
383 int ret;
384 struct gb_audio_ctl_elem_info *info;
385 struct gbaudio_ctl_pvt *data;
386 struct gb_audio_ctl_elem_value gbvalue;
6dd67645 387 struct gbaudio_module_info *module;
6339d232
VA
388 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
389 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
390 struct snd_soc_codec *codec = widget->codec;
796fad44 391 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
6ba7fad4 392 struct gb_bundle *bundle;
6339d232 393
6dd67645
VA
394 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
395 module = find_gb_module(gb, kcontrol->id.name);
396 if (!module)
397 return -EINVAL;
3994e0b1 398
6339d232
VA
399 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
400 info = (struct gb_audio_ctl_elem_info *)data->info;
6ba7fad4 401 bundle = to_gb_bundle(module->dev);
6339d232
VA
402
403 if (data->vcount == 2)
404 dev_warn(widget->dapm->dev,
405 "GB: Control '%s' is stereo, which is not supported\n",
406 kcontrol->id.name);
407
6ba7fad4
DL
408 ret = gb_pm_runtime_get_sync(bundle);
409 if (ret)
410 return ret;
411
6dd67645 412 ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
6339d232 413 GB_AUDIO_INVALID_INDEX, &gbvalue);
6ba7fad4
DL
414
415 gb_pm_runtime_put_autosuspend(bundle);
416
6339d232 417 if (ret) {
c6722ab5
VA
418 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
419 __func__, kcontrol->id.name);
6339d232
VA
420 return ret;
421 }
422 /* update ucontrol */
055fb9ce
VA
423 ucontrol->value.integer.value[0] =
424 le32_to_cpu(gbvalue.value.integer_value[0]);
6339d232
VA
425
426 return ret;
427}
428
429static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
430 struct snd_ctl_elem_value *ucontrol)
431{
432 int ret, wi, max, connect;
433 unsigned int mask, val;
434 struct gb_audio_ctl_elem_info *info;
435 struct gbaudio_ctl_pvt *data;
436 struct gb_audio_ctl_elem_value gbvalue;
6dd67645 437 struct gbaudio_module_info *module;
6339d232
VA
438 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
439 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
440 struct snd_soc_codec *codec = widget->codec;
796fad44 441 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
6ba7fad4 442 struct gb_bundle *bundle;
6339d232 443
6dd67645
VA
444 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
445 module = find_gb_module(gb, kcontrol->id.name);
446 if (!module)
447 return -EINVAL;
3994e0b1 448
6339d232
VA
449 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
450 info = (struct gb_audio_ctl_elem_info *)data->info;
6ba7fad4 451 bundle = to_gb_bundle(module->dev);
6339d232
VA
452
453 if (data->vcount == 2)
454 dev_warn(widget->dapm->dev,
455 "GB: Control '%s' is stereo, which is not supported\n",
456 kcontrol->id.name);
457
055fb9ce 458 max = le32_to_cpu(info->value.integer.max);
6339d232 459 mask = (1 << fls(max)) - 1;
4f1cbe2a 460 val = ucontrol->value.integer.value[0] & mask;
6339d232
VA
461 connect = !!val;
462
463 /* update ucontrol */
464 if (gbvalue.value.integer_value[0] != val) {
465 for (wi = 0; wi < wlist->num_widgets; wi++) {
466 widget = wlist->widgets[wi];
467
468 widget->value = val;
469 widget->dapm->update = NULL;
470 snd_soc_dapm_mixer_update_power(widget, kcontrol,
471 connect);
472 }
473 gbvalue.value.integer_value[0] =
055fb9ce 474 cpu_to_le32(ucontrol->value.integer.value[0]);
6ba7fad4
DL
475
476 ret = gb_pm_runtime_get_sync(bundle);
477 if (ret)
478 return ret;
479
6dd67645 480 ret = gb_audio_gb_set_control(module->mgmt_connection,
6339d232
VA
481 data->ctl_id,
482 GB_AUDIO_INVALID_INDEX, &gbvalue);
6ba7fad4
DL
483
484 gb_pm_runtime_put_autosuspend(bundle);
485
6339d232 486 if (ret) {
c6722ab5
VA
487 dev_err_ratelimited(codec->dev,
488 "%d:Error in %s for %s\n", ret,
489 __func__, kcontrol->id.name);
7224a2a5 490 return ret;
6339d232
VA
491 }
492 }
493
7224a2a5 494 return 0;
6339d232
VA
495}
496
497#define SOC_DAPM_MIXER_GB(xname, kcount, data) \
498{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
499 .count = kcount, .info = gbcodec_mixer_dapm_ctl_info, \
500 .get = gbcodec_mixer_dapm_ctl_get, .put = gbcodec_mixer_dapm_ctl_put, \
501 .private_value = (unsigned long)data}
502
503static int gbcodec_event_spk(struct snd_soc_dapm_widget *w,
504 struct snd_kcontrol *k, int event)
505{
506 /* Ensure GB speaker is connected */
507
508 return 0;
509}
510
511static int gbcodec_event_hp(struct snd_soc_dapm_widget *w,
512 struct snd_kcontrol *k, int event)
513{
514 /* Ensure GB module supports jack slot */
515
516 return 0;
517}
518
519static int gbcodec_event_int_mic(struct snd_soc_dapm_widget *w,
520 struct snd_kcontrol *k, int event)
521{
522 /* Ensure GB module supports jack slot */
523
524 return 0;
525}
526
527static int gbaudio_validate_kcontrol_count(struct gb_audio_widget *w)
528{
529 int ret = 0;
530
531 switch (w->type) {
532 case snd_soc_dapm_spk:
533 case snd_soc_dapm_hp:
534 case snd_soc_dapm_mic:
535 case snd_soc_dapm_output:
536 case snd_soc_dapm_input:
537 if (w->ncontrols)
538 ret = -EINVAL;
539 break;
540 case snd_soc_dapm_switch:
541 case snd_soc_dapm_mux:
542 if (w->ncontrols != 1)
543 ret = -EINVAL;
544 break;
545 default:
546 break;
547 }
548
549 return ret;
550}
551
e65579e3
VA
552static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol,
553 struct snd_ctl_elem_value *ucontrol)
554{
555 int ret, ctl_id;
556 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
557 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
558 struct gb_audio_ctl_elem_value gbvalue;
559 struct gbaudio_module_info *module;
560 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
9d3717f7 561 struct gb_bundle *bundle;
e65579e3
VA
562
563 module = find_gb_module(gb, kcontrol->id.name);
564 if (!module)
565 return -EINVAL;
566
567 ctl_id = gbaudio_map_controlname(module, kcontrol->id.name);
568 if (ctl_id < 0)
569 return -EINVAL;
570
9d3717f7
DL
571 bundle = to_gb_bundle(module->dev);
572
573 ret = gb_pm_runtime_get_sync(bundle);
574 if (ret)
575 return ret;
576
e65579e3
VA
577 ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
578 GB_AUDIO_INVALID_INDEX, &gbvalue);
9d3717f7
DL
579
580 gb_pm_runtime_put_autosuspend(bundle);
581
e65579e3
VA
582 if (ret) {
583 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
584 __func__, kcontrol->id.name);
585 return ret;
586 }
587
055fb9ce
VA
588 ucontrol->value.enumerated.item[0] =
589 le32_to_cpu(gbvalue.value.enumerated_item[0]);
e65579e3
VA
590 if (e->shift_l != e->shift_r)
591 ucontrol->value.enumerated.item[1] =
055fb9ce 592 le32_to_cpu(gbvalue.value.enumerated_item[1]);
e65579e3
VA
593
594 return 0;
595}
596
597static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol,
598 struct snd_ctl_elem_value *ucontrol)
599{
600 int ret, ctl_id;
601 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
602 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
603 struct gb_audio_ctl_elem_value gbvalue;
604 struct gbaudio_module_info *module;
605 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
9d3717f7 606 struct gb_bundle *bundle;
e65579e3
VA
607
608 module = find_gb_module(gb, kcontrol->id.name);
609 if (!module)
610 return -EINVAL;
611
612 ctl_id = gbaudio_map_controlname(module, kcontrol->id.name);
613 if (ctl_id < 0)
614 return -EINVAL;
615
616 if (ucontrol->value.enumerated.item[0] > e->max - 1)
617 return -EINVAL;
055fb9ce
VA
618 gbvalue.value.enumerated_item[0] =
619 cpu_to_le32(ucontrol->value.enumerated.item[0]);
e65579e3
VA
620
621 if (e->shift_l != e->shift_r) {
622 if (ucontrol->value.enumerated.item[1] > e->max - 1)
623 return -EINVAL;
624 gbvalue.value.enumerated_item[1] =
055fb9ce 625 cpu_to_le32(ucontrol->value.enumerated.item[1]);
e65579e3
VA
626 }
627
9d3717f7
DL
628 bundle = to_gb_bundle(module->dev);
629
630 ret = gb_pm_runtime_get_sync(bundle);
631 if (ret)
632 return ret;
633
e65579e3
VA
634 ret = gb_audio_gb_set_control(module->mgmt_connection, ctl_id,
635 GB_AUDIO_INVALID_INDEX, &gbvalue);
9d3717f7
DL
636
637 gb_pm_runtime_put_autosuspend(bundle);
638
e65579e3
VA
639 if (ret) {
640 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
641 __func__, kcontrol->id.name);
642 }
643
644 return ret;
645}
646
647static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb,
648 struct snd_kcontrol_new *kctl,
649 struct gb_audio_control *ctl)
650{
651 struct soc_enum *gbe;
652 struct gb_audio_enumerated *gb_enum;
653 int i;
654
655 gbe = devm_kzalloc(gb->dev, sizeof(*gbe), GFP_KERNEL);
656 if (!gbe)
657 return -ENOMEM;
658
659 gb_enum = &ctl->info.value.enumerated;
660
661 /* since count=1, and reg is dummy */
055fb9ce 662 gbe->max = le32_to_cpu(gb_enum->items);
e65579e3
VA
663 gbe->texts = gb_generate_enum_strings(gb, gb_enum);
664
665 /* debug enum info */
055fb9ce
VA
666 dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max,
667 le16_to_cpu(gb_enum->names_length));
668 for (i = 0; i < gbe->max; i++)
e65579e3
VA
669 dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
670
671 *kctl = (struct snd_kcontrol_new)
672 SOC_ENUM_EXT(ctl->name, *gbe, gbcodec_enum_ctl_get,
673 gbcodec_enum_ctl_put);
674 return 0;
675}
676
6dd67645 677static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb,
6339d232
VA
678 struct snd_kcontrol_new *kctl,
679 struct gb_audio_control *ctl)
680{
e65579e3 681 int ret = 0;
6339d232
VA
682 struct gbaudio_ctl_pvt *ctldata;
683
684 switch (ctl->iface) {
685 case SNDRV_CTL_ELEM_IFACE_MIXER:
e65579e3
VA
686 switch (ctl->info.type) {
687 case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
688 ret = gbaudio_tplg_create_enum_kctl(gb, kctl, ctl);
689 break;
690 default:
691 ctldata = devm_kzalloc(gb->dev,
692 sizeof(struct gbaudio_ctl_pvt),
693 GFP_KERNEL);
694 if (!ctldata)
695 return -ENOMEM;
696 ctldata->ctl_id = ctl->id;
055fb9ce 697 ctldata->data_cport = le16_to_cpu(ctl->data_cport);
e65579e3
VA
698 ctldata->access = ctl->access;
699 ctldata->vcount = ctl->count_values;
700 ctldata->info = &ctl->info;
701 *kctl = (struct snd_kcontrol_new)
702 SOC_MIXER_GB(ctl->name, ctl->count, ctldata);
703 ctldata = NULL;
704 break;
705 }
6339d232
VA
706 break;
707 default:
708 return -EINVAL;
709 }
710
711 dev_dbg(gb->dev, "%s:%d control created\n", ctl->name, ctl->id);
e65579e3
VA
712 return ret;
713}
714
715static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol *kcontrol,
716 struct snd_ctl_elem_value *ucontrol)
717{
718 int ret, ctl_id;
719 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
720 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
721 struct gbaudio_module_info *module;
722 struct gb_audio_ctl_elem_value gbvalue;
723 struct snd_soc_codec *codec = widget->codec;
724 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
725 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
9d3717f7 726 struct gb_bundle *bundle;
e65579e3
VA
727
728 module = find_gb_module(gb, kcontrol->id.name);
729 if (!module)
730 return -EINVAL;
731
732 ctl_id = gbaudio_map_wcontrolname(module, kcontrol->id.name);
733 if (ctl_id < 0)
734 return -EINVAL;
735
9d3717f7
DL
736 bundle = to_gb_bundle(module->dev);
737
738 ret = gb_pm_runtime_get_sync(bundle);
739 if (ret)
740 return ret;
741
e65579e3
VA
742 ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
743 GB_AUDIO_INVALID_INDEX, &gbvalue);
9d3717f7
DL
744
745 gb_pm_runtime_put_autosuspend(bundle);
746
e65579e3
VA
747 if (ret) {
748 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
749 __func__, kcontrol->id.name);
750 return ret;
751 }
752
753 ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0];
754 if (e->shift_l != e->shift_r)
755 ucontrol->value.enumerated.item[1] =
756 gbvalue.value.enumerated_item[1];
757
6339d232
VA
758 return 0;
759}
760
e65579e3
VA
761static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol,
762 struct snd_ctl_elem_value *ucontrol)
763{
764 int ret, wi, ctl_id;
765 unsigned int val, mux, change;
766 unsigned int mask;
767 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
768 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
769 struct gb_audio_ctl_elem_value gbvalue;
770 struct gbaudio_module_info *module;
771 struct snd_soc_codec *codec = widget->codec;
772 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
773 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
9d3717f7 774 struct gb_bundle *bundle;
e65579e3
VA
775
776 if (ucontrol->value.enumerated.item[0] > e->max - 1)
777 return -EINVAL;
778
779 module = find_gb_module(gb, kcontrol->id.name);
780 if (!module)
781 return -EINVAL;
782
783 ctl_id = gbaudio_map_wcontrolname(module, kcontrol->id.name);
784 if (ctl_id < 0)
785 return -EINVAL;
786
787 change = 0;
9d3717f7
DL
788 bundle = to_gb_bundle(module->dev);
789
790 ret = gb_pm_runtime_get_sync(bundle);
791 if (ret)
792 return ret;
793
e65579e3
VA
794 ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
795 GB_AUDIO_INVALID_INDEX, &gbvalue);
9d3717f7
DL
796
797 gb_pm_runtime_put_autosuspend(bundle);
798
e65579e3
VA
799 if (ret) {
800 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
801 __func__, kcontrol->id.name);
802 return ret;
803 }
6339d232 804
e65579e3
VA
805 mux = ucontrol->value.enumerated.item[0];
806 val = mux << e->shift_l;
807 mask = e->mask << e->shift_l;
6339d232 808
e65579e3
VA
809 if (gbvalue.value.enumerated_item[0] !=
810 ucontrol->value.enumerated.item[0]) {
811 change = 1;
812 gbvalue.value.enumerated_item[0] =
813 ucontrol->value.enumerated.item[0];
814 }
815
816 if (e->shift_l != e->shift_r) {
817 if (ucontrol->value.enumerated.item[1] > e->max - 1)
818 return -EINVAL;
819 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
820 mask |= e->mask << e->shift_r;
821 if (gbvalue.value.enumerated_item[1] !=
822 ucontrol->value.enumerated.item[1]) {
823 change = 1;
824 gbvalue.value.enumerated_item[1] =
825 ucontrol->value.enumerated.item[1];
826 }
827 }
828
829 if (change) {
9d3717f7
DL
830 ret = gb_pm_runtime_get_sync(bundle);
831 if (ret)
832 return ret;
833
e65579e3
VA
834 ret = gb_audio_gb_set_control(module->mgmt_connection, ctl_id,
835 GB_AUDIO_INVALID_INDEX, &gbvalue);
9d3717f7
DL
836
837 gb_pm_runtime_put_autosuspend(bundle);
838
e65579e3
VA
839 if (ret) {
840 dev_err_ratelimited(codec->dev,
841 "%d:Error in %s for %s\n", ret,
842 __func__, kcontrol->id.name);
843 }
844 for (wi = 0; wi < wlist->num_widgets; wi++) {
845 widget = wlist->widgets[wi];
846
847 widget->value = val;
848 widget->dapm->update = NULL;
849 snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
850 }
851 }
852
853 return change;
854}
6339d232 855
6dd67645 856static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb,
6339d232
VA
857 struct snd_kcontrol_new *kctl,
858 struct gb_audio_control *ctl)
859{
e65579e3
VA
860 struct soc_enum *gbe;
861 struct gb_audio_enumerated *gb_enum;
862 int i;
863
864 gbe = devm_kzalloc(gb->dev, sizeof(*gbe), GFP_KERNEL);
865 if (!gbe)
866 return -ENOMEM;
6339d232 867
e65579e3
VA
868 gb_enum = &ctl->info.value.enumerated;
869
870 /* since count=1, and reg is dummy */
055fb9ce 871 gbe->max = le32_to_cpu(gb_enum->items);
e65579e3
VA
872 gbe->texts = gb_generate_enum_strings(gb, gb_enum);
873
874 /* debug enum info */
055fb9ce
VA
875 dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max,
876 le16_to_cpu(gb_enum->names_length));
877 for (i = 0; i < gbe->max; i++)
e65579e3
VA
878 dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
879
880 *kctl = (struct snd_kcontrol_new)
881 SOC_DAPM_ENUM_EXT(ctl->name, *gbe, gbcodec_enum_dapm_ctl_get,
882 gbcodec_enum_dapm_ctl_put);
6339d232
VA
883 return 0;
884}
885
6dd67645 886static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb,
6339d232
VA
887 struct snd_kcontrol_new *kctl,
888 struct gb_audio_control *ctl)
889{
890 struct gbaudio_ctl_pvt *ctldata;
891
892 ctldata = devm_kzalloc(gb->dev, sizeof(struct gbaudio_ctl_pvt),
893 GFP_KERNEL);
894 if (!ctldata)
895 return -ENOMEM;
896 ctldata->ctl_id = ctl->id;
055fb9ce 897 ctldata->data_cport = le16_to_cpu(ctl->data_cport);
6339d232
VA
898 ctldata->access = ctl->access;
899 ctldata->vcount = ctl->count_values;
900 ctldata->info = &ctl->info;
901 *kctl = (struct snd_kcontrol_new)
902 SOC_DAPM_MIXER_GB(ctl->name, ctl->count, ctldata);
903
904 return 0;
905}
906
6dd67645 907static int gbaudio_tplg_create_wcontrol(struct gbaudio_module_info *gb,
6339d232
VA
908 struct snd_kcontrol_new *kctl,
909 struct gb_audio_control *ctl)
910{
911 int ret;
912
913 switch (ctl->iface) {
914 case SNDRV_CTL_ELEM_IFACE_MIXER:
915 switch (ctl->info.type) {
916 case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
917 ret = gbaudio_tplg_create_enum_ctl(gb, kctl, ctl);
918 break;
919 default:
920 ret = gbaudio_tplg_create_mixer_ctl(gb, kctl, ctl);
921 break;
922 }
923 break;
924 default:
925 return -EINVAL;
926
927 }
928
929 dev_dbg(gb->dev, "%s:%d DAPM control created, ret:%d\n", ctl->name,
930 ctl->id, ret);
931 return ret;
932}
933
934static int gbaudio_widget_event(struct snd_soc_dapm_widget *w,
935 struct snd_kcontrol *kcontrol, int event)
936{
937 int wid;
938 int ret;
939 struct snd_soc_codec *codec = w->codec;
796fad44 940 struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec);
6dd67645 941 struct gbaudio_module_info *module;
6ba7fad4 942 struct gb_bundle *bundle;
6339d232
VA
943
944 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
945
6dd67645
VA
946 /* Find relevant module */
947 module = find_gb_module(gbcodec, w->name);
948 if (!module)
949 return -EINVAL;
950
6339d232 951 /* map name to widget id */
6dd67645 952 wid = gbaudio_map_widgetname(module, w->name);
6339d232
VA
953 if (wid < 0) {
954 dev_err(codec->dev, "Invalid widget name:%s\n", w->name);
955 return -EINVAL;
956 }
957
6ba7fad4
DL
958 bundle = to_gb_bundle(module->dev);
959
960 ret = gb_pm_runtime_get_sync(bundle);
961 if (ret)
962 return ret;
963
6339d232
VA
964 switch (event) {
965 case SND_SOC_DAPM_PRE_PMU:
6dd67645
VA
966 ret = gb_audio_gb_enable_widget(module->mgmt_connection, wid);
967 if (!ret)
4ffca62a 968 ret = gbaudio_module_update(gbcodec, w, module, 1);
6339d232
VA
969 break;
970 case SND_SOC_DAPM_POST_PMD:
6dd67645
VA
971 ret = gb_audio_gb_disable_widget(module->mgmt_connection, wid);
972 if (!ret)
4ffca62a 973 ret = gbaudio_module_update(gbcodec, w, module, 0);
6339d232
VA
974 break;
975 }
976 if (ret)
c6722ab5
VA
977 dev_err_ratelimited(codec->dev,
978 "%d: widget, event:%d failed:%d\n", wid,
979 event, ret);
6ba7fad4
DL
980
981 gb_pm_runtime_put_autosuspend(bundle);
982
6339d232
VA
983 return ret;
984}
985
6dd67645 986static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module,
6339d232 987 struct snd_soc_dapm_widget *dw,
d4cd9daa 988 struct gb_audio_widget *w, int *w_size)
6339d232 989{
d4cd9daa 990 int i, ret, csize;
6339d232
VA
991 struct snd_kcontrol_new *widget_kctls;
992 struct gb_audio_control *curr;
993 struct gbaudio_control *control, *_control;
994 size_t size;
6dd67645 995 char temp_name[NAME_SIZE];
6339d232
VA
996
997 ret = gbaudio_validate_kcontrol_count(w);
998 if (ret) {
ac5d6d86 999 dev_err(module->dev, "Invalid kcontrol count=%d for %s\n",
6339d232
VA
1000 w->ncontrols, w->name);
1001 return ret;
1002 }
1003
1004 /* allocate memory for kcontrol */
1005 if (w->ncontrols) {
1006 size = sizeof(struct snd_kcontrol_new) * w->ncontrols;
6dd67645 1007 widget_kctls = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
1008 if (!widget_kctls)
1009 return -ENOMEM;
1010 }
1011
d4cd9daa
VA
1012 *w_size = sizeof(struct gb_audio_widget);
1013
6339d232 1014 /* create relevant kcontrols */
d4cd9daa 1015 curr = w->ctl;
6339d232 1016 for (i = 0; i < w->ncontrols; i++) {
6dd67645 1017 ret = gbaudio_tplg_create_wcontrol(module, &widget_kctls[i],
6339d232
VA
1018 curr);
1019 if (ret) {
6dd67645 1020 dev_err(module->dev,
6339d232
VA
1021 "%s:%d type widget_ctl not supported\n",
1022 curr->name, curr->iface);
1023 goto error;
1024 }
6dd67645 1025 control = devm_kzalloc(module->dev,
6339d232
VA
1026 sizeof(struct gbaudio_control),
1027 GFP_KERNEL);
1028 if (!control) {
1029 ret = -ENOMEM;
1030 goto error;
1031 }
1032 control->id = curr->id;
1033 control->name = curr->name;
0c15a9e0
VA
1034 control->wname = w->name;
1035
e65579e3
VA
1036 if (curr->info.type == GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED) {
1037 struct gb_audio_enumerated *gbenum =
1038 &curr->info.value.enumerated;
1039
1040 csize = offsetof(struct gb_audio_control, info);
1041 csize += offsetof(struct gb_audio_ctl_elem_info, value);
1042 csize += offsetof(struct gb_audio_enumerated, names);
055fb9ce 1043 csize += le16_to_cpu(gbenum->names_length);
6339d232 1044 control->texts = (const char * const *)
e65579e3 1045 gb_generate_enum_strings(module, gbenum);
055fb9ce 1046 control->items = le32_to_cpu(gbenum->items);
02ae32f7 1047 } else {
e65579e3 1048 csize = sizeof(struct gb_audio_control);
02ae32f7
CM
1049 }
1050
d4cd9daa
VA
1051 *w_size += csize;
1052 curr = (void *)curr + csize;
6dd67645
VA
1053 list_add(&control->list, &module->widget_ctl_list);
1054 dev_dbg(module->dev, "%s: control of type %d created\n",
6339d232
VA
1055 widget_kctls[i].name, widget_kctls[i].iface);
1056 }
1057
6dd67645
VA
1058 /* Prefix dev_id to widget control_name */
1059 strlcpy(temp_name, w->name, NAME_SIZE);
1060 snprintf(w->name, NAME_SIZE, "GB %d %s", module->dev_id, temp_name);
1061
6339d232
VA
1062 switch (w->type) {
1063 case snd_soc_dapm_spk:
1064 *dw = (struct snd_soc_dapm_widget)
1065 SND_SOC_DAPM_SPK(w->name, gbcodec_event_spk);
89de9a06 1066 module->op_devices |= GBAUDIO_DEVICE_OUT_SPEAKER;
6339d232
VA
1067 break;
1068 case snd_soc_dapm_hp:
1069 *dw = (struct snd_soc_dapm_widget)
1070 SND_SOC_DAPM_HP(w->name, gbcodec_event_hp);
89de9a06
VA
1071 module->op_devices |= (GBAUDIO_DEVICE_OUT_WIRED_HEADSET
1072 | GBAUDIO_DEVICE_OUT_WIRED_HEADPHONE);
1073 module->ip_devices |= GBAUDIO_DEVICE_IN_WIRED_HEADSET;
6339d232
VA
1074 break;
1075 case snd_soc_dapm_mic:
1076 *dw = (struct snd_soc_dapm_widget)
1077 SND_SOC_DAPM_MIC(w->name, gbcodec_event_int_mic);
89de9a06 1078 module->ip_devices |= GBAUDIO_DEVICE_IN_BUILTIN_MIC;
6339d232
VA
1079 break;
1080 case snd_soc_dapm_output:
1081 *dw = (struct snd_soc_dapm_widget)SND_SOC_DAPM_OUTPUT(w->name);
1082 break;
1083 case snd_soc_dapm_input:
1084 *dw = (struct snd_soc_dapm_widget)SND_SOC_DAPM_INPUT(w->name);
1085 break;
1086 case snd_soc_dapm_switch:
1087 *dw = (struct snd_soc_dapm_widget)
1088 SND_SOC_DAPM_SWITCH_E(w->name, SND_SOC_NOPM, 0, 0,
1089 widget_kctls, gbaudio_widget_event,
1090 SND_SOC_DAPM_PRE_PMU |
1091 SND_SOC_DAPM_POST_PMD);
1092 break;
1093 case snd_soc_dapm_pga:
1094 *dw = (struct snd_soc_dapm_widget)
1095 SND_SOC_DAPM_PGA_E(w->name, SND_SOC_NOPM, 0, 0, NULL, 0,
1096 gbaudio_widget_event,
1097 SND_SOC_DAPM_PRE_PMU |
1098 SND_SOC_DAPM_POST_PMD);
1099 break;
1100 case snd_soc_dapm_mixer:
1101 *dw = (struct snd_soc_dapm_widget)
1102 SND_SOC_DAPM_MIXER_E(w->name, SND_SOC_NOPM, 0, 0, NULL,
1103 0, gbaudio_widget_event,
1104 SND_SOC_DAPM_PRE_PMU |
1105 SND_SOC_DAPM_POST_PMD);
1106 break;
1107 case snd_soc_dapm_mux:
1108 *dw = (struct snd_soc_dapm_widget)
1109 SND_SOC_DAPM_MUX_E(w->name, SND_SOC_NOPM, 0, 0,
1110 widget_kctls, gbaudio_widget_event,
1111 SND_SOC_DAPM_PRE_PMU |
1112 SND_SOC_DAPM_POST_PMD);
1113 break;
1114 case snd_soc_dapm_aif_in:
1115 *dw = (struct snd_soc_dapm_widget)
1116 SND_SOC_DAPM_AIF_IN_E(w->name, w->sname, 0,
1117 SND_SOC_NOPM,
1118 0, 0, gbaudio_widget_event,
1119 SND_SOC_DAPM_PRE_PMU |
1120 SND_SOC_DAPM_POST_PMD);
1121 break;
1122 case snd_soc_dapm_aif_out:
1123 *dw = (struct snd_soc_dapm_widget)
1124 SND_SOC_DAPM_AIF_OUT_E(w->name, w->sname, 0,
1125 SND_SOC_NOPM,
1126 0, 0, gbaudio_widget_event,
1127 SND_SOC_DAPM_PRE_PMU |
1128 SND_SOC_DAPM_POST_PMD);
1129 break;
1130 default:
1131 ret = -EINVAL;
1132 goto error;
1133 }
1134
6dd67645 1135 dev_dbg(module->dev, "%s: widget of type %d created\n", dw->name,
6339d232
VA
1136 dw->id);
1137 return 0;
1138error:
6dd67645 1139 list_for_each_entry_safe(control, _control, &module->widget_ctl_list,
6339d232
VA
1140 list) {
1141 list_del(&control->list);
6dd67645 1142 devm_kfree(module->dev, control);
6339d232
VA
1143 }
1144 return ret;
1145}
1146
6dd67645 1147static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module,
6339d232
VA
1148 struct gb_audio_control *controls)
1149{
d4cd9daa 1150 int i, csize, ret;
6339d232
VA
1151 struct snd_kcontrol_new *dapm_kctls;
1152 struct gb_audio_control *curr;
1153 struct gbaudio_control *control, *_control;
1154 size_t size;
6dd67645 1155 char temp_name[NAME_SIZE];
6339d232 1156
6dd67645
VA
1157 size = sizeof(struct snd_kcontrol_new) * module->num_controls;
1158 dapm_kctls = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
1159 if (!dapm_kctls)
1160 return -ENOMEM;
1161
1162 curr = controls;
6dd67645
VA
1163 for (i = 0; i < module->num_controls; i++) {
1164 ret = gbaudio_tplg_create_kcontrol(module, &dapm_kctls[i],
6339d232
VA
1165 curr);
1166 if (ret) {
6dd67645 1167 dev_err(module->dev, "%s:%d type not supported\n",
6339d232
VA
1168 curr->name, curr->iface);
1169 goto error;
1170 }
6dd67645 1171 control = devm_kzalloc(module->dev, sizeof(struct
6339d232
VA
1172 gbaudio_control),
1173 GFP_KERNEL);
1174 if (!control) {
1175 ret = -ENOMEM;
1176 goto error;
1177 }
1178 control->id = curr->id;
6dd67645
VA
1179 /* Prefix dev_id to widget_name */
1180 strlcpy(temp_name, curr->name, NAME_SIZE);
1181 snprintf(curr->name, NAME_SIZE, "GB %d %s", module->dev_id,
1182 temp_name);
6339d232 1183 control->name = curr->name;
e65579e3
VA
1184 if (curr->info.type == GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED) {
1185 struct gb_audio_enumerated *gbenum =
1186 &curr->info.value.enumerated;
1187
1188 csize = offsetof(struct gb_audio_control, info);
1189 csize += offsetof(struct gb_audio_ctl_elem_info, value);
1190 csize += offsetof(struct gb_audio_enumerated, names);
055fb9ce 1191 csize += le16_to_cpu(gbenum->names_length);
6339d232 1192 control->texts = (const char * const *)
e65579e3 1193 gb_generate_enum_strings(module, gbenum);
055fb9ce 1194 control->items = le32_to_cpu(gbenum->items);
02ae32f7 1195 } else {
e65579e3 1196 csize = sizeof(struct gb_audio_control);
02ae32f7 1197 }
d4cd9daa 1198
6dd67645
VA
1199 list_add(&control->list, &module->ctl_list);
1200 dev_dbg(module->dev, "%d:%s created of type %d\n", curr->id,
6339d232 1201 curr->name, curr->info.type);
d4cd9daa 1202 curr = (void *)curr + csize;
6339d232 1203 }
6dd67645 1204 module->controls = dapm_kctls;
6339d232
VA
1205
1206 return 0;
1207error:
6dd67645 1208 list_for_each_entry_safe(control, _control, &module->ctl_list,
6339d232
VA
1209 list) {
1210 list_del(&control->list);
6dd67645 1211 devm_kfree(module->dev, control);
6339d232 1212 }
6dd67645 1213 devm_kfree(module->dev, dapm_kctls);
6339d232
VA
1214 return ret;
1215}
1216
6dd67645 1217static int gbaudio_tplg_process_widgets(struct gbaudio_module_info *module,
6339d232
VA
1218 struct gb_audio_widget *widgets)
1219{
d4cd9daa 1220 int i, ret, w_size;
6339d232
VA
1221 struct snd_soc_dapm_widget *dapm_widgets;
1222 struct gb_audio_widget *curr;
1223 struct gbaudio_widget *widget, *_widget;
1224 size_t size;
1225
6dd67645
VA
1226 size = sizeof(struct snd_soc_dapm_widget) * module->num_dapm_widgets;
1227 dapm_widgets = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
1228 if (!dapm_widgets)
1229 return -ENOMEM;
1230
1231 curr = widgets;
6dd67645
VA
1232 for (i = 0; i < module->num_dapm_widgets; i++) {
1233 ret = gbaudio_tplg_create_widget(module, &dapm_widgets[i],
d4cd9daa 1234 curr, &w_size);
6339d232 1235 if (ret) {
6dd67645 1236 dev_err(module->dev, "%s:%d type not supported\n",
6339d232
VA
1237 curr->name, curr->type);
1238 goto error;
1239 }
6dd67645 1240 widget = devm_kzalloc(module->dev, sizeof(struct
6339d232
VA
1241 gbaudio_widget),
1242 GFP_KERNEL);
1243 if (!widget) {
1244 ret = -ENOMEM;
1245 goto error;
1246 }
1247 widget->id = curr->id;
1248 widget->name = curr->name;
6dd67645 1249 list_add(&widget->list, &module->widget_list);
d4cd9daa 1250 curr = (void *)curr + w_size;
6339d232 1251 }
6dd67645 1252 module->dapm_widgets = dapm_widgets;
6339d232
VA
1253
1254 return 0;
1255
1256error:
6dd67645 1257 list_for_each_entry_safe(widget, _widget, &module->widget_list,
6339d232
VA
1258 list) {
1259 list_del(&widget->list);
6dd67645 1260 devm_kfree(module->dev, widget);
6339d232 1261 }
6dd67645 1262 devm_kfree(module->dev, dapm_widgets);
6339d232
VA
1263 return ret;
1264}
1265
6dd67645 1266static int gbaudio_tplg_process_routes(struct gbaudio_module_info *module,
6339d232
VA
1267 struct gb_audio_route *routes)
1268{
1269 int i, ret;
1270 struct snd_soc_dapm_route *dapm_routes;
1271 struct gb_audio_route *curr;
1272 size_t size;
1273
6dd67645
VA
1274 size = sizeof(struct snd_soc_dapm_route) * module->num_dapm_routes;
1275 dapm_routes = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
1276 if (!dapm_routes)
1277 return -ENOMEM;
1278
6dd67645 1279 module->dapm_routes = dapm_routes;
6339d232
VA
1280 curr = routes;
1281
6dd67645 1282 for (i = 0; i < module->num_dapm_routes; i++) {
6339d232 1283 dapm_routes->sink =
6dd67645 1284 gbaudio_map_widgetid(module, curr->destination_id);
6339d232 1285 if (!dapm_routes->sink) {
6dd67645 1286 dev_err(module->dev, "%d:%d:%d:%d - Invalid sink\n",
6339d232
VA
1287 curr->source_id, curr->destination_id,
1288 curr->control_id, curr->index);
1289 ret = -EINVAL;
1290 goto error;
1291 }
1292 dapm_routes->source =
6dd67645 1293 gbaudio_map_widgetid(module, curr->source_id);
6339d232 1294 if (!dapm_routes->source) {
6dd67645 1295 dev_err(module->dev, "%d:%d:%d:%d - Invalid source\n",
6339d232
VA
1296 curr->source_id, curr->destination_id,
1297 curr->control_id, curr->index);
1298 ret = -EINVAL;
1299 goto error;
1300 }
1301 dapm_routes->control =
6dd67645 1302 gbaudio_map_controlid(module,
6339d232
VA
1303 curr->control_id,
1304 curr->index);
1305 if ((curr->control_id != GBAUDIO_INVALID_ID) &&
1306 !dapm_routes->control) {
6dd67645 1307 dev_err(module->dev, "%d:%d:%d:%d - Invalid control\n",
6339d232
VA
1308 curr->source_id, curr->destination_id,
1309 curr->control_id, curr->index);
1310 ret = -EINVAL;
1311 goto error;
1312 }
6dd67645 1313 dev_dbg(module->dev, "Route {%s, %s, %s}\n", dapm_routes->sink,
8a983614 1314 (dapm_routes->control) ? dapm_routes->control : "NULL",
6339d232
VA
1315 dapm_routes->source);
1316 dapm_routes++;
1317 curr++;
1318 }
1319
1320 return 0;
1321
1322error:
6198f892 1323 devm_kfree(module->dev, module->dapm_routes);
6339d232
VA
1324 return ret;
1325}
1326
6dd67645 1327static int gbaudio_tplg_process_header(struct gbaudio_module_info *module,
6339d232
VA
1328 struct gb_audio_topology *tplg_data)
1329{
1330 /* fetch no. of kcontrols, widgets & routes */
6dd67645
VA
1331 module->num_controls = tplg_data->num_controls;
1332 module->num_dapm_widgets = tplg_data->num_widgets;
1333 module->num_dapm_routes = tplg_data->num_routes;
6339d232
VA
1334
1335 /* update block offset */
6dd67645 1336 module->dai_offset = (unsigned long)&tplg_data->data;
055fb9ce
VA
1337 module->control_offset = module->dai_offset +
1338 le32_to_cpu(tplg_data->size_dais);
6dd67645 1339 module->widget_offset = module->control_offset +
055fb9ce 1340 le32_to_cpu(tplg_data->size_controls);
6dd67645 1341 module->route_offset = module->widget_offset +
055fb9ce 1342 le32_to_cpu(tplg_data->size_widgets);
6339d232 1343
6dd67645
VA
1344 dev_dbg(module->dev, "DAI offset is 0x%lx\n", module->dai_offset);
1345 dev_dbg(module->dev, "control offset is %lx\n",
1346 module->control_offset);
1347 dev_dbg(module->dev, "widget offset is %lx\n", module->widget_offset);
1348 dev_dbg(module->dev, "route offset is %lx\n", module->route_offset);
6339d232
VA
1349
1350 return 0;
1351}
1352
6dd67645 1353int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
6339d232
VA
1354 struct gb_audio_topology *tplg_data)
1355{
1356 int ret;
6339d232
VA
1357 struct gb_audio_control *controls;
1358 struct gb_audio_widget *widgets;
1359 struct gb_audio_route *routes;
055fb9ce 1360 unsigned int jack_type;
6339d232
VA
1361
1362 if (!tplg_data)
1363 return -EINVAL;
1364
6dd67645 1365 ret = gbaudio_tplg_process_header(module, tplg_data);
6339d232 1366 if (ret) {
6dd67645 1367 dev_err(module->dev, "%d: Error in parsing topology header\n",
6339d232
VA
1368 ret);
1369 return ret;
1370 }
1371
1372 /* process control */
6dd67645
VA
1373 controls = (struct gb_audio_control *)module->control_offset;
1374 ret = gbaudio_tplg_process_kcontrols(module, controls);
6339d232 1375 if (ret) {
6dd67645 1376 dev_err(module->dev,
6339d232
VA
1377 "%d: Error in parsing controls data\n", ret);
1378 return ret;
1379 }
6dd67645 1380 dev_dbg(module->dev, "Control parsing finished\n");
6339d232
VA
1381
1382 /* process widgets */
6dd67645
VA
1383 widgets = (struct gb_audio_widget *)module->widget_offset;
1384 ret = gbaudio_tplg_process_widgets(module, widgets);
6339d232 1385 if (ret) {
6dd67645 1386 dev_err(module->dev,
6339d232
VA
1387 "%d: Error in parsing widgets data\n", ret);
1388 return ret;
1389 }
6dd67645 1390 dev_dbg(module->dev, "Widget parsing finished\n");
6339d232
VA
1391
1392 /* process route */
6dd67645
VA
1393 routes = (struct gb_audio_route *)module->route_offset;
1394 ret = gbaudio_tplg_process_routes(module, routes);
6339d232 1395 if (ret) {
6dd67645 1396 dev_err(module->dev,
6339d232
VA
1397 "%d: Error in parsing routes data\n", ret);
1398 return ret;
1399 }
6dd67645 1400 dev_dbg(module->dev, "Route parsing finished\n");
6339d232 1401
847175e8 1402 /* parse jack capabilities */
055fb9ce
VA
1403 jack_type = le32_to_cpu(tplg_data->jack_type);
1404 if (jack_type) {
1405 module->jack_mask = jack_type & GBCODEC_JACK_MASK;
1406 module->button_mask = jack_type & GBCODEC_JACK_BUTTON_MASK;
847175e8
VA
1407 }
1408
6339d232
VA
1409 return ret;
1410}
1411
6dd67645 1412void gbaudio_tplg_release(struct gbaudio_module_info *module)
6339d232 1413{
6339d232
VA
1414 struct gbaudio_control *control, *_control;
1415 struct gbaudio_widget *widget, *_widget;
1416
6dd67645 1417 if (!module->topology)
6339d232
VA
1418 return;
1419
1420 /* release kcontrols */
6dd67645 1421 list_for_each_entry_safe(control, _control, &module->ctl_list,
6339d232
VA
1422 list) {
1423 list_del(&control->list);
6dd67645 1424 devm_kfree(module->dev, control);
6339d232 1425 }
6dd67645
VA
1426 if (module->controls)
1427 devm_kfree(module->dev, module->controls);
6339d232
VA
1428
1429 /* release widget controls */
6dd67645 1430 list_for_each_entry_safe(control, _control, &module->widget_ctl_list,
6339d232
VA
1431 list) {
1432 list_del(&control->list);
6dd67645 1433 devm_kfree(module->dev, control);
6339d232
VA
1434 }
1435
1436 /* release widgets */
6dd67645 1437 list_for_each_entry_safe(widget, _widget, &module->widget_list,
6339d232
VA
1438 list) {
1439 list_del(&widget->list);
6dd67645 1440 devm_kfree(module->dev, widget);
6339d232 1441 }
6dd67645
VA
1442 if (module->dapm_widgets)
1443 devm_kfree(module->dev, module->dapm_widgets);
6339d232
VA
1444
1445 /* release routes */
6dd67645
VA
1446 if (module->dapm_routes)
1447 devm_kfree(module->dev, module->dapm_routes);
6339d232 1448}