1#ifndef __SOUND_PCM_PARAMS_H 2#define __SOUND_PCM_PARAMS_H 3 4/* 5 * PCM params helpers 6 * Copyright (c) by Abramo Bagnara <abramo@alsa-project.org> 7 * 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 */ 24 25int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, 26 struct snd_pcm_hw_params *params, 27 snd_pcm_hw_param_t var, int *dir); 28int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, 29 struct snd_pcm_hw_params *params, 30 snd_pcm_hw_param_t var, int *dir); 31int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, 32 snd_pcm_hw_param_t var, int *dir); 33 34#define SNDRV_MASK_BITS 64 /* we use so far 64bits only */ 35#define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32) 36#define MASK_OFS(i) ((i) >> 5) 37#define MASK_BIT(i) (1U << ((i) & 31)) 38 39static inline unsigned int ld2(u_int32_t v) 40{ 41 unsigned r = 0; 42 43 if (v >= 0x10000) { 44 v >>= 16; 45 r += 16; 46 } 47 if (v >= 0x100) { 48 v >>= 8; 49 r += 8; 50 } 51 if (v >= 0x10) { 52 v >>= 4; 53 r += 4; 54 } 55 if (v >= 4) { 56 v >>= 2; 57 r += 2; 58 } 59 if (v >= 2) 60 r++; 61 return r; 62} 63 64static inline size_t snd_mask_sizeof(void) 65{ 66 return sizeof(struct snd_mask); 67} 68 69static inline void snd_mask_none(struct snd_mask *mask) 70{ 71 memset(mask, 0, sizeof(*mask)); 72} 73 74static inline void snd_mask_any(struct snd_mask *mask) 75{ 76 memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 77} 78 79static inline int snd_mask_empty(const struct snd_mask *mask) 80{ 81 int i; 82 for (i = 0; i < SNDRV_MASK_SIZE; i++) 83 if (mask->bits[i]) 84 return 0; 85 return 1; 86} 87 88static inline unsigned int snd_mask_min(const struct snd_mask *mask) 89{ 90 int i; 91 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 92 if (mask->bits[i]) 93 return ffs(mask->bits[i]) - 1 + (i << 5); 94 } 95 return 0; 96} 97 98static inline unsigned int snd_mask_max(const struct snd_mask *mask) 99{ 100 int i; 101 for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) { 102 if (mask->bits[i]) 103 return ld2(mask->bits[i]) + (i << 5); 104 } 105 return 0; 106} 107 108static inline void snd_mask_set(struct snd_mask *mask, unsigned int val) 109{ 110 mask->bits[MASK_OFS(val)] |= MASK_BIT(val); 111} 112 113static inline void snd_mask_reset(struct snd_mask *mask, unsigned int val) 114{ 115 mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val); 116} 117 118static inline void snd_mask_set_range(struct snd_mask *mask, 119 unsigned int from, unsigned int to) 120{ 121 unsigned int i; 122 for (i = from; i <= to; i++) 123 mask->bits[MASK_OFS(i)] |= MASK_BIT(i); 124} 125 126static inline void snd_mask_reset_range(struct snd_mask *mask, 127 unsigned int from, unsigned int to) 128{ 129 unsigned int i; 130 for (i = from; i <= to; i++) 131 mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i); 132} 133 134static inline void snd_mask_leave(struct snd_mask *mask, unsigned int val) 135{ 136 unsigned int v; 137 v = mask->bits[MASK_OFS(val)] & MASK_BIT(val); 138 snd_mask_none(mask); 139 mask->bits[MASK_OFS(val)] = v; 140} 141 142static inline void snd_mask_intersect(struct snd_mask *mask, 143 const struct snd_mask *v) 144{ 145 int i; 146 for (i = 0; i < SNDRV_MASK_SIZE; i++) 147 mask->bits[i] &= v->bits[i]; 148} 149 150static inline int snd_mask_eq(const struct snd_mask *mask, 151 const struct snd_mask *v) 152{ 153 return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 154} 155 156static inline void snd_mask_copy(struct snd_mask *mask, 157 const struct snd_mask *v) 158{ 159 *mask = *v; 160} 161 162static inline int snd_mask_test(const struct snd_mask *mask, unsigned int val) 163{ 164 return mask->bits[MASK_OFS(val)] & MASK_BIT(val); 165} 166 167static inline int snd_mask_single(const struct snd_mask *mask) 168{ 169 int i, c = 0; 170 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 171 if (! mask->bits[i]) 172 continue; 173 if (mask->bits[i] & (mask->bits[i] - 1)) 174 return 0; 175 if (c) 176 return 0; 177 c++; 178 } 179 return 1; 180} 181 182static inline int snd_mask_refine(struct snd_mask *mask, 183 const struct snd_mask *v) 184{ 185 struct snd_mask old; 186 snd_mask_copy(&old, mask); 187 snd_mask_intersect(mask, v); 188 if (snd_mask_empty(mask)) 189 return -EINVAL; 190 return !snd_mask_eq(mask, &old); 191} 192 193static inline int snd_mask_refine_first(struct snd_mask *mask) 194{ 195 if (snd_mask_single(mask)) 196 return 0; 197 snd_mask_leave(mask, snd_mask_min(mask)); 198 return 1; 199} 200 201static inline int snd_mask_refine_last(struct snd_mask *mask) 202{ 203 if (snd_mask_single(mask)) 204 return 0; 205 snd_mask_leave(mask, snd_mask_max(mask)); 206 return 1; 207} 208 209static inline int snd_mask_refine_min(struct snd_mask *mask, unsigned int val) 210{ 211 if (snd_mask_min(mask) >= val) 212 return 0; 213 snd_mask_reset_range(mask, 0, val - 1); 214 if (snd_mask_empty(mask)) 215 return -EINVAL; 216 return 1; 217} 218 219static inline int snd_mask_refine_max(struct snd_mask *mask, unsigned int val) 220{ 221 if (snd_mask_max(mask) <= val) 222 return 0; 223 snd_mask_reset_range(mask, val + 1, SNDRV_MASK_BITS); 224 if (snd_mask_empty(mask)) 225 return -EINVAL; 226 return 1; 227} 228 229static inline int snd_mask_refine_set(struct snd_mask *mask, unsigned int val) 230{ 231 int changed; 232 changed = !snd_mask_single(mask); 233 snd_mask_leave(mask, val); 234 if (snd_mask_empty(mask)) 235 return -EINVAL; 236 return changed; 237} 238 239static inline int snd_mask_value(const struct snd_mask *mask) 240{ 241 return snd_mask_min(mask); 242} 243 244static inline void snd_interval_any(struct snd_interval *i) 245{ 246 i->min = 0; 247 i->openmin = 0; 248 i->max = UINT_MAX; 249 i->openmax = 0; 250 i->integer = 0; 251 i->empty = 0; 252} 253 254static inline void snd_interval_none(struct snd_interval *i) 255{ 256 i->empty = 1; 257} 258 259static inline int snd_interval_checkempty(const struct snd_interval *i) 260{ 261 return (i->min > i->max || 262 (i->min == i->max && (i->openmin || i->openmax))); 263} 264 265static inline int snd_interval_empty(const struct snd_interval *i) 266{ 267 return i->empty; 268} 269 270static inline int snd_interval_single(const struct snd_interval *i) 271{ 272 return (i->min == i->max || 273 (i->min + 1 == i->max && i->openmax)); 274} 275 276static inline int snd_interval_value(const struct snd_interval *i) 277{ 278 return i->min; 279} 280 281static inline int snd_interval_min(const struct snd_interval *i) 282{ 283 return i->min; 284} 285 286static inline int snd_interval_max(const struct snd_interval *i) 287{ 288 unsigned int v; 289 v = i->max; 290 if (i->openmax) 291 v--; 292 return v; 293} 294 295static inline int snd_interval_test(const struct snd_interval *i, unsigned int val) 296{ 297 return !((i->min > val || (i->min == val && i->openmin) || 298 i->max < val || (i->max == val && i->openmax))); 299} 300 301static inline void snd_interval_copy(struct snd_interval *d, const struct snd_interval *s) 302{ 303 *d = *s; 304} 305 306static inline int snd_interval_setinteger(struct snd_interval *i) 307{ 308 if (i->integer) 309 return 0; 310 if (i->openmin && i->openmax && i->min == i->max) 311 return -EINVAL; 312 i->integer = 1; 313 return 1; 314} 315 316static inline int snd_interval_eq(const struct snd_interval *i1, const struct snd_interval *i2) 317{ 318 if (i1->empty) 319 return i2->empty; 320 if (i2->empty) 321 return i1->empty; 322 return i1->min == i2->min && i1->openmin == i2->openmin && 323 i1->max == i2->max && i1->openmax == i2->openmax; 324} 325 326static inline unsigned int add(unsigned int a, unsigned int b) 327{ 328 if (a >= UINT_MAX - b) 329 return UINT_MAX; 330 return a + b; 331} 332 333static inline unsigned int sub(unsigned int a, unsigned int b) 334{ 335 if (a > b) 336 return a - b; 337 return 0; 338} 339 340#endif /* __SOUND_PCM_PARAMS_H */ 341