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 #define SAPM_POLL_TIME 10000 /* 10s */ 21 #define SAPM_SLEEP_TIME (3 * 60000) /* 3min */ 22 23 #define MIXER_REG_ADDR 10 /* mixer address -- Temporarily defined as this value */ 24 25 #define SAPM_POWER_DOWN 0 26 #define SAPM_POWER_UP 1 27 28 #define CONNECT_CODEC_PIN 1 29 #define UNCONNECT_CODEC_PIN 0 30 31 #define EXIST_EXTERNAL_WIDGET 1 32 #define UNEXIST_EXTERNAL_WIDGET 1 33 34 #define CONNECT_SINK_AND_SOURCE 1 35 #define UNCONNECT_SINK_AND_SOURCE 0 36 37 /* sapm widget types */ 38 enum AudioSapmType { 39 AUDIO_SAPM_INPUT = 0, /* input pin */ 40 AUDIO_SAPM_OUTPUT, /* output pin */ 41 AUDIO_SAPM_MUX, /* selects 1 analog signal from many inputs */ 42 AUDIO_SAPM_VIRT_MUX, /* virtual version of snd_soc_dapm_mux */ 43 AUDIO_SAPM_VALUE_MUX, /* selects 1 analog signal from many inputs */ 44 AUDIO_SAPM_MIXER, /* mixes several analog signals together */ 45 AUDIO_SAPM_MIXER_NAMED_CTRL, /* mixer with named controls */ 46 AUDIO_SAPM_PGA, /* programmable gain/attenuation (volume) */ 47 AUDIO_SAPM_OUT_DRV, /* output driver */ 48 AUDIO_SAPM_ADC, /* analog to digital converter */ 49 AUDIO_SAPM_DAC, /* digital to analog converter */ 50 AUDIO_SAPM_MICBIAS, /* microphone bias (power) */ 51 AUDIO_SAPM_MIC, /* microphone */ 52 AUDIO_SAPM_HP, /* headphones */ 53 AUDIO_SAPM_SPK, /* speaker */ 54 AUDIO_SAPM_LINE, /* line input/output */ 55 AUDIO_SAPM_ANALOG_SWITCH, /* analog switch */ 56 AUDIO_SAPM_VMID, /* codec bias/vmid - to minimise pops */ 57 AUDIO_SAPM_PRE, /* machine specific pre component - exec first */ 58 AUDIO_SAPM_POST, /* machine specific post component - exec last */ 59 AUDIO_SAPM_SUPPLY, /* power/clock supply */ 60 AUDIO_SAPM_AIF_IN, /* audio interface input */ 61 AUDIO_SAPM_AIF_OUT, /* audio interface output */ 62 }; 63 64 /* component has no PM register bit */ 65 #define AUDIO_SAPM_NOPM (-1) 66 67 /* dapm stream operations */ 68 #define AUDIO_SAPM_STREAM_NOP 0x0 69 #define AUDIO_SAPM_STREAM_START 0x1 70 #define AUDIO_SAPM_STREAM_STOP 0x2 71 #define AUDIO_SAPM_STREAM_SUSPEND 0x4 72 #define AUDIO_SAPM_STREAM_RESUME 0x8 73 #define AUDIO_SAPM_STREAM_PAUSE_PUSH 0x10 74 #define AUDIO_SAPM_STREAM_PAUSE_RELEASE 0x20 75 76 /* sapm event types */ 77 #define AUDIO_SAPM_PRE_PMU 0x1 /* before component power up */ 78 #define AUDIO_SAPM_POST_PMU 0x2 /* after component power up */ 79 #define AUDIO_SAPM_PRE_PMD 0x4 /* before component power down */ 80 #define AUDIO_SAPM_POST_PMD 0x8 /* after component power down */ 81 #define AUDIO_SAPM_PRE_REG 0x10 /* before audio path setup */ 82 #define AUDIO_SAPM_POST_REG 0x20 /* after audio path setup */ 83 #define AUDIO_SAPM_PRE_POST_PMD (AUDIO_SAPM_PRE_PMD | AUDIO_SAPM_POST_PMD) 84 85 enum AudioBiasLevel { 86 AUDIO_BIAS_OFF = 0, 87 AUDIO_BIAS_STANDBY = 1, 88 AUDIO_BIAS_PREPARE = 2, 89 AUDIO_BIAS_ON = 3, 90 }; 91 92 /* SAPM context */ 93 struct AudioSapmContext { 94 int32_t componentNum; /* number of components in this context */ 95 enum AudioBiasLevel biasLevel; 96 enum AudioBiasLevel suspendBiasLevel; 97 98 struct CodecDevice *codec; /* parent codec */ 99 struct PlatformDevice *platform; /* parent platform */ 100 struct AudioCard *card; /* parent card */ 101 102 /* used during SAPM updates */ 103 enum AudioBiasLevel targetBiasLevel; 104 struct DListHead list; 105 }; 106 107 /* enumerated kcontrol */ 108 struct AudioEnumKcontrol { 109 uint32_t reg; 110 uint32_t reg2; 111 uint8_t shiftLeft; 112 uint8_t shiftRight; 113 uint32_t max; 114 uint32_t mask; 115 const char * const *texts; 116 const uint32_t *values; 117 void *sapm; 118 }; 119 120 /* sapm audio path between two components */ 121 struct AudioSapmpath { 122 char *name; 123 124 /* source (input) and sink (output) components */ 125 struct AudioSapmComponent *source; 126 struct AudioSapmComponent *sink; 127 struct AudioKcontrol *kcontrol; 128 129 /* status */ 130 uint8_t connect; /* source and sink components are connected */ 131 uint8_t walked; /* path has been walked */ 132 uint8_t weak; /* path ignored for power management */ 133 134 int32_t (*connected)(struct AudioSapmComponent *source, struct AudioSapmComponent *sink); 135 136 struct DListHead listSource; 137 struct DListHead listSink; 138 struct DListHead list; 139 }; 140 141 /* sapm component */ 142 struct AudioSapmComponent { 143 enum AudioSapmType sapmType; 144 char *componentName; /* component name */ 145 char *streamName; /* stream name */ 146 struct AudioSapmContext *sapm; 147 struct CodecDevice *codec; /* parent codec */ 148 struct AccessoryDevice *accessory; /* parent accessory */ 149 struct PlatformDevice *platform; /* parent platform */ 150 151 /* sapm control */ 152 int16_t reg; /* negative reg = no direct sapm */ 153 uint8_t shift; /* bits to shift */ 154 uint8_t invert; /* invert the power bit */ 155 uint8_t mask; 156 uint8_t connected; /* connected codec pin */ 157 uint8_t external; /* has external components */ 158 uint8_t active; /* active stream on DAC, ADC's */ 159 uint8_t newPower; /* power checked this run */ 160 uint8_t power; 161 uint8_t newCpt; 162 163 /* external events */ 164 uint16_t eventFlags; /* flags to specify event types */ 165 int32_t (*Event)(struct AudioSapmComponent*, struct AudioKcontrol *, int32_t); 166 167 /* power check callback */ 168 int32_t (*PowerCheck)(const struct AudioSapmComponent *); 169 170 /* kcontrols that relate to this component */ 171 int32_t kcontrolsNum; 172 struct AudioKcontrol *kcontrolNews; 173 struct AudioKcontrol **kcontrols; 174 175 struct DListHead list; 176 177 /* component input and outputs */ 178 struct DListHead sources; 179 struct DListHead sinks; 180 181 /* used during SAPM updates */ 182 struct DListHead powerList; 183 struct DListHead dirty; 184 185 /* reserve clock interface */ 186 int32_t (*PowerClockOp)(struct AudioSapmComponent *); 187 }; 188 189 struct AudioSapmRoute { 190 const char *sink; 191 const char *control; 192 const char *source; 193 194 /* Note: currently only supported for links where source is a supply */ 195 uint32_t (*Connected)(struct AudioSapmComponent *source, 196 struct AudioSapmComponent *sink); 197 }; 198 199 int32_t AudioSapmNewComponents(struct AudioCard *audioCard, 200 const struct AudioSapmComponent *component, int32_t cptMaxNum); 201 int32_t AudioSapmAddRoutes(struct AudioCard *audioCard, 202 const struct AudioSapmRoute *route, int32_t routeMaxNum); 203 int32_t AudioSapmNewControls(struct AudioCard *audioCard); 204 int AudioSapmPowerComponents(struct AudioCard *audioCard); 205 int32_t AudioSapmSleep(const struct AudioCard *audioCard); 206 uint64_t AudioSapmRefreshTime(bool bRefresh); 207 int32_t AudioSampPowerUp(const struct AudioCard *card); 208 int32_t AudioSampSetPowerMonitor(struct AudioCard *card, bool powerMonitorState); 209 210 int32_t AudioCodecSapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue); 211 int32_t AudioCodecSapmGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue); 212 int32_t AudioAccessorySapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue); 213 int32_t AudioAccessorySapmGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue); 214 215 #ifdef __cplusplus 216 #if __cplusplus 217 } 218 #endif 219 #endif /* __cplusplus */ 220 221 #endif /* AUDIO_SAPM_H */ 222