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