Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.16-rc3 366 lines 8.7 kB view raw
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 25extern int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, 26 snd_pcm_hw_param_t var, const struct snd_mask *val); 27extern unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params, 28 snd_pcm_hw_param_t var, int *dir); 29extern unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params, 30 snd_pcm_hw_param_t var, int *dir); 31extern int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, 32 snd_pcm_hw_param_t var, unsigned int val, int dir); 33extern int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params, 34 snd_pcm_hw_param_t var); 35extern int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params, 36 snd_pcm_hw_param_t var, unsigned int val, int dir); 37 38/* To share the same code we have alsa-lib */ 39#define INLINE static inline 40#define assert(a) (void)(a) 41 42#define SNDRV_MASK_BITS 64 /* we use so far 64bits only */ 43#define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32) 44#define MASK_OFS(i) ((i) >> 5) 45#define MASK_BIT(i) (1U << ((i) & 31)) 46 47INLINE unsigned int ld2(u_int32_t v) 48{ 49 unsigned r = 0; 50 51 if (v >= 0x10000) { 52 v >>= 16; 53 r += 16; 54 } 55 if (v >= 0x100) { 56 v >>= 8; 57 r += 8; 58 } 59 if (v >= 0x10) { 60 v >>= 4; 61 r += 4; 62 } 63 if (v >= 4) { 64 v >>= 2; 65 r += 2; 66 } 67 if (v >= 2) 68 r++; 69 return r; 70} 71 72INLINE size_t snd_mask_sizeof(void) 73{ 74 return sizeof(struct snd_mask); 75} 76 77INLINE void snd_mask_none(struct snd_mask *mask) 78{ 79 memset(mask, 0, sizeof(*mask)); 80} 81 82INLINE void snd_mask_any(struct snd_mask *mask) 83{ 84 memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 85} 86 87INLINE int snd_mask_empty(const struct snd_mask *mask) 88{ 89 int i; 90 for (i = 0; i < SNDRV_MASK_SIZE; i++) 91 if (mask->bits[i]) 92 return 0; 93 return 1; 94} 95 96INLINE unsigned int snd_mask_min(const struct snd_mask *mask) 97{ 98 int i; 99 assert(!snd_mask_empty(mask)); 100 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 101 if (mask->bits[i]) 102 return ffs(mask->bits[i]) - 1 + (i << 5); 103 } 104 return 0; 105} 106 107INLINE unsigned int snd_mask_max(const struct snd_mask *mask) 108{ 109 int i; 110 assert(!snd_mask_empty(mask)); 111 for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) { 112 if (mask->bits[i]) 113 return ld2(mask->bits[i]) + (i << 5); 114 } 115 return 0; 116} 117 118INLINE void snd_mask_set(struct snd_mask *mask, unsigned int val) 119{ 120 assert(val <= SNDRV_MASK_BITS); 121 mask->bits[MASK_OFS(val)] |= MASK_BIT(val); 122} 123 124INLINE void snd_mask_reset(struct snd_mask *mask, unsigned int val) 125{ 126 assert(val <= SNDRV_MASK_BITS); 127 mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val); 128} 129 130INLINE void snd_mask_set_range(struct snd_mask *mask, unsigned int from, unsigned int to) 131{ 132 unsigned int i; 133 assert(to <= SNDRV_MASK_BITS && from <= to); 134 for (i = from; i <= to; i++) 135 mask->bits[MASK_OFS(i)] |= MASK_BIT(i); 136} 137 138INLINE void snd_mask_reset_range(struct snd_mask *mask, unsigned int from, unsigned int to) 139{ 140 unsigned int i; 141 assert(to <= SNDRV_MASK_BITS && from <= to); 142 for (i = from; i <= to; i++) 143 mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i); 144} 145 146INLINE void snd_mask_leave(struct snd_mask *mask, unsigned int val) 147{ 148 unsigned int v; 149 assert(val <= SNDRV_MASK_BITS); 150 v = mask->bits[MASK_OFS(val)] & MASK_BIT(val); 151 snd_mask_none(mask); 152 mask->bits[MASK_OFS(val)] = v; 153} 154 155INLINE void snd_mask_intersect(struct snd_mask *mask, const struct snd_mask *v) 156{ 157 int i; 158 for (i = 0; i < SNDRV_MASK_SIZE; i++) 159 mask->bits[i] &= v->bits[i]; 160} 161 162INLINE int snd_mask_eq(const struct snd_mask *mask, const struct snd_mask *v) 163{ 164 return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 165} 166 167INLINE void snd_mask_copy(struct snd_mask *mask, const struct snd_mask *v) 168{ 169 *mask = *v; 170} 171 172INLINE int snd_mask_test(const struct snd_mask *mask, unsigned int val) 173{ 174 assert(val <= SNDRV_MASK_BITS); 175 return mask->bits[MASK_OFS(val)] & MASK_BIT(val); 176} 177 178INLINE int snd_mask_single(const struct snd_mask *mask) 179{ 180 int i, c = 0; 181 assert(!snd_mask_empty(mask)); 182 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 183 if (! mask->bits[i]) 184 continue; 185 if (mask->bits[i] & (mask->bits[i] - 1)) 186 return 0; 187 if (c) 188 return 0; 189 c++; 190 } 191 return 1; 192} 193 194INLINE int snd_mask_refine(struct snd_mask *mask, const struct snd_mask *v) 195{ 196 struct snd_mask old; 197 assert(!snd_mask_empty(mask)); 198 snd_mask_copy(&old, mask); 199 snd_mask_intersect(mask, v); 200 if (snd_mask_empty(mask)) 201 return -EINVAL; 202 return !snd_mask_eq(mask, &old); 203} 204 205INLINE int snd_mask_refine_first(struct snd_mask *mask) 206{ 207 assert(!snd_mask_empty(mask)); 208 if (snd_mask_single(mask)) 209 return 0; 210 snd_mask_leave(mask, snd_mask_min(mask)); 211 return 1; 212} 213 214INLINE int snd_mask_refine_last(struct snd_mask *mask) 215{ 216 assert(!snd_mask_empty(mask)); 217 if (snd_mask_single(mask)) 218 return 0; 219 snd_mask_leave(mask, snd_mask_max(mask)); 220 return 1; 221} 222 223INLINE int snd_mask_refine_min(struct snd_mask *mask, unsigned int val) 224{ 225 assert(!snd_mask_empty(mask)); 226 if (snd_mask_min(mask) >= val) 227 return 0; 228 snd_mask_reset_range(mask, 0, val - 1); 229 if (snd_mask_empty(mask)) 230 return -EINVAL; 231 return 1; 232} 233 234INLINE int snd_mask_refine_max(struct snd_mask *mask, unsigned int val) 235{ 236 assert(!snd_mask_empty(mask)); 237 if (snd_mask_max(mask) <= val) 238 return 0; 239 snd_mask_reset_range(mask, val + 1, SNDRV_MASK_BITS); 240 if (snd_mask_empty(mask)) 241 return -EINVAL; 242 return 1; 243} 244 245INLINE int snd_mask_refine_set(struct snd_mask *mask, unsigned int val) 246{ 247 int changed; 248 assert(!snd_mask_empty(mask)); 249 changed = !snd_mask_single(mask); 250 snd_mask_leave(mask, val); 251 if (snd_mask_empty(mask)) 252 return -EINVAL; 253 return changed; 254} 255 256INLINE int snd_mask_value(const struct snd_mask *mask) 257{ 258 assert(!snd_mask_empty(mask)); 259 return snd_mask_min(mask); 260} 261 262INLINE void snd_interval_any(struct snd_interval *i) 263{ 264 i->min = 0; 265 i->openmin = 0; 266 i->max = UINT_MAX; 267 i->openmax = 0; 268 i->integer = 0; 269 i->empty = 0; 270} 271 272INLINE void snd_interval_none(struct snd_interval *i) 273{ 274 i->empty = 1; 275} 276 277INLINE int snd_interval_checkempty(const struct snd_interval *i) 278{ 279 return (i->min > i->max || 280 (i->min == i->max && (i->openmin || i->openmax))); 281} 282 283INLINE int snd_interval_empty(const struct snd_interval *i) 284{ 285 return i->empty; 286} 287 288INLINE int snd_interval_single(const struct snd_interval *i) 289{ 290 assert(!snd_interval_empty(i)); 291 return (i->min == i->max || 292 (i->min + 1 == i->max && i->openmax)); 293} 294 295INLINE int snd_interval_value(const struct snd_interval *i) 296{ 297 assert(snd_interval_single(i)); 298 return i->min; 299} 300 301INLINE int snd_interval_min(const struct snd_interval *i) 302{ 303 assert(!snd_interval_empty(i)); 304 return i->min; 305} 306 307INLINE int snd_interval_max(const struct snd_interval *i) 308{ 309 unsigned int v; 310 assert(!snd_interval_empty(i)); 311 v = i->max; 312 if (i->openmax) 313 v--; 314 return v; 315} 316 317INLINE int snd_interval_test(const struct snd_interval *i, unsigned int val) 318{ 319 return !((i->min > val || (i->min == val && i->openmin) || 320 i->max < val || (i->max == val && i->openmax))); 321} 322 323INLINE void snd_interval_copy(struct snd_interval *d, const struct snd_interval *s) 324{ 325 *d = *s; 326} 327 328INLINE int snd_interval_setinteger(struct snd_interval *i) 329{ 330 if (i->integer) 331 return 0; 332 if (i->openmin && i->openmax && i->min == i->max) 333 return -EINVAL; 334 i->integer = 1; 335 return 1; 336} 337 338INLINE int snd_interval_eq(const struct snd_interval *i1, const struct snd_interval *i2) 339{ 340 if (i1->empty) 341 return i2->empty; 342 if (i2->empty) 343 return i1->empty; 344 return i1->min == i2->min && i1->openmin == i2->openmin && 345 i1->max == i2->max && i1->openmax == i2->openmax; 346} 347 348static inline unsigned int add(unsigned int a, unsigned int b) 349{ 350 if (a >= UINT_MAX - b) 351 return UINT_MAX; 352 return a + b; 353} 354 355static inline unsigned int sub(unsigned int a, unsigned int b) 356{ 357 if (a > b) 358 return a - b; 359 return 0; 360} 361 362#undef INLINE 363#undef assert 364 365#endif /* __SOUND_PCM_PARAMS_H */ 366