1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #ifndef AUDIO_SAPM_H
10 #define AUDIO_SAPM_H
11 
12 #include "audio_core.h"
13 
14 #ifdef __cplusplus
15 #if __cplusplus
16 extern "C" {
17 #endif
18 #endif /* __cplusplus */
19 
20 /* component has no sapm register bit */
21 #define AUDIO_NO_SAPM_REG   0xFFFF
22 
23 /* sapm widget types */
24 enum AudioSapmType {
25     AUDIO_SAPM_INPUT = 0,       /* 0 input pin */
26     AUDIO_SAPM_OUTPUT,          /* 1 output pin */
27     AUDIO_SAPM_MUX,             /* 2 selects 1 analog signal from many inputs */
28     AUDIO_SAPM_DEMUX,           /* 3 connects the input to one of multiple outputs */
29     AUDIO_SAPM_VIRT_MUX,        /* 4 virtual version of snd_soc_dapm_mux */
30     AUDIO_SAPM_VALUE_MUX,       /* 5 selects 1 analog signal from many inputs */
31     AUDIO_SAPM_MIXER,           /* 6 mixes several analog signals together */
32     AUDIO_SAPM_MIXER_NAMED_CTRL, /* 7 mixer with named controls */
33     AUDIO_SAPM_PGA,             /* 8 programmable gain/attenuation (volume) */
34     AUDIO_SAPM_OUT_DRV,         /* 9 output driver */
35     AUDIO_SAPM_ADC,             /* 10 analog to digital converter */
36     AUDIO_SAPM_DAC,             /* 11 digital to analog converter */
37     AUDIO_SAPM_MICBIAS,         /* 12 microphone bias (power) */
38     AUDIO_SAPM_MIC,             /* 13 microphone */
39     AUDIO_SAPM_HP,              /* 14 headphones */
40     AUDIO_SAPM_SPK,             /* 15 speaker */
41     AUDIO_SAPM_LINE,            /* 16 line input/output */
42     AUDIO_SAPM_ANALOG_SWITCH,   /* 17 analog switch */
43     AUDIO_SAPM_VMID,            /* 18 codec bias/vmid - to minimise pops */
44     AUDIO_SAPM_PRE,             /* 19 machine specific pre component - exec first */
45     AUDIO_SAPM_POST,            /* 20 machine specific post component - exec last */
46     AUDIO_SAPM_SUPPLY,          /* 21 power/clock supply */
47     AUDIO_SAPM_REGULATOR_SUPPLY, /* 22 external regulator */
48     AUDIO_SAPM_CLOCK_SUPPLY,    /* 23 external clock */
49     AUDIO_SAPM_AIF_IN,          /* 24 audio interface input */
50     AUDIO_SAPM_AIF_OUT,         /* 25 audio interface output */
51     AUDIO_SAPM_SIGGEN,          /* 26 signal generator */
52     AUDIO_SAPM_SINK,            /* 27 */
53 };
54 
55 enum AudioBiasLevel {
56     AUDIO_BIAS_OFF = 0,
57     AUDIO_BIAS_STANDBY = 1,
58     AUDIO_BIAS_PREPARE = 2,
59     AUDIO_BIAS_ON = 3,
60 };
61 
62 /* SAPM context */
63 struct AudioSapmContext {
64     int32_t componentNum; /* number of components in this context */
65     enum AudioBiasLevel biasLevel;
66     enum AudioBiasLevel suspendBiasLevel;
67 
68     struct CodecDevice *codec; /* parent codec */
69     struct PlatformDevice *platform; /* parent platform */
70     struct AudioCard *card; /* parent card */
71 
72     /* used during SAPM updates */
73     enum AudioBiasLevel targetBiasLevel;
74     struct DListHead list;
75 };
76 
77 /* sapm audio path between two components */
78 struct AudioSapmpath {
79     char *name;
80 
81     /* source (input) and sink (output) components */
82     struct AudioSapmComponent *source;
83     struct AudioSapmComponent *sink;
84     struct AudioKcontrol *kcontrol;
85 
86     /* status */
87     uint8_t connect; /* source and sink components are connected */
88     uint8_t walked; /* path has been walked */
89     uint8_t weak; /* path ignored for power management */
90 
91     int32_t (*connected)(struct AudioSapmComponent *source, struct AudioSapmComponent *sink);
92 
93     struct DListHead listSource;
94     struct DListHead listSink;
95     struct DListHead list;
96 };
97 
98 /* sapm component */
99 struct AudioSapmComponent {
100     enum AudioSapmType sapmType;
101     char *componentName; /* component name */
102     char *streamName; /* stream name */
103     struct AudioSapmContext *sapm;
104     struct CodecDevice *codec; /* parent codec */
105     struct PlatformDevice *platform; /* parent platform */
106 
107     /* sapm control */
108     uint32_t reg; /* negative reg = no direct sapm */
109     uint8_t shift; /* bits to shift */
110     uint8_t invert; /* invert the power bit */
111     uint32_t mask;
112     uint8_t connected; /* connected codec pin */
113     uint8_t external; /* has external components */
114     uint8_t active; /* active stream on DAC, ADC's */
115     uint8_t newPower; /* power checked this run */
116     uint8_t power;
117     uint8_t newCpt;
118 
119     /* external events */
120     uint16_t eventFlags;   /* flags to specify event types */
121     int32_t (*Event)(struct AudioSapmComponent*, struct AudioKcontrol *, int32_t);
122 
123     /* power check callback */
124     int32_t (*PowerCheck)(const struct AudioSapmComponent *);
125 
126     /* kcontrols that relate to this component */
127     int32_t kcontrolsNum;
128     struct AudioKcontrol *kcontrolNews;
129     struct AudioKcontrol **kcontrols;
130 
131     struct DListHead list;
132 
133     /* component input and outputs */
134     struct DListHead sources;
135     struct DListHead sinks;
136 
137     /* used during SAPM updates */
138     struct DListHead powerList;
139     struct DListHead dirty;
140 
141     /* reserve clock interface */
142     int32_t (*PowerClockOp)(struct AudioSapmComponent *);
143 };
144 
145 struct AudioSapmRoute {
146     const char *sink;
147     const char *control;
148     const char *source;
149 
150     /* Note: currently only supported for links where source is a supply */
151     uint32_t (*Connected)(struct AudioSapmComponent *source,
152         struct AudioSapmComponent *sink);
153 };
154 
155 int32_t AudioSapmNewComponents(struct AudioCard *audioCard,
156     const struct AudioSapmComponent *component, int32_t cptMaxNum);
157 int32_t AudioSapmAddRoutes(struct AudioCard *audioCard,
158     const struct AudioSapmRoute *route, int32_t routeMaxNum);
159 int32_t AudioSapmNewControls(struct AudioCard *audioCard);
160 int32_t AudioSapmSleep(struct AudioCard *audioCard);
161 int32_t AudioSampPowerUp(const struct AudioCard *card);
162 int32_t AudioSampSetPowerMonitor(struct AudioCard *card, bool powerMonitorState);
163 
164 int32_t AudioCodecSapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue);
165 int32_t AudioCodecSapmGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue);
166 int32_t AudioCodecSapmSetEnumCtrlOps(const struct AudioKcontrol *kcontrol,
167     const struct AudioCtrlElemValue *elemValue);
168 int32_t AudioCodecSapmGetEnumCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue);
169 
170 #ifdef __cplusplus
171 #if __cplusplus
172 }
173 #endif
174 #endif /* __cplusplus */
175 
176 #endif /* AUDIO_SAPM_H */
177