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