staging: greybus: camera: simplify NULL test
[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;
15c726ea
VA
67 if (index >= control->items)
68 return NULL;
6339d232
VA
69 return control->texts[index];
70 }
71 }
6dd67645 72 list_for_each_entry(control, &module->widget_ctl_list, list) {
6339d232
VA
73 if (control->id == control_id) {
74 if (index == GBAUDIO_INVALID_ID)
75 return control->name;
15c726ea
VA
76 if (index >= control->items)
77 return NULL;
6339d232
VA
78 return control->texts[index];
79 }
80 }
81 return NULL;
82}
83
e65579e3
VA
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
0c15a9e0 99static int gbaudio_map_wcontrolname(struct gbaudio_module_info *module,
e65579e3 100 const char *name)
0c15a9e0
VA
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
6dd67645 113static int gbaudio_map_widgetname(struct gbaudio_module_info *module,
e65579e3 114 const char *name)
6339d232
VA
115{
116 struct gbaudio_widget *widget;
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;
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
6339d232
VA
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;
6dd67645 166 struct gbaudio_module_info *module;
6339d232 167 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
796fad44 168 struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec);
6339d232 169
6dd67645 170 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
6339d232
VA
171 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
172 info = (struct gb_audio_ctl_elem_info *)data->info;
173
174 if (!info) {
6dd67645 175 dev_err(module->dev, "NULL info for %s\n", uinfo->id.name);
6339d232
VA
176 return -EINVAL;
177 }
178
179 /* update uinfo */
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;
6dd67645
VA
195 module = find_gb_module(gbcodec, kcontrol->id.name);
196 if (!module)
197 return -EINVAL;
198 name = gbaudio_map_controlid(module, data->ctl_id,
6339d232
VA
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;
6dd67645 217 struct gbaudio_module_info *module;
6339d232 218 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
796fad44 219 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
6ba7fad4 220 struct gb_bundle *bundle;
6339d232 221
6dd67645
VA
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;
3994e0b1 226
6339d232
VA
227 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
228 info = (struct gb_audio_ctl_elem_info *)data->info;
6ba7fad4
DL
229 bundle = to_gb_bundle(module->dev);
230
231 ret = gb_pm_runtime_get_sync(bundle);
232 if (ret)
233 return ret;
6339d232 234
6dd67645 235 ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
6339d232 236 GB_AUDIO_INVALID_INDEX, &gbvalue);
6ba7fad4
DL
237
238 gb_pm_runtime_put_autosuspend(bundle);
239
6339d232 240 if (ret) {
c6722ab5
VA
241 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
242 __func__, kcontrol->id.name);
6339d232
VA
243 return ret;
244 }
245
246 /* update ucontrol */
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;
6dd67645 279 struct gbaudio_module_info *module;
6339d232 280 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
796fad44 281 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
6ba7fad4 282 struct gb_bundle *bundle;
6339d232 283
6dd67645
VA
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;
3994e0b1 288
6339d232
VA
289 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
290 info = (struct gb_audio_ctl_elem_info *)data->info;
6ba7fad4 291 bundle = to_gb_bundle(module->dev);
6339d232
VA
292
293 /* update ucontrol */
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
6ba7fad4
DL
317 if (ret)
318 return ret;
319
320 ret = gb_pm_runtime_get_sync(bundle);
6339d232
VA
321 if (ret)
322 return ret;
323
6dd67645 324 ret = gb_audio_gb_set_control(module->mgmt_connection, data->ctl_id,
6339d232 325 GB_AUDIO_INVALID_INDEX, &gbvalue);
6ba7fad4
DL
326
327 gb_pm_runtime_put_autosuspend(bundle);
328
6339d232 329 if (ret) {
c6722ab5
VA
330 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
331 __func__, kcontrol->id.name);
6339d232
VA
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 * although below callback functions seems redundant to above functions.
345 * same are kept to allow provision for different handling in case
346 * of DAPM related sequencing, etc.
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;
6dd67645
VA
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;
6339d232 357
6dd67645 358 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
6339d232
VA
359 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
360 info = (struct gb_audio_ctl_elem_info *)data->info;
361
362 /* update uinfo */
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;
6dd67645 390 struct gbaudio_module_info *module;
6339d232
VA
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;
796fad44 394 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
6ba7fad4 395 struct gb_bundle *bundle;
6339d232 396
6dd67645
VA
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;
3994e0b1 401
6339d232
VA
402 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
403 info = (struct gb_audio_ctl_elem_info *)data->info;
6ba7fad4 404 bundle = to_gb_bundle(module->dev);
6339d232
VA
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
6ba7fad4
DL
411 ret = gb_pm_runtime_get_sync(bundle);
412 if (ret)
413 return ret;
414
6dd67645 415 ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
6339d232 416 GB_AUDIO_INVALID_INDEX, &gbvalue);
6ba7fad4
DL
417
418 gb_pm_runtime_put_autosuspend(bundle);
419
6339d232 420 if (ret) {
c6722ab5
VA
421 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
422 __func__, kcontrol->id.name);
6339d232
VA
423 return ret;
424 }
425 /* update ucontrol */
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;
6dd67645 439 struct gbaudio_module_info *module;
6339d232
VA
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;
796fad44 443 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
6ba7fad4 444 struct gb_bundle *bundle;
6339d232 445
6dd67645
VA
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;
3994e0b1 450
6339d232
VA
451 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
452 info = (struct gb_audio_ctl_elem_info *)data->info;
6ba7fad4 453 bundle = to_gb_bundle(module->dev);
6339d232
VA
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 /* update ucontrol */
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];
6ba7fad4
DL
477
478 ret = gb_pm_runtime_get_sync(bundle);
479 if (ret)
480 return ret;
481
6dd67645 482 ret = gb_audio_gb_set_control(module->mgmt_connection,
6339d232
VA
483 data->ctl_id,
484 GB_AUDIO_INVALID_INDEX, &gbvalue);
6ba7fad4
DL
485
486 gb_pm_runtime_put_autosuspend(bundle);
487
6339d232 488 if (ret) {
c6722ab5
VA
489 dev_err_ratelimited(codec->dev,
490 "%d:Error in %s for %s\n", ret,
491 __func__, kcontrol->id.name);
6339d232
VA
492 }
493 }
494
495 return ret;
496}
497
498#define SOC_DAPM_MIXER_GB(xname, kcount, data) \
499{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
500 .count = kcount, .info = gbcodec_mixer_dapm_ctl_info, \
501 .get = gbcodec_mixer_dapm_ctl_get, .put = gbcodec_mixer_dapm_ctl_put, \
502 .private_value = (unsigned long)data}
503
504static int gbcodec_event_spk(struct snd_soc_dapm_widget *w,
505 struct snd_kcontrol *k, int event)
506{
507 /* Ensure GB speaker is connected */
508
509 return 0;
510}
511
512static int gbcodec_event_hp(struct snd_soc_dapm_widget *w,
513 struct snd_kcontrol *k, int event)
514{
515 /* Ensure GB module supports jack slot */
516
517 return 0;
518}
519
520static int gbcodec_event_int_mic(struct snd_soc_dapm_widget *w,
521 struct snd_kcontrol *k, int event)
522{
523 /* Ensure GB module supports jack slot */
524
525 return 0;
526}
527
528static int gbaudio_validate_kcontrol_count(struct gb_audio_widget *w)
529{
530 int ret = 0;
531
532 switch (w->type) {
533 case snd_soc_dapm_spk:
534 case snd_soc_dapm_hp:
535 case snd_soc_dapm_mic:
536 case snd_soc_dapm_output:
537 case snd_soc_dapm_input:
538 if (w->ncontrols)
539 ret = -EINVAL;
540 break;
541 case snd_soc_dapm_switch:
542 case snd_soc_dapm_mux:
543 if (w->ncontrols != 1)
544 ret = -EINVAL;
545 break;
546 default:
547 break;
548 }
549
550 return ret;
551}
552
e65579e3
VA
553static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol,
554 struct snd_ctl_elem_value *ucontrol)
555{
556 int ret, ctl_id;
557 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
558 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
559 struct gb_audio_ctl_elem_value gbvalue;
560 struct gbaudio_module_info *module;
561 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
9d3717f7 562 struct gb_bundle *bundle;
e65579e3
VA
563
564 module = find_gb_module(gb, kcontrol->id.name);
565 if (!module)
566 return -EINVAL;
567
568 ctl_id = gbaudio_map_controlname(module, kcontrol->id.name);
569 if (ctl_id < 0)
570 return -EINVAL;
571
9d3717f7
DL
572 bundle = to_gb_bundle(module->dev);
573
574 ret = gb_pm_runtime_get_sync(bundle);
575 if (ret)
576 return ret;
577
e65579e3
VA
578 ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
579 GB_AUDIO_INVALID_INDEX, &gbvalue);
9d3717f7
DL
580
581 gb_pm_runtime_put_autosuspend(bundle);
582
e65579e3
VA
583 if (ret) {
584 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
585 __func__, kcontrol->id.name);
586 return ret;
587 }
588
589 ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0];
590 if (e->shift_l != e->shift_r)
591 ucontrol->value.enumerated.item[1] =
592 gbvalue.value.enumerated_item[1];
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;
618 gbvalue.value.enumerated_item[0] = ucontrol->value.enumerated.item[0];
619
620 if (e->shift_l != e->shift_r) {
621 if (ucontrol->value.enumerated.item[1] > e->max - 1)
622 return -EINVAL;
623 gbvalue.value.enumerated_item[1] =
624 ucontrol->value.enumerated.item[1];
625 }
626
9d3717f7
DL
627 bundle = to_gb_bundle(module->dev);
628
629 ret = gb_pm_runtime_get_sync(bundle);
630 if (ret)
631 return ret;
632
e65579e3
VA
633 ret = gb_audio_gb_set_control(module->mgmt_connection, ctl_id,
634 GB_AUDIO_INVALID_INDEX, &gbvalue);
9d3717f7
DL
635
636 gb_pm_runtime_put_autosuspend(bundle);
637
e65579e3
VA
638 if (ret) {
639 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
640 __func__, kcontrol->id.name);
641 }
642
643 return ret;
644}
645
646static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb,
647 struct snd_kcontrol_new *kctl,
648 struct gb_audio_control *ctl)
649{
650 struct soc_enum *gbe;
651 struct gb_audio_enumerated *gb_enum;
652 int i;
653
654 gbe = devm_kzalloc(gb->dev, sizeof(*gbe), GFP_KERNEL);
655 if (!gbe)
656 return -ENOMEM;
657
658 gb_enum = &ctl->info.value.enumerated;
659
660 /* since count=1, and reg is dummy */
661 gbe->max = gb_enum->items;
662 gbe->texts = gb_generate_enum_strings(gb, gb_enum);
663
664 /* debug enum info */
665 dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items,
666 gb_enum->names_length);
667 for (i = 0; i < gb_enum->items; i++)
668 dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
669
670 *kctl = (struct snd_kcontrol_new)
671 SOC_ENUM_EXT(ctl->name, *gbe, gbcodec_enum_ctl_get,
672 gbcodec_enum_ctl_put);
673 return 0;
674}
675
6dd67645 676static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb,
6339d232
VA
677 struct snd_kcontrol_new *kctl,
678 struct gb_audio_control *ctl)
679{
e65579e3 680 int ret = 0;
6339d232
VA
681 struct gbaudio_ctl_pvt *ctldata;
682
683 switch (ctl->iface) {
684 case SNDRV_CTL_ELEM_IFACE_MIXER:
e65579e3
VA
685 switch (ctl->info.type) {
686 case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
687 ret = gbaudio_tplg_create_enum_kctl(gb, kctl, ctl);
688 break;
689 default:
690 ctldata = devm_kzalloc(gb->dev,
691 sizeof(struct gbaudio_ctl_pvt),
692 GFP_KERNEL);
693 if (!ctldata)
694 return -ENOMEM;
695 ctldata->ctl_id = ctl->id;
696 ctldata->data_cport = ctl->data_cport;
697 ctldata->access = ctl->access;
698 ctldata->vcount = ctl->count_values;
699 ctldata->info = &ctl->info;
700 *kctl = (struct snd_kcontrol_new)
701 SOC_MIXER_GB(ctl->name, ctl->count, ctldata);
702 ctldata = NULL;
703 break;
704 }
6339d232
VA
705 break;
706 default:
707 return -EINVAL;
708 }
709
710 dev_dbg(gb->dev, "%s:%d control created\n", ctl->name, ctl->id);
e65579e3
VA
711 return ret;
712}
713
714static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol *kcontrol,
715 struct snd_ctl_elem_value *ucontrol)
716{
717 int ret, ctl_id;
718 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
719 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
720 struct gbaudio_module_info *module;
721 struct gb_audio_ctl_elem_value gbvalue;
722 struct snd_soc_codec *codec = widget->codec;
723 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
724 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
9d3717f7 725 struct gb_bundle *bundle;
e65579e3
VA
726
727 module = find_gb_module(gb, kcontrol->id.name);
728 if (!module)
729 return -EINVAL;
730
731 ctl_id = gbaudio_map_wcontrolname(module, kcontrol->id.name);
732 if (ctl_id < 0)
733 return -EINVAL;
734
9d3717f7
DL
735 bundle = to_gb_bundle(module->dev);
736
737 ret = gb_pm_runtime_get_sync(bundle);
738 if (ret)
739 return ret;
740
e65579e3
VA
741 ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
742 GB_AUDIO_INVALID_INDEX, &gbvalue);
9d3717f7
DL
743
744 gb_pm_runtime_put_autosuspend(bundle);
745
e65579e3
VA
746 if (ret) {
747 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
748 __func__, kcontrol->id.name);
749 return ret;
750 }
751
752 ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0];
753 if (e->shift_l != e->shift_r)
754 ucontrol->value.enumerated.item[1] =
755 gbvalue.value.enumerated_item[1];
756
6339d232
VA
757 return 0;
758}
759
e65579e3
VA
760static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol,
761 struct snd_ctl_elem_value *ucontrol)
762{
763 int ret, wi, ctl_id;
764 unsigned int val, mux, change;
765 unsigned int mask;
766 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
767 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
768 struct gb_audio_ctl_elem_value gbvalue;
769 struct gbaudio_module_info *module;
770 struct snd_soc_codec *codec = widget->codec;
771 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
772 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
9d3717f7 773 struct gb_bundle *bundle;
e65579e3
VA
774
775 if (ucontrol->value.enumerated.item[0] > e->max - 1)
776 return -EINVAL;
777
778 module = find_gb_module(gb, kcontrol->id.name);
779 if (!module)
780 return -EINVAL;
781
782 ctl_id = gbaudio_map_wcontrolname(module, kcontrol->id.name);
783 if (ctl_id < 0)
784 return -EINVAL;
785
786 change = 0;
9d3717f7
DL
787 bundle = to_gb_bundle(module->dev);
788
789 ret = gb_pm_runtime_get_sync(bundle);
790 if (ret)
791 return ret;
792
e65579e3
VA
793 ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
794 GB_AUDIO_INVALID_INDEX, &gbvalue);
9d3717f7
DL
795
796 gb_pm_runtime_put_autosuspend(bundle);
797
e65579e3
VA
798 if (ret) {
799 dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
800 __func__, kcontrol->id.name);
801 return ret;
802 }
6339d232 803
e65579e3
VA
804 mux = ucontrol->value.enumerated.item[0];
805 val = mux << e->shift_l;
806 mask = e->mask << e->shift_l;
6339d232 807
e65579e3
VA
808 if (gbvalue.value.enumerated_item[0] !=
809 ucontrol->value.enumerated.item[0]) {
810 change = 1;
811 gbvalue.value.enumerated_item[0] =
812 ucontrol->value.enumerated.item[0];
813 }
814
815 if (e->shift_l != e->shift_r) {
816 if (ucontrol->value.enumerated.item[1] > e->max - 1)
817 return -EINVAL;
818 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
819 mask |= e->mask << e->shift_r;
820 if (gbvalue.value.enumerated_item[1] !=
821 ucontrol->value.enumerated.item[1]) {
822 change = 1;
823 gbvalue.value.enumerated_item[1] =
824 ucontrol->value.enumerated.item[1];
825 }
826 }
827
828 if (change) {
9d3717f7
DL
829 ret = gb_pm_runtime_get_sync(bundle);
830 if (ret)
831 return ret;
832
e65579e3
VA
833 ret = gb_audio_gb_set_control(module->mgmt_connection, ctl_id,
834 GB_AUDIO_INVALID_INDEX, &gbvalue);
9d3717f7
DL
835
836 gb_pm_runtime_put_autosuspend(bundle);
837
e65579e3
VA
838 if (ret) {
839 dev_err_ratelimited(codec->dev,
840 "%d:Error in %s for %s\n", ret,
841 __func__, kcontrol->id.name);
842 }
843 for (wi = 0; wi < wlist->num_widgets; wi++) {
844 widget = wlist->widgets[wi];
845
846 widget->value = val;
847 widget->dapm->update = NULL;
848 snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
849 }
850 }
851
852 return change;
853}
6339d232 854
6dd67645 855static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb,
6339d232
VA
856 struct snd_kcontrol_new *kctl,
857 struct gb_audio_control *ctl)
858{
e65579e3
VA
859 struct soc_enum *gbe;
860 struct gb_audio_enumerated *gb_enum;
861 int i;
862
863 gbe = devm_kzalloc(gb->dev, sizeof(*gbe), GFP_KERNEL);
864 if (!gbe)
865 return -ENOMEM;
6339d232 866
e65579e3
VA
867 gb_enum = &ctl->info.value.enumerated;
868
869 /* since count=1, and reg is dummy */
870 gbe->max = gb_enum->items;
871 gbe->texts = gb_generate_enum_strings(gb, gb_enum);
872
873 /* debug enum info */
874 dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items,
875 gb_enum->names_length);
876 for (i = 0; i < gb_enum->items; i++)
877 dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
878
879 *kctl = (struct snd_kcontrol_new)
880 SOC_DAPM_ENUM_EXT(ctl->name, *gbe, gbcodec_enum_dapm_ctl_get,
881 gbcodec_enum_dapm_ctl_put);
6339d232
VA
882 return 0;
883}
884
6dd67645 885static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb,
6339d232
VA
886 struct snd_kcontrol_new *kctl,
887 struct gb_audio_control *ctl)
888{
889 struct gbaudio_ctl_pvt *ctldata;
890
891 ctldata = devm_kzalloc(gb->dev, sizeof(struct gbaudio_ctl_pvt),
892 GFP_KERNEL);
893 if (!ctldata)
894 return -ENOMEM;
895 ctldata->ctl_id = ctl->id;
896 ctldata->data_cport = ctl->data_cport;
897 ctldata->access = ctl->access;
898 ctldata->vcount = ctl->count_values;
899 ctldata->info = &ctl->info;
900 *kctl = (struct snd_kcontrol_new)
901 SOC_DAPM_MIXER_GB(ctl->name, ctl->count, ctldata);
902
903 return 0;
904}
905
6dd67645 906static int gbaudio_tplg_create_wcontrol(struct gbaudio_module_info *gb,
6339d232
VA
907 struct snd_kcontrol_new *kctl,
908 struct gb_audio_control *ctl)
909{
910 int ret;
911
912 switch (ctl->iface) {
913 case SNDRV_CTL_ELEM_IFACE_MIXER:
914 switch (ctl->info.type) {
915 case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
916 ret = gbaudio_tplg_create_enum_ctl(gb, kctl, ctl);
917 break;
918 default:
919 ret = gbaudio_tplg_create_mixer_ctl(gb, kctl, ctl);
920 break;
921 }
922 break;
923 default:
924 return -EINVAL;
925
926 }
927
928 dev_dbg(gb->dev, "%s:%d DAPM control created, ret:%d\n", ctl->name,
929 ctl->id, ret);
930 return ret;
931}
932
933static int gbaudio_widget_event(struct snd_soc_dapm_widget *w,
934 struct snd_kcontrol *kcontrol, int event)
935{
936 int wid;
937 int ret;
938 struct snd_soc_codec *codec = w->codec;
796fad44 939 struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec);
6dd67645 940 struct gbaudio_module_info *module;
6ba7fad4 941 struct gb_bundle *bundle;
6339d232
VA
942
943 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
944
6dd67645
VA
945 /* Find relevant module */
946 module = find_gb_module(gbcodec, w->name);
947 if (!module)
948 return -EINVAL;
949
6339d232 950 /* map name to widget id */
6dd67645 951 wid = gbaudio_map_widgetname(module, w->name);
6339d232
VA
952 if (wid < 0) {
953 dev_err(codec->dev, "Invalid widget name:%s\n", w->name);
954 return -EINVAL;
955 }
956
6ba7fad4
DL
957 bundle = to_gb_bundle(module->dev);
958
959 ret = gb_pm_runtime_get_sync(bundle);
960 if (ret)
961 return ret;
962
6339d232
VA
963 switch (event) {
964 case SND_SOC_DAPM_PRE_PMU:
6dd67645
VA
965 ret = gb_audio_gb_enable_widget(module->mgmt_connection, wid);
966 if (!ret)
4ffca62a 967 ret = gbaudio_module_update(gbcodec, w, module, 1);
6339d232
VA
968 break;
969 case SND_SOC_DAPM_POST_PMD:
6dd67645
VA
970 ret = gb_audio_gb_disable_widget(module->mgmt_connection, wid);
971 if (!ret)
4ffca62a 972 ret = gbaudio_module_update(gbcodec, w, module, 0);
6339d232
VA
973 break;
974 }
975 if (ret)
c6722ab5
VA
976 dev_err_ratelimited(codec->dev,
977 "%d: widget, event:%d failed:%d\n", wid,
978 event, ret);
6ba7fad4
DL
979
980 gb_pm_runtime_put_autosuspend(bundle);
981
6339d232
VA
982 return ret;
983}
984
6dd67645 985static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module,
6339d232 986 struct snd_soc_dapm_widget *dw,
d4cd9daa 987 struct gb_audio_widget *w, int *w_size)
6339d232 988{
d4cd9daa 989 int i, ret, csize;
6339d232
VA
990 struct snd_kcontrol_new *widget_kctls;
991 struct gb_audio_control *curr;
992 struct gbaudio_control *control, *_control;
993 size_t size;
6dd67645 994 char temp_name[NAME_SIZE];
6339d232
VA
995
996 ret = gbaudio_validate_kcontrol_count(w);
997 if (ret) {
6dd67645 998 dev_err(module->dev, "Inavlid kcontrol count=%d for %s\n",
6339d232
VA
999 w->ncontrols, w->name);
1000 return ret;
1001 }
1002
1003 /* allocate memory for kcontrol */
1004 if (w->ncontrols) {
1005 size = sizeof(struct snd_kcontrol_new) * w->ncontrols;
6dd67645 1006 widget_kctls = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
1007 if (!widget_kctls)
1008 return -ENOMEM;
1009 }
1010
d4cd9daa
VA
1011 *w_size = sizeof(struct gb_audio_widget);
1012
6339d232 1013 /* create relevant kcontrols */
d4cd9daa 1014 curr = w->ctl;
6339d232 1015 for (i = 0; i < w->ncontrols; i++) {
6dd67645 1016 ret = gbaudio_tplg_create_wcontrol(module, &widget_kctls[i],
6339d232
VA
1017 curr);
1018 if (ret) {
6dd67645 1019 dev_err(module->dev,
6339d232
VA
1020 "%s:%d type widget_ctl not supported\n",
1021 curr->name, curr->iface);
1022 goto error;
1023 }
6dd67645 1024 control = devm_kzalloc(module->dev,
6339d232
VA
1025 sizeof(struct gbaudio_control),
1026 GFP_KERNEL);
1027 if (!control) {
1028 ret = -ENOMEM;
1029 goto error;
1030 }
1031 control->id = curr->id;
1032 control->name = curr->name;
0c15a9e0
VA
1033 control->wname = w->name;
1034
e65579e3
VA
1035 if (curr->info.type == GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED) {
1036 struct gb_audio_enumerated *gbenum =
1037 &curr->info.value.enumerated;
1038
1039 csize = offsetof(struct gb_audio_control, info);
1040 csize += offsetof(struct gb_audio_ctl_elem_info, value);
1041 csize += offsetof(struct gb_audio_enumerated, names);
1042 csize += gbenum->names_length;
6339d232 1043 control->texts = (const char * const *)
e65579e3 1044 gb_generate_enum_strings(module, gbenum);
15c726ea 1045 control->items = gbenum->items;
e65579e3
VA
1046 } else
1047 csize = sizeof(struct gb_audio_control);
d4cd9daa
VA
1048 *w_size += csize;
1049 curr = (void *)curr + csize;
6dd67645
VA
1050 list_add(&control->list, &module->widget_ctl_list);
1051 dev_dbg(module->dev, "%s: control of type %d created\n",
6339d232
VA
1052 widget_kctls[i].name, widget_kctls[i].iface);
1053 }
1054
6dd67645
VA
1055 /* Prefix dev_id to widget control_name */
1056 strlcpy(temp_name, w->name, NAME_SIZE);
1057 snprintf(w->name, NAME_SIZE, "GB %d %s", module->dev_id, temp_name);
1058
6339d232
VA
1059 switch (w->type) {
1060 case snd_soc_dapm_spk:
1061 *dw = (struct snd_soc_dapm_widget)
1062 SND_SOC_DAPM_SPK(w->name, gbcodec_event_spk);
89de9a06 1063 module->op_devices |= GBAUDIO_DEVICE_OUT_SPEAKER;
6339d232
VA
1064 break;
1065 case snd_soc_dapm_hp:
1066 *dw = (struct snd_soc_dapm_widget)
1067 SND_SOC_DAPM_HP(w->name, gbcodec_event_hp);
89de9a06
VA
1068 module->op_devices |= (GBAUDIO_DEVICE_OUT_WIRED_HEADSET
1069 | GBAUDIO_DEVICE_OUT_WIRED_HEADPHONE);
1070 module->ip_devices |= GBAUDIO_DEVICE_IN_WIRED_HEADSET;
6339d232
VA
1071 break;
1072 case snd_soc_dapm_mic:
1073 *dw = (struct snd_soc_dapm_widget)
1074 SND_SOC_DAPM_MIC(w->name, gbcodec_event_int_mic);
89de9a06 1075 module->ip_devices |= GBAUDIO_DEVICE_IN_BUILTIN_MIC;
6339d232
VA
1076 break;
1077 case snd_soc_dapm_output:
1078 *dw = (struct snd_soc_dapm_widget)SND_SOC_DAPM_OUTPUT(w->name);
1079 break;
1080 case snd_soc_dapm_input:
1081 *dw = (struct snd_soc_dapm_widget)SND_SOC_DAPM_INPUT(w->name);
1082 break;
1083 case snd_soc_dapm_switch:
1084 *dw = (struct snd_soc_dapm_widget)
1085 SND_SOC_DAPM_SWITCH_E(w->name, SND_SOC_NOPM, 0, 0,
1086 widget_kctls, gbaudio_widget_event,
1087 SND_SOC_DAPM_PRE_PMU |
1088 SND_SOC_DAPM_POST_PMD);
1089 break;
1090 case snd_soc_dapm_pga:
1091 *dw = (struct snd_soc_dapm_widget)
1092 SND_SOC_DAPM_PGA_E(w->name, SND_SOC_NOPM, 0, 0, NULL, 0,
1093 gbaudio_widget_event,
1094 SND_SOC_DAPM_PRE_PMU |
1095 SND_SOC_DAPM_POST_PMD);
1096 break;
1097 case snd_soc_dapm_mixer:
1098 *dw = (struct snd_soc_dapm_widget)
1099 SND_SOC_DAPM_MIXER_E(w->name, SND_SOC_NOPM, 0, 0, NULL,
1100 0, gbaudio_widget_event,
1101 SND_SOC_DAPM_PRE_PMU |
1102 SND_SOC_DAPM_POST_PMD);
1103 break;
1104 case snd_soc_dapm_mux:
1105 *dw = (struct snd_soc_dapm_widget)
1106 SND_SOC_DAPM_MUX_E(w->name, SND_SOC_NOPM, 0, 0,
1107 widget_kctls, gbaudio_widget_event,
1108 SND_SOC_DAPM_PRE_PMU |
1109 SND_SOC_DAPM_POST_PMD);
1110 break;
1111 case snd_soc_dapm_aif_in:
1112 *dw = (struct snd_soc_dapm_widget)
1113 SND_SOC_DAPM_AIF_IN_E(w->name, w->sname, 0,
1114 SND_SOC_NOPM,
1115 0, 0, gbaudio_widget_event,
1116 SND_SOC_DAPM_PRE_PMU |
1117 SND_SOC_DAPM_POST_PMD);
1118 break;
1119 case snd_soc_dapm_aif_out:
1120 *dw = (struct snd_soc_dapm_widget)
1121 SND_SOC_DAPM_AIF_OUT_E(w->name, w->sname, 0,
1122 SND_SOC_NOPM,
1123 0, 0, gbaudio_widget_event,
1124 SND_SOC_DAPM_PRE_PMU |
1125 SND_SOC_DAPM_POST_PMD);
1126 break;
1127 default:
1128 ret = -EINVAL;
1129 goto error;
1130 }
1131
6dd67645 1132 dev_dbg(module->dev, "%s: widget of type %d created\n", dw->name,
6339d232
VA
1133 dw->id);
1134 return 0;
1135error:
6dd67645 1136 list_for_each_entry_safe(control, _control, &module->widget_ctl_list,
6339d232
VA
1137 list) {
1138 list_del(&control->list);
6dd67645 1139 devm_kfree(module->dev, control);
6339d232
VA
1140 }
1141 return ret;
1142}
1143
6dd67645 1144static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module,
6339d232
VA
1145 struct gb_audio_control *controls)
1146{
d4cd9daa 1147 int i, csize, ret;
6339d232
VA
1148 struct snd_kcontrol_new *dapm_kctls;
1149 struct gb_audio_control *curr;
1150 struct gbaudio_control *control, *_control;
1151 size_t size;
6dd67645 1152 char temp_name[NAME_SIZE];
6339d232 1153
6dd67645
VA
1154 size = sizeof(struct snd_kcontrol_new) * module->num_controls;
1155 dapm_kctls = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
1156 if (!dapm_kctls)
1157 return -ENOMEM;
1158
1159 curr = controls;
6dd67645
VA
1160 for (i = 0; i < module->num_controls; i++) {
1161 ret = gbaudio_tplg_create_kcontrol(module, &dapm_kctls[i],
6339d232
VA
1162 curr);
1163 if (ret) {
6dd67645 1164 dev_err(module->dev, "%s:%d type not supported\n",
6339d232
VA
1165 curr->name, curr->iface);
1166 goto error;
1167 }
6dd67645 1168 control = devm_kzalloc(module->dev, sizeof(struct
6339d232
VA
1169 gbaudio_control),
1170 GFP_KERNEL);
1171 if (!control) {
1172 ret = -ENOMEM;
1173 goto error;
1174 }
1175 control->id = curr->id;
6dd67645
VA
1176 /* Prefix dev_id to widget_name */
1177 strlcpy(temp_name, curr->name, NAME_SIZE);
1178 snprintf(curr->name, NAME_SIZE, "GB %d %s", module->dev_id,
1179 temp_name);
6339d232 1180 control->name = curr->name;
e65579e3
VA
1181 if (curr->info.type == GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED) {
1182 struct gb_audio_enumerated *gbenum =
1183 &curr->info.value.enumerated;
1184
1185 csize = offsetof(struct gb_audio_control, info);
1186 csize += offsetof(struct gb_audio_ctl_elem_info, value);
1187 csize += offsetof(struct gb_audio_enumerated, names);
1188 csize += gbenum->names_length;
6339d232 1189 control->texts = (const char * const *)
e65579e3 1190 gb_generate_enum_strings(module, gbenum);
15c726ea 1191 control->items = gbenum->items;
e65579e3
VA
1192 } else
1193 csize = sizeof(struct gb_audio_control);
d4cd9daa 1194
6dd67645
VA
1195 list_add(&control->list, &module->ctl_list);
1196 dev_dbg(module->dev, "%d:%s created of type %d\n", curr->id,
6339d232 1197 curr->name, curr->info.type);
d4cd9daa 1198 curr = (void *)curr + csize;
6339d232 1199 }
6dd67645 1200 module->controls = dapm_kctls;
6339d232
VA
1201
1202 return 0;
1203error:
6dd67645 1204 list_for_each_entry_safe(control, _control, &module->ctl_list,
6339d232
VA
1205 list) {
1206 list_del(&control->list);
6dd67645 1207 devm_kfree(module->dev, control);
6339d232 1208 }
6dd67645 1209 devm_kfree(module->dev, dapm_kctls);
6339d232
VA
1210 return ret;
1211}
1212
6dd67645 1213static int gbaudio_tplg_process_widgets(struct gbaudio_module_info *module,
6339d232
VA
1214 struct gb_audio_widget *widgets)
1215{
d4cd9daa 1216 int i, ret, w_size;
6339d232
VA
1217 struct snd_soc_dapm_widget *dapm_widgets;
1218 struct gb_audio_widget *curr;
1219 struct gbaudio_widget *widget, *_widget;
1220 size_t size;
1221
6dd67645
VA
1222 size = sizeof(struct snd_soc_dapm_widget) * module->num_dapm_widgets;
1223 dapm_widgets = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
1224 if (!dapm_widgets)
1225 return -ENOMEM;
1226
1227 curr = widgets;
6dd67645
VA
1228 for (i = 0; i < module->num_dapm_widgets; i++) {
1229 ret = gbaudio_tplg_create_widget(module, &dapm_widgets[i],
d4cd9daa 1230 curr, &w_size);
6339d232 1231 if (ret) {
6dd67645 1232 dev_err(module->dev, "%s:%d type not supported\n",
6339d232
VA
1233 curr->name, curr->type);
1234 goto error;
1235 }
6dd67645 1236 widget = devm_kzalloc(module->dev, sizeof(struct
6339d232
VA
1237 gbaudio_widget),
1238 GFP_KERNEL);
1239 if (!widget) {
1240 ret = -ENOMEM;
1241 goto error;
1242 }
1243 widget->id = curr->id;
1244 widget->name = curr->name;
6dd67645 1245 list_add(&widget->list, &module->widget_list);
d4cd9daa 1246 curr = (void *)curr + w_size;
6339d232 1247 }
6dd67645 1248 module->dapm_widgets = dapm_widgets;
6339d232
VA
1249
1250 return 0;
1251
1252error:
6dd67645 1253 list_for_each_entry_safe(widget, _widget, &module->widget_list,
6339d232
VA
1254 list) {
1255 list_del(&widget->list);
6dd67645 1256 devm_kfree(module->dev, widget);
6339d232 1257 }
6dd67645 1258 devm_kfree(module->dev, dapm_widgets);
6339d232
VA
1259 return ret;
1260}
1261
6dd67645 1262static int gbaudio_tplg_process_routes(struct gbaudio_module_info *module,
6339d232
VA
1263 struct gb_audio_route *routes)
1264{
1265 int i, ret;
1266 struct snd_soc_dapm_route *dapm_routes;
1267 struct gb_audio_route *curr;
1268 size_t size;
1269
6dd67645
VA
1270 size = sizeof(struct snd_soc_dapm_route) * module->num_dapm_routes;
1271 dapm_routes = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
1272 if (!dapm_routes)
1273 return -ENOMEM;
1274
6dd67645 1275 module->dapm_routes = dapm_routes;
6339d232
VA
1276 curr = routes;
1277
6dd67645 1278 for (i = 0; i < module->num_dapm_routes; i++) {
6339d232 1279 dapm_routes->sink =
6dd67645 1280 gbaudio_map_widgetid(module, curr->destination_id);
6339d232 1281 if (!dapm_routes->sink) {
6dd67645 1282 dev_err(module->dev, "%d:%d:%d:%d - Invalid sink\n",
6339d232
VA
1283 curr->source_id, curr->destination_id,
1284 curr->control_id, curr->index);
1285 ret = -EINVAL;
1286 goto error;
1287 }
1288 dapm_routes->source =
6dd67645 1289 gbaudio_map_widgetid(module, curr->source_id);
6339d232 1290 if (!dapm_routes->source) {
6dd67645 1291 dev_err(module->dev, "%d:%d:%d:%d - Invalid source\n",
6339d232
VA
1292 curr->source_id, curr->destination_id,
1293 curr->control_id, curr->index);
1294 ret = -EINVAL;
1295 goto error;
1296 }
1297 dapm_routes->control =
6dd67645 1298 gbaudio_map_controlid(module,
6339d232
VA
1299 curr->control_id,
1300 curr->index);
1301 if ((curr->control_id != GBAUDIO_INVALID_ID) &&
1302 !dapm_routes->control) {
6dd67645 1303 dev_err(module->dev, "%d:%d:%d:%d - Invalid control\n",
6339d232
VA
1304 curr->source_id, curr->destination_id,
1305 curr->control_id, curr->index);
1306 ret = -EINVAL;
1307 goto error;
1308 }
6dd67645 1309 dev_dbg(module->dev, "Route {%s, %s, %s}\n", dapm_routes->sink,
6339d232
VA
1310 (dapm_routes->control) ? dapm_routes->control:"NULL",
1311 dapm_routes->source);
1312 dapm_routes++;
1313 curr++;
1314 }
1315
1316 return 0;
1317
1318error:
6198f892 1319 devm_kfree(module->dev, module->dapm_routes);
6339d232
VA
1320 return ret;
1321}
1322
6dd67645 1323static int gbaudio_tplg_process_header(struct gbaudio_module_info *module,
6339d232
VA
1324 struct gb_audio_topology *tplg_data)
1325{
1326 /* fetch no. of kcontrols, widgets & routes */
6dd67645
VA
1327 module->num_controls = tplg_data->num_controls;
1328 module->num_dapm_widgets = tplg_data->num_widgets;
1329 module->num_dapm_routes = tplg_data->num_routes;
6339d232
VA
1330
1331 /* update block offset */
6dd67645
VA
1332 module->dai_offset = (unsigned long)&tplg_data->data;
1333 module->control_offset = module->dai_offset + tplg_data->size_dais;
1334 module->widget_offset = module->control_offset +
6339d232 1335 tplg_data->size_controls;
6dd67645 1336 module->route_offset = module->widget_offset +
6339d232
VA
1337 tplg_data->size_widgets;
1338
6dd67645
VA
1339 dev_dbg(module->dev, "DAI offset is 0x%lx\n", module->dai_offset);
1340 dev_dbg(module->dev, "control offset is %lx\n",
1341 module->control_offset);
1342 dev_dbg(module->dev, "widget offset is %lx\n", module->widget_offset);
1343 dev_dbg(module->dev, "route offset is %lx\n", module->route_offset);
6339d232
VA
1344
1345 return 0;
1346}
1347
6dd67645 1348int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
6339d232
VA
1349 struct gb_audio_topology *tplg_data)
1350{
1351 int ret;
6339d232
VA
1352 struct gb_audio_control *controls;
1353 struct gb_audio_widget *widgets;
1354 struct gb_audio_route *routes;
1355
1356 if (!tplg_data)
1357 return -EINVAL;
1358
6dd67645 1359 ret = gbaudio_tplg_process_header(module, tplg_data);
6339d232 1360 if (ret) {
6dd67645 1361 dev_err(module->dev, "%d: Error in parsing topology header\n",
6339d232
VA
1362 ret);
1363 return ret;
1364 }
1365
1366 /* process control */
6dd67645
VA
1367 controls = (struct gb_audio_control *)module->control_offset;
1368 ret = gbaudio_tplg_process_kcontrols(module, controls);
6339d232 1369 if (ret) {
6dd67645 1370 dev_err(module->dev,
6339d232
VA
1371 "%d: Error in parsing controls data\n", ret);
1372 return ret;
1373 }
6dd67645 1374 dev_dbg(module->dev, "Control parsing finished\n");
6339d232
VA
1375
1376 /* process widgets */
6dd67645
VA
1377 widgets = (struct gb_audio_widget *)module->widget_offset;
1378 ret = gbaudio_tplg_process_widgets(module, widgets);
6339d232 1379 if (ret) {
6dd67645 1380 dev_err(module->dev,
6339d232
VA
1381 "%d: Error in parsing widgets data\n", ret);
1382 return ret;
1383 }
6dd67645 1384 dev_dbg(module->dev, "Widget parsing finished\n");
6339d232
VA
1385
1386 /* process route */
6dd67645
VA
1387 routes = (struct gb_audio_route *)module->route_offset;
1388 ret = gbaudio_tplg_process_routes(module, routes);
6339d232 1389 if (ret) {
6dd67645 1390 dev_err(module->dev,
6339d232
VA
1391 "%d: Error in parsing routes data\n", ret);
1392 return ret;
1393 }
6dd67645 1394 dev_dbg(module->dev, "Route parsing finished\n");
6339d232 1395
847175e8
VA
1396 /* parse jack capabilities */
1397 if (tplg_data->jack_type) {
1398 module->jack_mask = tplg_data->jack_type & GBCODEC_JACK_MASK;
1399 module->button_mask = tplg_data->jack_type &
1400 GBCODEC_JACK_BUTTON_MASK;
1401 }
1402
6339d232
VA
1403 return ret;
1404}
1405
6dd67645 1406void gbaudio_tplg_release(struct gbaudio_module_info *module)
6339d232 1407{
6339d232
VA
1408 struct gbaudio_control *control, *_control;
1409 struct gbaudio_widget *widget, *_widget;
1410
6dd67645 1411 if (!module->topology)
6339d232
VA
1412 return;
1413
1414 /* release kcontrols */
6dd67645 1415 list_for_each_entry_safe(control, _control, &module->ctl_list,
6339d232
VA
1416 list) {
1417 list_del(&control->list);
6dd67645 1418 devm_kfree(module->dev, control);
6339d232 1419 }
6dd67645
VA
1420 if (module->controls)
1421 devm_kfree(module->dev, module->controls);
6339d232
VA
1422
1423 /* release widget controls */
6dd67645 1424 list_for_each_entry_safe(control, _control, &module->widget_ctl_list,
6339d232
VA
1425 list) {
1426 list_del(&control->list);
6dd67645 1427 devm_kfree(module->dev, control);
6339d232
VA
1428 }
1429
1430 /* release widgets */
6dd67645 1431 list_for_each_entry_safe(widget, _widget, &module->widget_list,
6339d232
VA
1432 list) {
1433 list_del(&widget->list);
6dd67645 1434 devm_kfree(module->dev, widget);
6339d232 1435 }
6dd67645
VA
1436 if (module->dapm_widgets)
1437 devm_kfree(module->dev, module->dapm_widgets);
6339d232
VA
1438
1439 /* release routes */
6dd67645
VA
1440 if (module->dapm_routes)
1441 devm_kfree(module->dev, module->dapm_routes);
6339d232 1442}