forked from thesofproject/sof
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontrol.c
More file actions
152 lines (135 loc) · 4.28 KB
/
control.c
File metadata and controls
152 lines (135 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2019 Intel Corporation. All rights reserved.
//
// Author: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
/* Topology parser */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <errno.h>
#include <string.h>
#include <ipc/topology.h>
#include <sof/lib/uuid.h>
#include <sof/ipc/topology.h>
#include <tplg_parser/topology.h>
#include <tplg_parser/tokens.h>
int tplg_get_single_control(struct tplg_context *ctx,
struct snd_soc_tplg_ctl_hdr **ctl,
struct snd_soc_tplg_private **priv_data)
{
struct snd_soc_tplg_ctl_hdr *ctl_hdr;
struct snd_soc_tplg_mixer_control *mixer_ctl = NULL;
struct snd_soc_tplg_enum_control *enum_ctl = NULL;
struct snd_soc_tplg_bytes_control *bytes_ctl = NULL;
/* These are set if success */
*ctl = NULL;
*priv_data = NULL;
ctl_hdr = tplg_get(ctx);
/* load control based on type */
switch (ctl_hdr->ops.info) {
case SND_SOC_TPLG_CTL_VOLSW:
case SND_SOC_TPLG_CTL_STROBE:
case SND_SOC_TPLG_CTL_VOLSW_SX:
case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
case SND_SOC_TPLG_CTL_RANGE:
case SND_SOC_TPLG_DAPM_CTL_VOLSW:
/* load mixer type control */
mixer_ctl = (struct snd_soc_tplg_mixer_control *)ctl_hdr;
if (priv_data)
*priv_data = &mixer_ctl->priv;
/* ctl is after private data */
*ctl = tplg_get_object_priv(ctx, mixer_ctl, mixer_ctl->priv.size);
break;
case SND_SOC_TPLG_CTL_ENUM:
case SND_SOC_TPLG_CTL_ENUM_VALUE:
case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
/* load enum type control */
enum_ctl = (struct snd_soc_tplg_enum_control *)ctl_hdr;
if (priv_data)
*priv_data = &enum_ctl->priv;
/* ctl is after private data */
*ctl = tplg_get_object_priv(ctx, enum_ctl, enum_ctl->priv.size);
break;
case SND_SOC_TPLG_CTL_BYTES:
/* load bytes type control */
bytes_ctl = (struct snd_soc_tplg_bytes_control *)ctl_hdr;
if (priv_data)
*priv_data = &bytes_ctl->priv;
/* ctl is after private data */
*ctl = tplg_get_object_priv(ctx, bytes_ctl, bytes_ctl->priv.size);
break;
default:
printf("info: control type %d not supported\n",
ctl_hdr->ops.info);
return -EINVAL;
}
return 0;
}
/* load dapm widget kcontrols
* we don't use controls in the fuzzer atm.
* so just skip to the next dapm widget
*/
int tplg_create_controls(struct tplg_context *ctx, int num_kcontrols,
struct snd_soc_tplg_ctl_hdr *rctl,
size_t max_ctl_size, void *object)
{
struct snd_soc_tplg_ctl_hdr *ctl_hdr = NULL;
struct snd_soc_tplg_mixer_control *mixer_ctl;
struct snd_soc_tplg_enum_control *enum_ctl;
struct snd_soc_tplg_bytes_control *bytes_ctl;
int j, ret = 0;
for (j = 0; j < num_kcontrols; j++) {
ctl_hdr = tplg_get(ctx);
/* load control based on type */
switch (ctl_hdr->ops.info) {
case SND_SOC_TPLG_CTL_VOLSW:
case SND_SOC_TPLG_CTL_STROBE:
case SND_SOC_TPLG_CTL_VOLSW_SX:
case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
case SND_SOC_TPLG_CTL_RANGE:
case SND_SOC_TPLG_DAPM_CTL_VOLSW:
/* load mixer type control */
mixer_ctl = (struct snd_soc_tplg_mixer_control *)ctl_hdr;
/* ctl is after private data */
tplg_get_object_priv(ctx, mixer_ctl, mixer_ctl->priv.size);
break;
case SND_SOC_TPLG_CTL_ENUM:
case SND_SOC_TPLG_CTL_ENUM_VALUE:
case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
/* load enum_ctl type control */
enum_ctl = (struct snd_soc_tplg_enum_control *)ctl_hdr;
/* ctl is after private data */
tplg_get_object_priv(ctx, enum_ctl, enum_ctl->priv.size);
break;
case SND_SOC_TPLG_CTL_BYTES:
/* load bytes_ctl type control */
bytes_ctl = (struct snd_soc_tplg_bytes_control *)ctl_hdr;
/* ctl is after private data */
tplg_get_object_priv(ctx, bytes_ctl, bytes_ctl->priv.size);
break;
default:
printf("info: control type %d not supported\n",
ctl_hdr->ops.info);
return -EINVAL;
}
if (ctx->ctl_cb && object)
ctx->ctl_cb(ctl_hdr, object, ctx->ctl_arg);
}
if (rctl && ctl_hdr) {
/* make sure the CTL will fit if we need to copy it for others */
if (ctl_hdr->size > max_ctl_size) {
fprintf(stderr, "error: failed control control copy\n");
ret = -EINVAL;
goto err;
}
memcpy(rctl, ctl_hdr, ctl_hdr->size);
}
err:
return ret;
}