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