1 /* 2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited 3 */ 4 5 #ifndef CONTROL_H 6 #define CONTROL_H 7 8 #include <stdio.h> 9 #include <aos/list.h> 10 #include "control_dev.h" 11 12 #ifdef __cplusplus 13 extern "C" { 14 #endif 15 16 struct audio_kcontrol; 17 struct audio_mixer_control; 18 19 #define AOS_CTL_ELEM_TYPE_NONE (1 << 0) /* invalid */ 20 #define AOS_CTL_ELEM_TYPE_BOOLEAN (1 << 1) /* boolean type */ 21 #define AOS_CTL_ELEM_TYPE_INTEGER (1 << 2) /* integer type */ 22 #define AOS_CTL_ELEM_TYPE_ENUMERATED (1 << 3) /* enumerated type */ 23 #define AOS_CTL_ELEM_TYPE_BYTES (1 << 4) /* byte array */ 24 #define AOS_CTL_ELEM_TYPE_IEC958 (1 << 5) /* IEC958 (S/PDIF) setup */ 25 #define AOS_CTL_ELEM_TYPE_INTEGER64 (1 << 6) /* 64-bit integer type */ 26 #define AOS_CTL_ELEM_TYPE_LAST AOS_CTL_ELEM_TYPE_INTEGER64 27 28 #define AOS_CTL_ELEM_IFACE_MIXER (1 << 2) /* virtual mixer device */ 29 #define AOS_CTL_ELEM_IFACE_LAST AOS_CTL_ELEM_IFACE_MIXER 30 31 #define AOS_CTL_ELEM_ACCESS_READ (1<<0) 32 #define AOS_CTL_ELEM_ACCESS_WRITE (1<<1) 33 #define AOS_CTL_ELEM_ACCESS_READWRITE (AOS_CTL_ELEM_ACCESS_READ|AOS_CTL_ELEM_ACCESS_WRITE) 34 35 #define AOS_DOUBLE_VALUE(sreg, left, right, smax, sinvert, sautodisable) \ 36 ((unsigned long)&(struct audio_mixer_control) \ 37 {.reg = sreg, .rreg = sreg, .shift = left, \ 38 .rshift = right, .max = smax, .platform_max = smax, \ 39 .invert = sinvert, .autodisable = sautodisable}) 40 41 #define AOS_SINGLE_VALUE(reg, shift, max, invert, autodisable) \ 42 AOS_DOUBLE_VALUE(reg, shift, shift, max, invert, autodisable) 43 44 #define SOC_SINGLE_EXT(sname, reg, shift, max, invert, handler_get, handler_put) \ 45 { .iface = AOS_CTL_ELEM_IFACE_MIXER, \ 46 .name = sname, \ 47 .info = get_integer_info, \ 48 .get = handler_get, \ 49 .put = handler_put, \ 50 .private_value = AOS_SINGLE_VALUE(reg, shift, max, invert, 0) \ 51 } 52 53 #define SOC_DOUBLE_EXT(sname, reg, left, right, max, invert, handler_get, handler_put) \ 54 { .iface = AOS_CTL_ELEM_IFACE_MIXER, \ 55 .name = (sname),\ 56 .info = get_integer_info, \ 57 .get = handler_get, \ 58 .put = handler_put, \ 59 .private_value = AOS_DOUBLE_VALUE(reg, left, right, max, invert, 0) \ 60 } 61 62 struct audio_ctl_card_info { 63 int card; /* card number */ 64 unsigned char driverName[16]; /* Driver name */ 65 unsigned char shortName[32]; /* Short name of card */ 66 unsigned char longName[64]; /* long name about card */ 67 unsigned char mixerName[64]; /* visual mixer name */ 68 unsigned char components[64]; /* card components info */ 69 }; 70 71 struct audio_ctl_elem_id { 72 unsigned int id; /* element id, zero = invalid */ 73 int iface; /* interface id */ 74 unsigned int deviceId; /* device number */ 75 unsigned int subdeviceId; /* subdevice (substream) number */ 76 char name[64]; /* name of item */ 77 unsigned int index; /* index of item */ 78 }; 79 80 struct audio_ctl_elem_list { 81 struct audio_ctl_elem_id *pids; /* R: IDs */ 82 unsigned int offset; /* W: first element offset */ 83 unsigned int space; /* W: element count to get */ 84 unsigned int used; /* R: element count been set */ 85 unsigned int count; /* R: total elements count */ 86 }; 87 88 struct audio_ctl_elem_info { 89 struct audio_ctl_elem_id id; /* W: element ID */ 90 int type; /* R: AOS_CTL_ELEM_TYPE_* */ 91 unsigned int access; /* R: AOS_CTL_ELEM_ACCESS_* */ 92 unsigned int count; /* count of values */ 93 union { 94 struct { 95 long min; /* R: min value */ 96 long max; /* R: max value */ 97 long step; /* R: step */ 98 } integer; 99 struct { 100 long long min; /* R: min value */ 101 long long max; /* R: max value */ 102 long long step; /* R: step */ 103 } integer64; 104 } value; 105 }; 106 107 struct audio_ctl_elem_value { 108 struct audio_ctl_elem_id id; /* W: element ID */ 109 union { 110 union { 111 long value[64]; 112 } integer; 113 union { 114 long long value[64]; 115 } integer64; 116 union { 117 unsigned char data[512]; 118 } bytes; 119 } value; /* RO */ 120 }; 121 122 struct audio_ctl_tlv { 123 unsigned int numid; /* control element numeric identification */ 124 unsigned int len; /* in bytes aligned to 4 */ 125 unsigned int tlv[0]; /* first TLV */ 126 }; 127 128 /* mixer control */ 129 typedef int (audio_kcontrol_info_t) (struct audio_kcontrol * kcontrol, struct audio_ctl_elem_info * uinfo); 130 typedef int (audio_kcontrol_get_t) (struct audio_kcontrol * kcontrol, struct audio_ctl_elem_value * ucontrol); 131 typedef int (audio_kcontrol_put_t) (struct audio_kcontrol * kcontrol, struct audio_ctl_elem_value * ucontrol); 132 typedef int (audio_kcontrol_tlv_rw_t)(struct audio_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int *tlv); 133 134 135 struct audio_mixer_control { 136 int min, max, platform_max; 137 int reg, rreg; 138 unsigned int shift, rshift; 139 unsigned int sign_bit; 140 unsigned int invert:1; 141 unsigned int autodisable:1; 142 }; 143 144 struct audio_kcontrol_volatile { 145 void *owner; /* locked */ 146 unsigned int access; /* access rights */ 147 }; 148 149 struct audio_kcontrol_new { 150 unsigned int iface; /* interface identifier */ 151 const char *name; /* ASCII name of item */ 152 audio_kcontrol_info_t *info; 153 audio_kcontrol_get_t *get; 154 audio_kcontrol_put_t *put; 155 union { 156 audio_kcontrol_tlv_rw_t *c; 157 const unsigned int *p; 158 } tlv; 159 unsigned long private_value; 160 161 unsigned int deviceId; /* device ID*/ 162 unsigned int subdeviceId; /* subdevice ID */ 163 unsigned int index; /* index of item */ 164 unsigned int access; /* access rights */ 165 unsigned int count; /* count of same elements */ 166 }; 167 168 struct audio_kcontrol { 169 struct dlist_s list; /* list of controls */ 170 struct audio_ctl_elem_id id; 171 unsigned int count; /* count of same elements */ 172 audio_kcontrol_info_t *info; 173 audio_kcontrol_get_t *get; 174 audio_kcontrol_put_t *put; 175 union { 176 audio_kcontrol_tlv_rw_t *c; 177 const unsigned int *p; 178 } tlv; 179 unsigned long private_value; 180 void *private_data; 181 void (*private_free)(struct audio_kcontrol *kcontrol); 182 struct audio_kcontrol_volatile vd[0]; /* volatile data */ 183 }; 184 185 enum { 186 AOS_CTL_TLV_OP_READ = 0, 187 AOS_CTL_TLV_OP_WRITE = 1, 188 AOS_CTL_TLV_OP_CMD = -1, 189 }; 190 191 int get_integer_info(struct audio_kcontrol * kcontrol, struct audio_ctl_elem_info * uinfo); 192 int audio_ctl_card_info(ctrl_device_t *dev, struct audio_ctl_card_info *info); 193 int audio_ctl_elem_list(ctrl_device_t *dev, struct audio_ctl_elem_list *list); 194 int audio_ctl_elem_info(ctrl_device_t *dev, struct audio_ctl_elem_info *info); 195 int audio_ctl_elem_read(ctrl_device_t *dev, struct audio_ctl_elem_value *value); 196 int audio_ctl_elem_write(ctrl_device_t *dev, struct audio_ctl_elem_value *value); 197 int audio_ctl_tlv_ioctl(ctrl_device_t *dev, struct audio_ctl_tlv *tlv, int op_flag); 198 int audio_add_controls(ctrl_device_t *dev, const struct audio_kcontrol_new *controls, int num_controls, void *data); 199 200 #ifdef __cplusplus 201 } 202 #endif 203 204 #endif /* CONTROL_H */