greybus: Remove apbridgea_shutdown_xx sequence if already done
[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,
6339d232
VA
56 __u8 control_id, __u8 index)
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
6dd67645 80static int gbaudio_map_widgetname(struct gbaudio_module_info *module,
6339d232
VA
81 const char *name)
82{
83 struct gbaudio_widget *widget;
6dd67645
VA
84 list_for_each_entry(widget, &module->widget_list, list) {
85 if (!strncmp(widget->name, name, NAME_SIZE))
6339d232
VA
86 return widget->id;
87 }
88 return -EINVAL;
89}
90
6dd67645 91static const char *gbaudio_map_widgetid(struct gbaudio_module_info *module,
6339d232
VA
92 __u8 widget_id)
93{
94 struct gbaudio_widget *widget;
95
6dd67645 96 list_for_each_entry(widget, &module->widget_list, list) {
6339d232
VA
97 if (widget->id == widget_id)
98 return widget->name;
99 }
100 return NULL;
101}
102
103static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol,
104 struct snd_ctl_elem_info *uinfo)
105{
106 unsigned int max;
107 const char *name;
108 struct gbaudio_ctl_pvt *data;
109 struct gb_audio_ctl_elem_info *info;
6dd67645 110 struct gbaudio_module_info *module;
6339d232 111 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
796fad44 112 struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec);
6339d232 113
6dd67645 114 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
6339d232
VA
115 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
116 info = (struct gb_audio_ctl_elem_info *)data->info;
117
118 if (!info) {
6dd67645 119 dev_err(module->dev, "NULL info for %s\n", uinfo->id.name);
6339d232
VA
120 return -EINVAL;
121 }
122
123 /* update uinfo */
124 uinfo->access = data->access;
125 uinfo->count = data->vcount;
126 uinfo->type = (snd_ctl_elem_type_t)info->type;
127
128 switch (info->type) {
129 case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
130 case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
131 uinfo->value.integer.min = info->value.integer.min;
132 uinfo->value.integer.max = info->value.integer.max;
133 break;
134 case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
135 max = info->value.enumerated.items;
136 uinfo->value.enumerated.items = max;
137 if (uinfo->value.enumerated.item > max - 1)
138 uinfo->value.enumerated.item = max - 1;
6dd67645
VA
139 module = find_gb_module(gbcodec, kcontrol->id.name);
140 if (!module)
141 return -EINVAL;
142 name = gbaudio_map_controlid(module, data->ctl_id,
6339d232
VA
143 uinfo->value.enumerated.item);
144 strlcpy(uinfo->value.enumerated.name, name, NAME_SIZE);
145 break;
146 default:
147 dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
148 info->type, kcontrol->id.name);
149 break;
150 }
151 return 0;
152}
153
154static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol,
155 struct snd_ctl_elem_value *ucontrol)
156{
157 int ret;
158 struct gb_audio_ctl_elem_info *info;
159 struct gbaudio_ctl_pvt *data;
160 struct gb_audio_ctl_elem_value gbvalue;
6dd67645 161 struct gbaudio_module_info *module;
6339d232 162 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
796fad44 163 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
6339d232 164
6dd67645
VA
165 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
166 module = find_gb_module(gb, kcontrol->id.name);
167 if (!module)
168 return -EINVAL;
3994e0b1 169
6339d232
VA
170 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
171 info = (struct gb_audio_ctl_elem_info *)data->info;
172
6dd67645 173 ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
6339d232
VA
174 GB_AUDIO_INVALID_INDEX, &gbvalue);
175 if (ret) {
176 dev_err(codec->dev, "%d:Error in %s for %s\n", ret, __func__,
177 kcontrol->id.name);
178 return ret;
179 }
180
181 /* update ucontrol */
182 switch (info->type) {
183 case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
184 case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
185 ucontrol->value.integer.value[0] =
186 gbvalue.value.integer_value[0];
187 if (data->vcount == 2)
188 ucontrol->value.integer.value[1] =
189 gbvalue.value.integer_value[1];
190 break;
191 case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
192 ucontrol->value.enumerated.item[0] =
193 gbvalue.value.enumerated_item[0];
194 if (data->vcount == 2)
195 ucontrol->value.enumerated.item[1] =
196 gbvalue.value.enumerated_item[1];
197 break;
198 default:
199 dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
200 info->type, kcontrol->id.name);
201 ret = -EINVAL;
202 break;
203 }
204 return ret;
205}
206
207static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol,
208 struct snd_ctl_elem_value *ucontrol)
209{
210 int ret = 0;
211 struct gb_audio_ctl_elem_info *info;
212 struct gbaudio_ctl_pvt *data;
213 struct gb_audio_ctl_elem_value gbvalue;
6dd67645 214 struct gbaudio_module_info *module;
6339d232 215 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
796fad44 216 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
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;
225
226 /* update ucontrol */
227 switch (info->type) {
228 case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
229 case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
230 gbvalue.value.integer_value[0] =
231 ucontrol->value.integer.value[0];
232 if (data->vcount == 2)
233 gbvalue.value.integer_value[1] =
234 ucontrol->value.integer.value[1];
235 break;
236 case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
237 gbvalue.value.enumerated_item[0] =
238 ucontrol->value.enumerated.item[0];
239 if (data->vcount == 2)
240 gbvalue.value.enumerated_item[1] =
241 ucontrol->value.enumerated.item[1];
242 break;
243 default:
244 dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
245 info->type, kcontrol->id.name);
246 ret = -EINVAL;
247 break;
248 }
249
250 if (ret)
251 return ret;
252
6dd67645 253 ret = gb_audio_gb_set_control(module->mgmt_connection, data->ctl_id,
6339d232
VA
254 GB_AUDIO_INVALID_INDEX, &gbvalue);
255 if (ret) {
256 dev_err(codec->dev, "%d:Error in %s for %s\n", ret, __func__,
257 kcontrol->id.name);
258 }
259
260 return ret;
261}
262
263#define SOC_MIXER_GB(xname, kcount, data) \
264{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
265 .count = kcount, .info = gbcodec_mixer_ctl_info, \
266 .get = gbcodec_mixer_ctl_get, .put = gbcodec_mixer_ctl_put, \
267 .private_value = (unsigned long)data }
268
269/*
270 * although below callback functions seems redundant to above functions.
271 * same are kept to allow provision for different handling in case
272 * of DAPM related sequencing, etc.
273 */
274static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol,
275 struct snd_ctl_elem_info *uinfo)
276{
277 int platform_max, platform_min;
278 struct gbaudio_ctl_pvt *data;
279 struct gb_audio_ctl_elem_info *info;
6dd67645
VA
280 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
281 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
282 struct snd_soc_codec *codec = widget->codec;
6339d232 283
6dd67645 284 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
6339d232
VA
285 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
286 info = (struct gb_audio_ctl_elem_info *)data->info;
287
288 /* update uinfo */
289 platform_max = info->value.integer.max;
290 platform_min = info->value.integer.min;
291
292 if (platform_max == 1 &&
293 !strnstr(kcontrol->id.name, " Volume", NAME_SIZE))
294 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
295 else
296 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
297
298 uinfo->count = data->vcount;
299 uinfo->value.integer.min = 0;
300 if (info->value.integer.min < 0 &&
301 (uinfo->type == SNDRV_CTL_ELEM_TYPE_INTEGER))
302 uinfo->value.integer.max = platform_max - platform_min;
303 else
304 uinfo->value.integer.max = platform_max;
305
306 return 0;
307}
308
309static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol,
310 struct snd_ctl_elem_value *ucontrol)
311{
312 int ret;
313 struct gb_audio_ctl_elem_info *info;
314 struct gbaudio_ctl_pvt *data;
315 struct gb_audio_ctl_elem_value gbvalue;
6dd67645 316 struct gbaudio_module_info *module;
6339d232
VA
317 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
318 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
319 struct snd_soc_codec *codec = widget->codec;
796fad44 320 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
6339d232 321
6dd67645
VA
322 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
323 module = find_gb_module(gb, kcontrol->id.name);
324 if (!module)
325 return -EINVAL;
3994e0b1 326
6339d232
VA
327 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
328 info = (struct gb_audio_ctl_elem_info *)data->info;
329
330 if (data->vcount == 2)
331 dev_warn(widget->dapm->dev,
332 "GB: Control '%s' is stereo, which is not supported\n",
333 kcontrol->id.name);
334
6dd67645 335 ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
6339d232
VA
336 GB_AUDIO_INVALID_INDEX, &gbvalue);
337 if (ret) {
338 dev_err(codec->dev, "%d:Error in %s for %s\n", ret, __func__,
339 kcontrol->id.name);
340 return ret;
341 }
342 /* update ucontrol */
343 ucontrol->value.integer.value[0] = gbvalue.value.integer_value[0];
344
345 return ret;
346}
347
348static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
349 struct snd_ctl_elem_value *ucontrol)
350{
351 int ret, wi, max, connect;
352 unsigned int mask, val;
353 struct gb_audio_ctl_elem_info *info;
354 struct gbaudio_ctl_pvt *data;
355 struct gb_audio_ctl_elem_value gbvalue;
6dd67645 356 struct gbaudio_module_info *module;
6339d232
VA
357 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
358 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
359 struct snd_soc_codec *codec = widget->codec;
796fad44 360 struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
6339d232 361
6dd67645
VA
362 dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
363 module = find_gb_module(gb, kcontrol->id.name);
364 if (!module)
365 return -EINVAL;
3994e0b1 366
6339d232
VA
367 data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
368 info = (struct gb_audio_ctl_elem_info *)data->info;
369
370 if (data->vcount == 2)
371 dev_warn(widget->dapm->dev,
372 "GB: Control '%s' is stereo, which is not supported\n",
373 kcontrol->id.name);
374
375 max = info->value.integer.max;
376 mask = (1 << fls(max)) - 1;
377 val = (ucontrol->value.integer.value[0] & mask);
378 connect = !!val;
379
380 /* update ucontrol */
381 if (gbvalue.value.integer_value[0] != val) {
382 for (wi = 0; wi < wlist->num_widgets; wi++) {
383 widget = wlist->widgets[wi];
384
385 widget->value = val;
386 widget->dapm->update = NULL;
387 snd_soc_dapm_mixer_update_power(widget, kcontrol,
388 connect);
389 }
390 gbvalue.value.integer_value[0] =
391 ucontrol->value.integer.value[0];
6dd67645 392 ret = gb_audio_gb_set_control(module->mgmt_connection,
6339d232
VA
393 data->ctl_id,
394 GB_AUDIO_INVALID_INDEX, &gbvalue);
395 if (ret) {
396 dev_err(codec->dev,
397 "%d:Error in %s for %s\n", ret, __func__,
398 kcontrol->id.name);
399 }
400 }
401
402 return ret;
403}
404
405#define SOC_DAPM_MIXER_GB(xname, kcount, data) \
406{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
407 .count = kcount, .info = gbcodec_mixer_dapm_ctl_info, \
408 .get = gbcodec_mixer_dapm_ctl_get, .put = gbcodec_mixer_dapm_ctl_put, \
409 .private_value = (unsigned long)data}
410
411static int gbcodec_event_spk(struct snd_soc_dapm_widget *w,
412 struct snd_kcontrol *k, int event)
413{
414 /* Ensure GB speaker is connected */
415
416 return 0;
417}
418
419static int gbcodec_event_hp(struct snd_soc_dapm_widget *w,
420 struct snd_kcontrol *k, int event)
421{
422 /* Ensure GB module supports jack slot */
423
424 return 0;
425}
426
427static int gbcodec_event_int_mic(struct snd_soc_dapm_widget *w,
428 struct snd_kcontrol *k, int event)
429{
430 /* Ensure GB module supports jack slot */
431
432 return 0;
433}
434
435static int gbaudio_validate_kcontrol_count(struct gb_audio_widget *w)
436{
437 int ret = 0;
438
439 switch (w->type) {
440 case snd_soc_dapm_spk:
441 case snd_soc_dapm_hp:
442 case snd_soc_dapm_mic:
443 case snd_soc_dapm_output:
444 case snd_soc_dapm_input:
445 if (w->ncontrols)
446 ret = -EINVAL;
447 break;
448 case snd_soc_dapm_switch:
449 case snd_soc_dapm_mux:
450 if (w->ncontrols != 1)
451 ret = -EINVAL;
452 break;
453 default:
454 break;
455 }
456
457 return ret;
458}
459
6dd67645 460static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb,
6339d232
VA
461 struct snd_kcontrol_new *kctl,
462 struct gb_audio_control *ctl)
463{
464 struct gbaudio_ctl_pvt *ctldata;
465
466 switch (ctl->iface) {
467 case SNDRV_CTL_ELEM_IFACE_MIXER:
468 ctldata = devm_kzalloc(gb->dev, sizeof(struct gbaudio_ctl_pvt),
469 GFP_KERNEL);
470 if (!ctldata)
471 return -ENOMEM;
472 ctldata->ctl_id = ctl->id;
473 ctldata->data_cport = ctl->data_cport;
474 ctldata->access = ctl->access;
475 ctldata->vcount = ctl->count_values;
476 ctldata->info = &ctl->info;
477 *kctl = (struct snd_kcontrol_new)
478 SOC_MIXER_GB(ctl->name, ctl->count, ctldata);
479 ctldata = NULL;
480 break;
481 default:
482 return -EINVAL;
483 }
484
485 dev_dbg(gb->dev, "%s:%d control created\n", ctl->name, ctl->id);
486 return 0;
487}
488
489static const char * const gbtexts[] = {"Stereo", "Left", "Right"};
490
491static const SOC_ENUM_SINGLE_DECL(
6dd67645 492 module_apb1_rx_enum, GBCODEC_APB1_MUX_REG, 0, gbtexts);
6339d232
VA
493
494static const SOC_ENUM_SINGLE_DECL(
6dd67645 495 module_mic_enum, GBCODEC_APB1_MUX_REG, 4, gbtexts);
6339d232 496
6dd67645 497static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb,
6339d232
VA
498 struct snd_kcontrol_new *kctl,
499 struct gb_audio_control *ctl)
500{
501 switch (ctl->id) {
502 case 8:
503 *kctl = (struct snd_kcontrol_new)
6dd67645 504 SOC_DAPM_ENUM(ctl->name, module_apb1_rx_enum);
6339d232
VA
505 break;
506 case 9:
507 *kctl = (struct snd_kcontrol_new)
6dd67645 508 SOC_DAPM_ENUM(ctl->name, module_mic_enum);
6339d232
VA
509 break;
510 default:
511 return -EINVAL;
512 }
513
514 return 0;
515}
516
6dd67645 517static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb,
6339d232
VA
518 struct snd_kcontrol_new *kctl,
519 struct gb_audio_control *ctl)
520{
521 struct gbaudio_ctl_pvt *ctldata;
522
523 ctldata = devm_kzalloc(gb->dev, sizeof(struct gbaudio_ctl_pvt),
524 GFP_KERNEL);
525 if (!ctldata)
526 return -ENOMEM;
527 ctldata->ctl_id = ctl->id;
528 ctldata->data_cport = ctl->data_cport;
529 ctldata->access = ctl->access;
530 ctldata->vcount = ctl->count_values;
531 ctldata->info = &ctl->info;
532 *kctl = (struct snd_kcontrol_new)
533 SOC_DAPM_MIXER_GB(ctl->name, ctl->count, ctldata);
534
535 return 0;
536}
537
6dd67645 538static int gbaudio_tplg_create_wcontrol(struct gbaudio_module_info *gb,
6339d232
VA
539 struct snd_kcontrol_new *kctl,
540 struct gb_audio_control *ctl)
541{
542 int ret;
543
544 switch (ctl->iface) {
545 case SNDRV_CTL_ELEM_IFACE_MIXER:
546 switch (ctl->info.type) {
547 case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
548 ret = gbaudio_tplg_create_enum_ctl(gb, kctl, ctl);
549 break;
550 default:
551 ret = gbaudio_tplg_create_mixer_ctl(gb, kctl, ctl);
552 break;
553 }
554 break;
555 default:
556 return -EINVAL;
557
558 }
559
560 dev_dbg(gb->dev, "%s:%d DAPM control created, ret:%d\n", ctl->name,
561 ctl->id, ret);
562 return ret;
563}
564
565static int gbaudio_widget_event(struct snd_soc_dapm_widget *w,
566 struct snd_kcontrol *kcontrol, int event)
567{
568 int wid;
569 int ret;
570 struct snd_soc_codec *codec = w->codec;
796fad44 571 struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec);
6dd67645 572 struct gbaudio_module_info *module;
6339d232
VA
573
574 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
575
6dd67645
VA
576 /* Find relevant module */
577 module = find_gb_module(gbcodec, w->name);
578 if (!module)
579 return -EINVAL;
580
6339d232 581 /* map name to widget id */
6dd67645 582 wid = gbaudio_map_widgetname(module, w->name);
6339d232
VA
583 if (wid < 0) {
584 dev_err(codec->dev, "Invalid widget name:%s\n", w->name);
585 return -EINVAL;
586 }
587
588 switch (event) {
589 case SND_SOC_DAPM_PRE_PMU:
6dd67645
VA
590 ret = gb_audio_gb_enable_widget(module->mgmt_connection, wid);
591 if (!ret)
592 ret = gbaudio_module_update(gbcodec, w->name, module,
593 1);
6339d232
VA
594 break;
595 case SND_SOC_DAPM_POST_PMD:
6dd67645
VA
596 ret = gb_audio_gb_disable_widget(module->mgmt_connection, wid);
597 if (!ret)
598 ret = gbaudio_module_update(gbcodec, w->name, module,
599 0);
6339d232
VA
600 break;
601 }
602 if (ret)
603 dev_err(codec->dev, "%d: widget, event:%d failed:%d\n", wid,
604 event, ret);
605 return ret;
606}
607
6dd67645 608static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module,
6339d232
VA
609 struct snd_soc_dapm_widget *dw,
610 struct gb_audio_widget *w)
611{
612 int i, ret;
613 struct snd_kcontrol_new *widget_kctls;
614 struct gb_audio_control *curr;
615 struct gbaudio_control *control, *_control;
616 size_t size;
6dd67645 617 char temp_name[NAME_SIZE];
6339d232
VA
618
619 ret = gbaudio_validate_kcontrol_count(w);
620 if (ret) {
6dd67645 621 dev_err(module->dev, "Inavlid kcontrol count=%d for %s\n",
6339d232
VA
622 w->ncontrols, w->name);
623 return ret;
624 }
625
626 /* allocate memory for kcontrol */
627 if (w->ncontrols) {
628 size = sizeof(struct snd_kcontrol_new) * w->ncontrols;
6dd67645 629 widget_kctls = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
630 if (!widget_kctls)
631 return -ENOMEM;
632 }
633
634 /* create relevant kcontrols */
635 for (i = 0; i < w->ncontrols; i++) {
636 curr = &w->ctl[i];
6dd67645 637 ret = gbaudio_tplg_create_wcontrol(module, &widget_kctls[i],
6339d232
VA
638 curr);
639 if (ret) {
6dd67645 640 dev_err(module->dev,
6339d232
VA
641 "%s:%d type widget_ctl not supported\n",
642 curr->name, curr->iface);
643 goto error;
644 }
6dd67645 645 control = devm_kzalloc(module->dev,
6339d232
VA
646 sizeof(struct gbaudio_control),
647 GFP_KERNEL);
648 if (!control) {
649 ret = -ENOMEM;
650 goto error;
651 }
652 control->id = curr->id;
653 control->name = curr->name;
654 if (curr->info.type == GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED)
655 control->texts = (const char * const *)
656 curr->info.value.enumerated.names;
6dd67645
VA
657 list_add(&control->list, &module->widget_ctl_list);
658 dev_dbg(module->dev, "%s: control of type %d created\n",
6339d232
VA
659 widget_kctls[i].name, widget_kctls[i].iface);
660 }
661
6dd67645
VA
662 /* Prefix dev_id to widget control_name */
663 strlcpy(temp_name, w->name, NAME_SIZE);
664 snprintf(w->name, NAME_SIZE, "GB %d %s", module->dev_id, temp_name);
665
6339d232
VA
666 switch (w->type) {
667 case snd_soc_dapm_spk:
668 *dw = (struct snd_soc_dapm_widget)
669 SND_SOC_DAPM_SPK(w->name, gbcodec_event_spk);
89de9a06 670 module->op_devices |= GBAUDIO_DEVICE_OUT_SPEAKER;
6339d232
VA
671 break;
672 case snd_soc_dapm_hp:
673 *dw = (struct snd_soc_dapm_widget)
674 SND_SOC_DAPM_HP(w->name, gbcodec_event_hp);
64a7e2cc 675 module->num_jacks++;
89de9a06
VA
676 module->op_devices |= (GBAUDIO_DEVICE_OUT_WIRED_HEADSET
677 | GBAUDIO_DEVICE_OUT_WIRED_HEADPHONE);
678 module->ip_devices |= GBAUDIO_DEVICE_IN_WIRED_HEADSET;
6339d232
VA
679 break;
680 case snd_soc_dapm_mic:
681 *dw = (struct snd_soc_dapm_widget)
682 SND_SOC_DAPM_MIC(w->name, gbcodec_event_int_mic);
89de9a06 683 module->ip_devices |= GBAUDIO_DEVICE_IN_BUILTIN_MIC;
6339d232
VA
684 break;
685 case snd_soc_dapm_output:
686 *dw = (struct snd_soc_dapm_widget)SND_SOC_DAPM_OUTPUT(w->name);
687 break;
688 case snd_soc_dapm_input:
689 *dw = (struct snd_soc_dapm_widget)SND_SOC_DAPM_INPUT(w->name);
690 break;
691 case snd_soc_dapm_switch:
692 *dw = (struct snd_soc_dapm_widget)
693 SND_SOC_DAPM_SWITCH_E(w->name, SND_SOC_NOPM, 0, 0,
694 widget_kctls, gbaudio_widget_event,
695 SND_SOC_DAPM_PRE_PMU |
696 SND_SOC_DAPM_POST_PMD);
697 break;
698 case snd_soc_dapm_pga:
699 *dw = (struct snd_soc_dapm_widget)
700 SND_SOC_DAPM_PGA_E(w->name, SND_SOC_NOPM, 0, 0, NULL, 0,
701 gbaudio_widget_event,
702 SND_SOC_DAPM_PRE_PMU |
703 SND_SOC_DAPM_POST_PMD);
704 break;
705 case snd_soc_dapm_mixer:
706 *dw = (struct snd_soc_dapm_widget)
707 SND_SOC_DAPM_MIXER_E(w->name, SND_SOC_NOPM, 0, 0, NULL,
708 0, gbaudio_widget_event,
709 SND_SOC_DAPM_PRE_PMU |
710 SND_SOC_DAPM_POST_PMD);
711 break;
712 case snd_soc_dapm_mux:
713 *dw = (struct snd_soc_dapm_widget)
714 SND_SOC_DAPM_MUX_E(w->name, SND_SOC_NOPM, 0, 0,
715 widget_kctls, gbaudio_widget_event,
716 SND_SOC_DAPM_PRE_PMU |
717 SND_SOC_DAPM_POST_PMD);
718 break;
719 case snd_soc_dapm_aif_in:
720 *dw = (struct snd_soc_dapm_widget)
721 SND_SOC_DAPM_AIF_IN_E(w->name, w->sname, 0,
722 SND_SOC_NOPM,
723 0, 0, gbaudio_widget_event,
724 SND_SOC_DAPM_PRE_PMU |
725 SND_SOC_DAPM_POST_PMD);
726 break;
727 case snd_soc_dapm_aif_out:
728 *dw = (struct snd_soc_dapm_widget)
729 SND_SOC_DAPM_AIF_OUT_E(w->name, w->sname, 0,
730 SND_SOC_NOPM,
731 0, 0, gbaudio_widget_event,
732 SND_SOC_DAPM_PRE_PMU |
733 SND_SOC_DAPM_POST_PMD);
734 break;
735 default:
736 ret = -EINVAL;
737 goto error;
738 }
739
6dd67645 740 dev_dbg(module->dev, "%s: widget of type %d created\n", dw->name,
6339d232
VA
741 dw->id);
742 return 0;
743error:
6dd67645 744 list_for_each_entry_safe(control, _control, &module->widget_ctl_list,
6339d232
VA
745 list) {
746 list_del(&control->list);
6dd67645 747 devm_kfree(module->dev, control);
6339d232
VA
748 }
749 return ret;
750}
751
6dd67645 752static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module,
6339d232
VA
753 struct gb_audio_control *controls)
754{
755 int i, ret;
756 struct snd_kcontrol_new *dapm_kctls;
757 struct gb_audio_control *curr;
758 struct gbaudio_control *control, *_control;
759 size_t size;
6dd67645 760 char temp_name[NAME_SIZE];
6339d232 761
6dd67645
VA
762 size = sizeof(struct snd_kcontrol_new) * module->num_controls;
763 dapm_kctls = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
764 if (!dapm_kctls)
765 return -ENOMEM;
766
767 curr = controls;
6dd67645
VA
768 for (i = 0; i < module->num_controls; i++) {
769 ret = gbaudio_tplg_create_kcontrol(module, &dapm_kctls[i],
6339d232
VA
770 curr);
771 if (ret) {
6dd67645 772 dev_err(module->dev, "%s:%d type not supported\n",
6339d232
VA
773 curr->name, curr->iface);
774 goto error;
775 }
6dd67645 776 control = devm_kzalloc(module->dev, sizeof(struct
6339d232
VA
777 gbaudio_control),
778 GFP_KERNEL);
779 if (!control) {
780 ret = -ENOMEM;
781 goto error;
782 }
783 control->id = curr->id;
6dd67645
VA
784 /* Prefix dev_id to widget_name */
785 strlcpy(temp_name, curr->name, NAME_SIZE);
786 snprintf(curr->name, NAME_SIZE, "GB %d %s", module->dev_id,
787 temp_name);
6339d232
VA
788 control->name = curr->name;
789 if (curr->info.type == GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED)
790 control->texts = (const char * const *)
791 curr->info.value.enumerated.names;
6dd67645
VA
792 list_add(&control->list, &module->ctl_list);
793 dev_dbg(module->dev, "%d:%s created of type %d\n", curr->id,
6339d232
VA
794 curr->name, curr->info.type);
795 curr++;
796 }
6dd67645 797 module->controls = dapm_kctls;
6339d232
VA
798
799 return 0;
800error:
6dd67645 801 list_for_each_entry_safe(control, _control, &module->ctl_list,
6339d232
VA
802 list) {
803 list_del(&control->list);
6dd67645 804 devm_kfree(module->dev, control);
6339d232 805 }
6dd67645 806 devm_kfree(module->dev, dapm_kctls);
6339d232
VA
807 return ret;
808}
809
6dd67645 810static int gbaudio_tplg_process_widgets(struct gbaudio_module_info *module,
6339d232
VA
811 struct gb_audio_widget *widgets)
812{
813 int i, ret, ncontrols;
814 struct snd_soc_dapm_widget *dapm_widgets;
815 struct gb_audio_widget *curr;
816 struct gbaudio_widget *widget, *_widget;
817 size_t size;
818
6dd67645
VA
819 size = sizeof(struct snd_soc_dapm_widget) * module->num_dapm_widgets;
820 dapm_widgets = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
821 if (!dapm_widgets)
822 return -ENOMEM;
823
824 curr = widgets;
6dd67645
VA
825 for (i = 0; i < module->num_dapm_widgets; i++) {
826 ret = gbaudio_tplg_create_widget(module, &dapm_widgets[i],
6339d232
VA
827 curr);
828 if (ret) {
6dd67645 829 dev_err(module->dev, "%s:%d type not supported\n",
6339d232
VA
830 curr->name, curr->type);
831 goto error;
832 }
6dd67645 833 widget = devm_kzalloc(module->dev, sizeof(struct
6339d232
VA
834 gbaudio_widget),
835 GFP_KERNEL);
836 if (!widget) {
837 ret = -ENOMEM;
838 goto error;
839 }
840 widget->id = curr->id;
841 widget->name = curr->name;
6dd67645 842 list_add(&widget->list, &module->widget_list);
6339d232
VA
843 ncontrols = curr->ncontrols;
844 curr++;
6da549ec 845 curr = (void *)curr + ncontrols*sizeof(struct gb_audio_control);
6339d232 846 }
6dd67645 847 module->dapm_widgets = dapm_widgets;
6339d232
VA
848
849 return 0;
850
851error:
6dd67645 852 list_for_each_entry_safe(widget, _widget, &module->widget_list,
6339d232
VA
853 list) {
854 list_del(&widget->list);
6dd67645 855 devm_kfree(module->dev, widget);
6339d232 856 }
6dd67645 857 devm_kfree(module->dev, dapm_widgets);
6339d232
VA
858 return ret;
859}
860
6dd67645 861static int gbaudio_tplg_process_routes(struct gbaudio_module_info *module,
6339d232
VA
862 struct gb_audio_route *routes)
863{
864 int i, ret;
865 struct snd_soc_dapm_route *dapm_routes;
866 struct gb_audio_route *curr;
867 size_t size;
868
6dd67645
VA
869 size = sizeof(struct snd_soc_dapm_route) * module->num_dapm_routes;
870 dapm_routes = devm_kzalloc(module->dev, size, GFP_KERNEL);
6339d232
VA
871 if (!dapm_routes)
872 return -ENOMEM;
873
874
6dd67645 875 module->dapm_routes = dapm_routes;
6339d232
VA
876 curr = routes;
877
6dd67645 878 for (i = 0; i < module->num_dapm_routes; i++) {
6339d232 879 dapm_routes->sink =
6dd67645 880 gbaudio_map_widgetid(module, curr->destination_id);
6339d232 881 if (!dapm_routes->sink) {
6dd67645 882 dev_err(module->dev, "%d:%d:%d:%d - Invalid sink\n",
6339d232
VA
883 curr->source_id, curr->destination_id,
884 curr->control_id, curr->index);
885 ret = -EINVAL;
886 goto error;
887 }
888 dapm_routes->source =
6dd67645 889 gbaudio_map_widgetid(module, curr->source_id);
6339d232 890 if (!dapm_routes->source) {
6dd67645 891 dev_err(module->dev, "%d:%d:%d:%d - Invalid source\n",
6339d232
VA
892 curr->source_id, curr->destination_id,
893 curr->control_id, curr->index);
894 ret = -EINVAL;
895 goto error;
896 }
897 dapm_routes->control =
6dd67645 898 gbaudio_map_controlid(module,
6339d232
VA
899 curr->control_id,
900 curr->index);
901 if ((curr->control_id != GBAUDIO_INVALID_ID) &&
902 !dapm_routes->control) {
6dd67645 903 dev_err(module->dev, "%d:%d:%d:%d - Invalid control\n",
6339d232
VA
904 curr->source_id, curr->destination_id,
905 curr->control_id, curr->index);
906 ret = -EINVAL;
907 goto error;
908 }
6dd67645 909 dev_dbg(module->dev, "Route {%s, %s, %s}\n", dapm_routes->sink,
6339d232
VA
910 (dapm_routes->control) ? dapm_routes->control:"NULL",
911 dapm_routes->source);
912 dapm_routes++;
913 curr++;
914 }
915
916 return 0;
917
918error:
6dd67645 919 devm_kfree(module->dev, dapm_routes);
6339d232
VA
920 return ret;
921}
922
6dd67645 923static int gbaudio_tplg_process_header(struct gbaudio_module_info *module,
6339d232
VA
924 struct gb_audio_topology *tplg_data)
925{
926 /* fetch no. of kcontrols, widgets & routes */
6dd67645
VA
927 module->num_controls = tplg_data->num_controls;
928 module->num_dapm_widgets = tplg_data->num_widgets;
929 module->num_dapm_routes = tplg_data->num_routes;
6339d232
VA
930
931 /* update block offset */
6dd67645
VA
932 module->dai_offset = (unsigned long)&tplg_data->data;
933 module->control_offset = module->dai_offset + tplg_data->size_dais;
934 module->widget_offset = module->control_offset +
6339d232 935 tplg_data->size_controls;
6dd67645 936 module->route_offset = module->widget_offset +
6339d232
VA
937 tplg_data->size_widgets;
938
6dd67645
VA
939 dev_dbg(module->dev, "DAI offset is 0x%lx\n", module->dai_offset);
940 dev_dbg(module->dev, "control offset is %lx\n",
941 module->control_offset);
942 dev_dbg(module->dev, "widget offset is %lx\n", module->widget_offset);
943 dev_dbg(module->dev, "route offset is %lx\n", module->route_offset);
6339d232
VA
944
945 return 0;
946}
947
6dd67645 948int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
6339d232
VA
949 struct gb_audio_topology *tplg_data)
950{
951 int ret;
6339d232
VA
952 struct gb_audio_control *controls;
953 struct gb_audio_widget *widgets;
954 struct gb_audio_route *routes;
955
956 if (!tplg_data)
957 return -EINVAL;
958
6dd67645 959 ret = gbaudio_tplg_process_header(module, tplg_data);
6339d232 960 if (ret) {
6dd67645 961 dev_err(module->dev, "%d: Error in parsing topology header\n",
6339d232
VA
962 ret);
963 return ret;
964 }
965
966 /* process control */
6dd67645
VA
967 controls = (struct gb_audio_control *)module->control_offset;
968 ret = gbaudio_tplg_process_kcontrols(module, controls);
6339d232 969 if (ret) {
6dd67645 970 dev_err(module->dev,
6339d232
VA
971 "%d: Error in parsing controls data\n", ret);
972 return ret;
973 }
6dd67645 974 dev_dbg(module->dev, "Control parsing finished\n");
6339d232
VA
975
976 /* process widgets */
6dd67645
VA
977 widgets = (struct gb_audio_widget *)module->widget_offset;
978 ret = gbaudio_tplg_process_widgets(module, widgets);
6339d232 979 if (ret) {
6dd67645 980 dev_err(module->dev,
6339d232
VA
981 "%d: Error in parsing widgets data\n", ret);
982 return ret;
983 }
6dd67645 984 dev_dbg(module->dev, "Widget parsing finished\n");
6339d232
VA
985
986 /* process route */
6dd67645
VA
987 routes = (struct gb_audio_route *)module->route_offset;
988 ret = gbaudio_tplg_process_routes(module, routes);
6339d232 989 if (ret) {
6dd67645 990 dev_err(module->dev,
6339d232
VA
991 "%d: Error in parsing routes data\n", ret);
992 return ret;
993 }
6dd67645 994 dev_dbg(module->dev, "Route parsing finished\n");
6339d232
VA
995
996 return ret;
997}
998
6dd67645 999void gbaudio_tplg_release(struct gbaudio_module_info *module)
6339d232 1000{
6339d232
VA
1001 struct gbaudio_control *control, *_control;
1002 struct gbaudio_widget *widget, *_widget;
1003
6dd67645 1004 if (!module->topology)
6339d232
VA
1005 return;
1006
1007 /* release kcontrols */
6dd67645 1008 list_for_each_entry_safe(control, _control, &module->ctl_list,
6339d232
VA
1009 list) {
1010 list_del(&control->list);
6dd67645 1011 devm_kfree(module->dev, control);
6339d232 1012 }
6dd67645
VA
1013 if (module->controls)
1014 devm_kfree(module->dev, module->controls);
6339d232
VA
1015
1016 /* release widget controls */
6dd67645 1017 list_for_each_entry_safe(control, _control, &module->widget_ctl_list,
6339d232
VA
1018 list) {
1019 list_del(&control->list);
6dd67645 1020 devm_kfree(module->dev, control);
6339d232
VA
1021 }
1022
1023 /* release widgets */
6dd67645 1024 list_for_each_entry_safe(widget, _widget, &module->widget_list,
6339d232
VA
1025 list) {
1026 list_del(&widget->list);
6dd67645 1027 devm_kfree(module->dev, widget);
6339d232 1028 }
6dd67645
VA
1029 if (module->dapm_widgets)
1030 devm_kfree(module->dev, module->dapm_widgets);
6339d232
VA
1031
1032 /* release routes */
6dd67645
VA
1033 if (module->dapm_routes)
1034 devm_kfree(module->dev, module->dapm_routes);
6339d232 1035}