0001
0002 #ifndef __SOUND_PCM_PARAMS_H
0003 #define __SOUND_PCM_PARAMS_H
0004
0005
0006
0007
0008
0009
0010 #include <sound/pcm.h>
0011
0012 int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
0013 struct snd_pcm_hw_params *params,
0014 snd_pcm_hw_param_t var, int *dir);
0015 int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
0016 struct snd_pcm_hw_params *params,
0017 snd_pcm_hw_param_t var, int *dir);
0018 int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
0019 snd_pcm_hw_param_t var, int *dir);
0020
0021 #define SNDRV_MASK_BITS 64
0022 #define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32)
0023 #define MASK_OFS(i) ((i) >> 5)
0024 #define MASK_BIT(i) (1U << ((i) & 31))
0025
0026 static inline void snd_mask_none(struct snd_mask *mask)
0027 {
0028 memset(mask, 0, sizeof(*mask));
0029 }
0030
0031 static inline void snd_mask_any(struct snd_mask *mask)
0032 {
0033 memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t));
0034 }
0035
0036 static inline int snd_mask_empty(const struct snd_mask *mask)
0037 {
0038 int i;
0039 for (i = 0; i < SNDRV_MASK_SIZE; i++)
0040 if (mask->bits[i])
0041 return 0;
0042 return 1;
0043 }
0044
0045 static inline unsigned int snd_mask_min(const struct snd_mask *mask)
0046 {
0047 int i;
0048 for (i = 0; i < SNDRV_MASK_SIZE; i++) {
0049 if (mask->bits[i])
0050 return __ffs(mask->bits[i]) + (i << 5);
0051 }
0052 return 0;
0053 }
0054
0055 static inline unsigned int snd_mask_max(const struct snd_mask *mask)
0056 {
0057 int i;
0058 for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) {
0059 if (mask->bits[i])
0060 return __fls(mask->bits[i]) + (i << 5);
0061 }
0062 return 0;
0063 }
0064
0065 static inline void snd_mask_set(struct snd_mask *mask, unsigned int val)
0066 {
0067 mask->bits[MASK_OFS(val)] |= MASK_BIT(val);
0068 }
0069
0070
0071 static inline void snd_mask_set_format(struct snd_mask *mask,
0072 snd_pcm_format_t format)
0073 {
0074 snd_mask_set(mask, (__force unsigned int)format);
0075 }
0076
0077 static inline void snd_mask_reset(struct snd_mask *mask, unsigned int val)
0078 {
0079 mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val);
0080 }
0081
0082 static inline void snd_mask_set_range(struct snd_mask *mask,
0083 unsigned int from, unsigned int to)
0084 {
0085 unsigned int i;
0086 for (i = from; i <= to; i++)
0087 mask->bits[MASK_OFS(i)] |= MASK_BIT(i);
0088 }
0089
0090 static inline void snd_mask_reset_range(struct snd_mask *mask,
0091 unsigned int from, unsigned int to)
0092 {
0093 unsigned int i;
0094 for (i = from; i <= to; i++)
0095 mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i);
0096 }
0097
0098 static inline void snd_mask_leave(struct snd_mask *mask, unsigned int val)
0099 {
0100 unsigned int v;
0101 v = mask->bits[MASK_OFS(val)] & MASK_BIT(val);
0102 snd_mask_none(mask);
0103 mask->bits[MASK_OFS(val)] = v;
0104 }
0105
0106 static inline void snd_mask_intersect(struct snd_mask *mask,
0107 const struct snd_mask *v)
0108 {
0109 int i;
0110 for (i = 0; i < SNDRV_MASK_SIZE; i++)
0111 mask->bits[i] &= v->bits[i];
0112 }
0113
0114 static inline int snd_mask_eq(const struct snd_mask *mask,
0115 const struct snd_mask *v)
0116 {
0117 return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t));
0118 }
0119
0120 static inline void snd_mask_copy(struct snd_mask *mask,
0121 const struct snd_mask *v)
0122 {
0123 *mask = *v;
0124 }
0125
0126 static inline int snd_mask_test(const struct snd_mask *mask, unsigned int val)
0127 {
0128 return mask->bits[MASK_OFS(val)] & MASK_BIT(val);
0129 }
0130
0131
0132 static inline int snd_mask_test_format(const struct snd_mask *mask,
0133 snd_pcm_format_t format)
0134 {
0135 return snd_mask_test(mask, (__force unsigned int)format);
0136 }
0137
0138 static inline int snd_mask_single(const struct snd_mask *mask)
0139 {
0140 int i, c = 0;
0141 for (i = 0; i < SNDRV_MASK_SIZE; i++) {
0142 if (! mask->bits[i])
0143 continue;
0144 if (mask->bits[i] & (mask->bits[i] - 1))
0145 return 0;
0146 if (c)
0147 return 0;
0148 c++;
0149 }
0150 return 1;
0151 }
0152
0153 static inline int snd_mask_refine(struct snd_mask *mask,
0154 const struct snd_mask *v)
0155 {
0156 struct snd_mask old;
0157 snd_mask_copy(&old, mask);
0158 snd_mask_intersect(mask, v);
0159 if (snd_mask_empty(mask))
0160 return -EINVAL;
0161 return !snd_mask_eq(mask, &old);
0162 }
0163
0164 static inline int snd_mask_refine_first(struct snd_mask *mask)
0165 {
0166 if (snd_mask_single(mask))
0167 return 0;
0168 snd_mask_leave(mask, snd_mask_min(mask));
0169 return 1;
0170 }
0171
0172 static inline int snd_mask_refine_last(struct snd_mask *mask)
0173 {
0174 if (snd_mask_single(mask))
0175 return 0;
0176 snd_mask_leave(mask, snd_mask_max(mask));
0177 return 1;
0178 }
0179
0180 static inline int snd_mask_refine_min(struct snd_mask *mask, unsigned int val)
0181 {
0182 if (snd_mask_min(mask) >= val)
0183 return 0;
0184 snd_mask_reset_range(mask, 0, val - 1);
0185 if (snd_mask_empty(mask))
0186 return -EINVAL;
0187 return 1;
0188 }
0189
0190 static inline int snd_mask_refine_max(struct snd_mask *mask, unsigned int val)
0191 {
0192 if (snd_mask_max(mask) <= val)
0193 return 0;
0194 snd_mask_reset_range(mask, val + 1, SNDRV_MASK_BITS);
0195 if (snd_mask_empty(mask))
0196 return -EINVAL;
0197 return 1;
0198 }
0199
0200 static inline int snd_mask_refine_set(struct snd_mask *mask, unsigned int val)
0201 {
0202 int changed;
0203 changed = !snd_mask_single(mask);
0204 snd_mask_leave(mask, val);
0205 if (snd_mask_empty(mask))
0206 return -EINVAL;
0207 return changed;
0208 }
0209
0210 static inline int snd_mask_value(const struct snd_mask *mask)
0211 {
0212 return snd_mask_min(mask);
0213 }
0214
0215 static inline void snd_interval_any(struct snd_interval *i)
0216 {
0217 i->min = 0;
0218 i->openmin = 0;
0219 i->max = UINT_MAX;
0220 i->openmax = 0;
0221 i->integer = 0;
0222 i->empty = 0;
0223 }
0224
0225 static inline void snd_interval_none(struct snd_interval *i)
0226 {
0227 i->empty = 1;
0228 }
0229
0230 static inline int snd_interval_checkempty(const struct snd_interval *i)
0231 {
0232 return (i->min > i->max ||
0233 (i->min == i->max && (i->openmin || i->openmax)));
0234 }
0235
0236 static inline int snd_interval_empty(const struct snd_interval *i)
0237 {
0238 return i->empty;
0239 }
0240
0241 static inline int snd_interval_single(const struct snd_interval *i)
0242 {
0243 return (i->min == i->max ||
0244 (i->min + 1 == i->max && (i->openmin || i->openmax)));
0245 }
0246
0247 static inline int snd_interval_value(const struct snd_interval *i)
0248 {
0249 if (i->openmin && !i->openmax)
0250 return i->max;
0251 return i->min;
0252 }
0253
0254 static inline int snd_interval_min(const struct snd_interval *i)
0255 {
0256 return i->min;
0257 }
0258
0259 static inline int snd_interval_max(const struct snd_interval *i)
0260 {
0261 unsigned int v;
0262 v = i->max;
0263 if (i->openmax)
0264 v--;
0265 return v;
0266 }
0267
0268 static inline int snd_interval_test(const struct snd_interval *i, unsigned int val)
0269 {
0270 return !((i->min > val || (i->min == val && i->openmin) ||
0271 i->max < val || (i->max == val && i->openmax)));
0272 }
0273
0274 static inline void snd_interval_copy(struct snd_interval *d, const struct snd_interval *s)
0275 {
0276 *d = *s;
0277 }
0278
0279 static inline int snd_interval_setinteger(struct snd_interval *i)
0280 {
0281 if (i->integer)
0282 return 0;
0283 if (i->openmin && i->openmax && i->min == i->max)
0284 return -EINVAL;
0285 i->integer = 1;
0286 return 1;
0287 }
0288
0289 static inline int snd_interval_eq(const struct snd_interval *i1, const struct snd_interval *i2)
0290 {
0291 if (i1->empty)
0292 return i2->empty;
0293 if (i2->empty)
0294 return i1->empty;
0295 return i1->min == i2->min && i1->openmin == i2->openmin &&
0296 i1->max == i2->max && i1->openmax == i2->openmax;
0297 }
0298
0299
0300
0301
0302
0303 static inline snd_pcm_access_t params_access(const struct snd_pcm_hw_params *p)
0304 {
0305 return (__force snd_pcm_access_t)snd_mask_min(hw_param_mask_c(p,
0306 SNDRV_PCM_HW_PARAM_ACCESS));
0307 }
0308
0309
0310
0311
0312
0313 static inline snd_pcm_format_t params_format(const struct snd_pcm_hw_params *p)
0314 {
0315 return (__force snd_pcm_format_t)snd_mask_min(hw_param_mask_c(p,
0316 SNDRV_PCM_HW_PARAM_FORMAT));
0317 }
0318
0319
0320
0321
0322
0323 static inline snd_pcm_subformat_t
0324 params_subformat(const struct snd_pcm_hw_params *p)
0325 {
0326 return (__force snd_pcm_subformat_t)snd_mask_min(hw_param_mask_c(p,
0327 SNDRV_PCM_HW_PARAM_SUBFORMAT));
0328 }
0329
0330
0331
0332
0333
0334 static inline unsigned int
0335 params_period_bytes(const struct snd_pcm_hw_params *p)
0336 {
0337 return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)->min;
0338 }
0339
0340
0341
0342
0343
0344
0345
0346
0347 static inline int params_width(const struct snd_pcm_hw_params *p)
0348 {
0349 return snd_pcm_format_width(params_format(p));
0350 }
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360 static inline int params_physical_width(const struct snd_pcm_hw_params *p)
0361 {
0362 return snd_pcm_format_physical_width(params_format(p));
0363 }
0364
0365 static inline void
0366 params_set_format(struct snd_pcm_hw_params *p, snd_pcm_format_t fmt)
0367 {
0368 snd_mask_set_format(hw_param_mask(p, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
0369 }
0370
0371 #endif