2002-09-29 18:27:29

by Jaroslav Kysela

[permalink] [raw]
Subject: [PATCH] ALSA update [2/10] - 2002/06/26

You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.

===================================================================


[email protected], 2002-09-25 15:23:53+02:00, [email protected]
ALSA update 2002/06/26
- Enhanced bitmasks in PCM - added support for more formats by Takashi and me
- RME32 driver - added support for ADAT (Digi 32/8)


include/sound/asound.h | 41 +++++---
include/sound/pcm.h | 90 ++++++++++-------
include/sound/pcm_params.h | 88 +++++++++++------
include/sound/version.h | 2
sound/core/ioctl32/pcm32.c | 89 +++++++++++++++++
sound/core/oss/io.c | 1
sound/core/oss/pcm_oss.c | 21 ++--
sound/core/oss/pcm_plugin.c | 26 ++---
sound/core/oss/pcm_plugin.h | 4
sound/core/pcm.c | 12 ++
sound/core/pcm_lib.c | 26 ++++-
sound/core/pcm_misc.c | 116 +++++++++++++++++++++-
sound/core/pcm_native.c | 138 ++++++++++++++++++++++++---
sound/core/seq/oss/Makefile | 6 -
sound/isa/Makefile | 2
sound/isa/ad1848/ad1848_lib.c | 2
sound/isa/cs423x/cs4231_lib.c | 1
sound/isa/es18xx.c | 1
sound/isa/gus/gus_pcm.c | 1
sound/pci/korg1212/korg1212.c | 1
sound/pci/rme32.c | 212 +++++++++++++++++++++++++++++++++++++++---
sound/pci/rme96.c | 1
sound/pci/via8233.c | 4
23 files changed, 736 insertions(+), 149 deletions(-)


diff -Nru a/include/sound/asound.h b/include/sound/asound.h
--- a/include/sound/asound.h Sun Sep 29 20:20:12 2002
+++ b/include/sound/asound.h Sun Sep 29 20:20:12 2002
@@ -128,7 +128,7 @@
* *
*****************************************************************************/

-#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 1)
+#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 2)

typedef unsigned long sndrv_pcm_uframes_t;
typedef long sndrv_pcm_sframes_t;
@@ -191,7 +191,19 @@
SNDRV_PCM_FORMAT_MPEG,
SNDRV_PCM_FORMAT_GSM,
SNDRV_PCM_FORMAT_SPECIAL = 31,
- SNDRV_PCM_FORMAT_LAST = 31,
+ SNDRV_PCM_FORMAT_S24_3LE = 32, /* in three bytes */
+ SNDRV_PCM_FORMAT_S24_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U24_3LE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U24_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_S20_3LE, /* in three bytes */
+ SNDRV_PCM_FORMAT_S20_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U20_3LE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U20_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_S18_3LE, /* in three bytes */
+ SNDRV_PCM_FORMAT_S18_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U18_3LE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U18_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_LAST = SNDRV_PCM_FORMAT_U18_3BE,

#ifdef SNDRV_LITTLE_ENDIAN
SNDRV_PCM_FORMAT_S16 = SNDRV_PCM_FORMAT_S16_LE,
@@ -284,7 +296,7 @@
SNDRV_PCM_HW_PARAM_SUBFORMAT, /* Subformat */
SNDRV_PCM_HW_PARAM_LAST_MASK = SNDRV_PCM_HW_PARAM_SUBFORMAT,

- SNDRV_PCM_HW_PARAM_SAMPLE_BITS, /* Bits per sample */
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS = 8, /* Bits per sample */
SNDRV_PCM_HW_PARAM_FIRST_INTERVAL = SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
SNDRV_PCM_HW_PARAM_FRAME_BITS, /* Bits per frame */
SNDRV_PCM_HW_PARAM_CHANNELS, /* Channels */
@@ -298,8 +310,7 @@
SNDRV_PCM_HW_PARAM_BUFFER_SIZE, /* Size of buffer in frames */
SNDRV_PCM_HW_PARAM_BUFFER_BYTES, /* Size of buffer in bytes */
SNDRV_PCM_HW_PARAM_TICK_TIME, /* Approx tick duration in us */
- SNDRV_PCM_HW_PARAM_LAST_INTERVAL = SNDRV_PCM_HW_PARAM_TICK_TIME,
- SNDRV_PCM_HW_PARAM_LAST = SNDRV_PCM_HW_PARAM_LAST_INTERVAL,
+ SNDRV_PCM_HW_PARAM_LAST_INTERVAL = SNDRV_PCM_HW_PARAM_TICK_TIME
};

#define SNDRV_PCM_HW_PARAMS_RUNTIME (1<<0)
@@ -312,20 +323,28 @@
empty:1;
};

+#define SNDRV_MASK_MAX 256
+
+struct sndrv_mask {
+ u_int32_t bits[(SNDRV_MASK_MAX+31)/32];
+};
+
struct sndrv_pcm_hw_params {
unsigned int flags;
- unsigned int masks[SNDRV_PCM_HW_PARAM_LAST_MASK -
- SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
+ struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK -
+ SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
+ struct sndrv_mask mres[5]; /* reserved masks */
struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
- unsigned int rmask;
- unsigned int cmask;
+ struct sndrv_interval ires[9]; /* reserved intervals */
+ unsigned int rmask; /* W: requested masks */
+ unsigned int cmask; /* R: changed masks */
unsigned int info; /* R: Info flags for returned setup */
unsigned int msbits; /* R: used most significant bits */
unsigned int rate_num; /* R: rate numerator */
unsigned int rate_den; /* R: rate denominator */
sndrv_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames */
- unsigned char reserved[64];
+ unsigned char reserved[64]; /* reserved for future */
};

enum sndrv_pcm_tstamp {
@@ -345,7 +364,7 @@
sndrv_pcm_uframes_t silence_threshold; /* min distance from noise for silence filling */
sndrv_pcm_uframes_t silence_size; /* silence block size */
sndrv_pcm_uframes_t boundary; /* pointers wrap point */
- unsigned char reserved[64];
+ unsigned char reserved[64]; /* reserved for future */
};

struct sndrv_pcm_channel_info {
diff -Nru a/include/sound/pcm.h b/include/sound/pcm.h
--- a/include/sound/pcm.h Sun Sep 29 20:20:12 2002
+++ b/include/sound/pcm.h Sun Sep 29 20:20:12 2002
@@ -48,6 +48,7 @@
typedef struct sndrv_pcm_status snd_pcm_status_t;
typedef struct sndrv_pcm_mmap_status snd_pcm_mmap_status_t;
typedef struct sndrv_pcm_mmap_control snd_pcm_mmap_control_t;
+typedef struct sndrv_mask snd_mask_t;

#define _snd_pcm_substream_chip(substream) ((substream)->pcm->private_data)
#define snd_pcm_substream_chip(substream) snd_magic_cast1(chip_t, _snd_pcm_substream_chip(substream), return -ENXIO)
@@ -67,7 +68,7 @@

typedef struct _snd_pcm_hardware {
unsigned int info; /* SNDRV_PCM_INFO_* */
- unsigned int formats; /* SNDRV_PCM_FMTBIT_* */
+ u64 formats; /* SNDRV_PCM_FMTBIT_* */
unsigned int rates; /* SNDRV_PCM_RATE_* */
unsigned int rate_min; /* min rate */
unsigned int rate_max; /* max rate */
@@ -148,32 +149,44 @@
SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000)
#define SNDRV_PCM_RATE_8000_192000 (SNDRV_PCM_RATE_8000_96000|SNDRV_PCM_RATE_176400|\
SNDRV_PCM_RATE_192000)
-#define SNDRV_PCM_FMTBIT_S8 (1 << SNDRV_PCM_FORMAT_S8)
-#define SNDRV_PCM_FMTBIT_U8 (1 << SNDRV_PCM_FORMAT_U8)
-#define SNDRV_PCM_FMTBIT_S16_LE (1 << SNDRV_PCM_FORMAT_S16_LE)
-#define SNDRV_PCM_FMTBIT_S16_BE (1 << SNDRV_PCM_FORMAT_S16_BE)
-#define SNDRV_PCM_FMTBIT_U16_LE (1 << SNDRV_PCM_FORMAT_U16_LE)
-#define SNDRV_PCM_FMTBIT_U16_BE (1 << SNDRV_PCM_FORMAT_U16_BE)
-#define SNDRV_PCM_FMTBIT_S24_LE (1 << SNDRV_PCM_FORMAT_S24_LE)
-#define SNDRV_PCM_FMTBIT_S24_BE (1 << SNDRV_PCM_FORMAT_S24_BE)
-#define SNDRV_PCM_FMTBIT_U24_LE (1 << SNDRV_PCM_FORMAT_U24_LE)
-#define SNDRV_PCM_FMTBIT_U24_BE (1 << SNDRV_PCM_FORMAT_U24_BE)
-#define SNDRV_PCM_FMTBIT_S32_LE (1 << SNDRV_PCM_FORMAT_S32_LE)
-#define SNDRV_PCM_FMTBIT_S32_BE (1 << SNDRV_PCM_FORMAT_S32_BE)
-#define SNDRV_PCM_FMTBIT_U32_LE (1 << SNDRV_PCM_FORMAT_U32_LE)
-#define SNDRV_PCM_FMTBIT_U32_BE (1 << SNDRV_PCM_FORMAT_U32_BE)
-#define SNDRV_PCM_FMTBIT_FLOAT_LE (1 << SNDRV_PCM_FORMAT_FLOAT_LE)
-#define SNDRV_PCM_FMTBIT_FLOAT_BE (1 << SNDRV_PCM_FORMAT_FLOAT_BE)
-#define SNDRV_PCM_FMTBIT_FLOAT64_LE (1 << SNDRV_PCM_FORMAT_FLOAT64_LE)
-#define SNDRV_PCM_FMTBIT_FLOAT64_BE (1 << SNDRV_PCM_FORMAT_FLOAT64_BE)
-#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE (1 << SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE)
-#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE (1 << SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE)
-#define SNDRV_PCM_FMTBIT_MU_LAW (1 << SNDRV_PCM_FORMAT_MU_LAW)
-#define SNDRV_PCM_FMTBIT_A_LAW (1 << SNDRV_PCM_FORMAT_A_LAW)
-#define SNDRV_PCM_FMTBIT_IMA_ADPCM (1 << SNDRV_PCM_FORMAT_IMA_ADPCM)
-#define SNDRV_PCM_FMTBIT_MPEG (1 << SNDRV_PCM_FORMAT_MPEG)
-#define SNDRV_PCM_FMTBIT_GSM (1 << SNDRV_PCM_FORMAT_GSM)
-#define SNDRV_PCM_FMTBIT_SPECIAL (1 << SNDRV_PCM_FORMAT_SPECIAL)
+#define SNDRV_PCM_FMTBIT_S8 (1ULL << SNDRV_PCM_FORMAT_S8)
+#define SNDRV_PCM_FMTBIT_U8 (1ULL << SNDRV_PCM_FORMAT_U8)
+#define SNDRV_PCM_FMTBIT_S16_LE (1ULL << SNDRV_PCM_FORMAT_S16_LE)
+#define SNDRV_PCM_FMTBIT_S16_BE (1ULL << SNDRV_PCM_FORMAT_S16_BE)
+#define SNDRV_PCM_FMTBIT_U16_LE (1ULL << SNDRV_PCM_FORMAT_U16_LE)
+#define SNDRV_PCM_FMTBIT_U16_BE (1ULL << SNDRV_PCM_FORMAT_U16_BE)
+#define SNDRV_PCM_FMTBIT_S24_LE (1ULL << SNDRV_PCM_FORMAT_S24_LE)
+#define SNDRV_PCM_FMTBIT_S24_BE (1ULL << SNDRV_PCM_FORMAT_S24_BE)
+#define SNDRV_PCM_FMTBIT_U24_LE (1ULL << SNDRV_PCM_FORMAT_U24_LE)
+#define SNDRV_PCM_FMTBIT_U24_BE (1ULL << SNDRV_PCM_FORMAT_U24_BE)
+#define SNDRV_PCM_FMTBIT_S32_LE (1ULL << SNDRV_PCM_FORMAT_S32_LE)
+#define SNDRV_PCM_FMTBIT_S32_BE (1ULL << SNDRV_PCM_FORMAT_S32_BE)
+#define SNDRV_PCM_FMTBIT_U32_LE (1ULL << SNDRV_PCM_FORMAT_U32_LE)
+#define SNDRV_PCM_FMTBIT_U32_BE (1ULL << SNDRV_PCM_FORMAT_U32_BE)
+#define SNDRV_PCM_FMTBIT_FLOAT_LE (1ULL << SNDRV_PCM_FORMAT_FLOAT_LE)
+#define SNDRV_PCM_FMTBIT_FLOAT_BE (1ULL << SNDRV_PCM_FORMAT_FLOAT_BE)
+#define SNDRV_PCM_FMTBIT_FLOAT64_LE (1ULL << SNDRV_PCM_FORMAT_FLOAT64_LE)
+#define SNDRV_PCM_FMTBIT_FLOAT64_BE (1ULL << SNDRV_PCM_FORMAT_FLOAT64_BE)
+#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE (1ULL << SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE)
+#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE (1ULL << SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE)
+#define SNDRV_PCM_FMTBIT_MU_LAW (1ULL << SNDRV_PCM_FORMAT_MU_LAW)
+#define SNDRV_PCM_FMTBIT_A_LAW (1ULL << SNDRV_PCM_FORMAT_A_LAW)
+#define SNDRV_PCM_FMTBIT_IMA_ADPCM (1ULL << SNDRV_PCM_FORMAT_IMA_ADPCM)
+#define SNDRV_PCM_FMTBIT_MPEG (1ULL << SNDRV_PCM_FORMAT_MPEG)
+#define SNDRV_PCM_FMTBIT_GSM (1ULL << SNDRV_PCM_FORMAT_GSM)
+#define SNDRV_PCM_FMTBIT_SPECIAL (1ULL << SNDRV_PCM_FORMAT_SPECIAL)
+#define SNDRV_PCM_FMTBIT_S24_3LE (1ULL << SNDRV_PCM_FORMAT_S24_3LE)
+#define SNDRV_PCM_FMTBIT_U24_3LE (1ULL << SNDRV_PCM_FORMAT_U24_3LE)
+#define SNDRV_PCM_FMTBIT_S24_3BE (1ULL << SNDRV_PCM_FORMAT_S24_3BE)
+#define SNDRV_PCM_FMTBIT_U24_3BE (1ULL << SNDRV_PCM_FORMAT_U24_3BE)
+#define SNDRV_PCM_FMTBIT_S20_3LE (1ULL << SNDRV_PCM_FORMAT_S20_3LE)
+#define SNDRV_PCM_FMTBIT_U20_3LE (1ULL << SNDRV_PCM_FORMAT_U20_3LE)
+#define SNDRV_PCM_FMTBIT_S20_3BE (1ULL << SNDRV_PCM_FORMAT_S20_3BE)
+#define SNDRV_PCM_FMTBIT_U20_3BE (1ULL << SNDRV_PCM_FORMAT_U20_3BE)
+#define SNDRV_PCM_FMTBIT_S18_3LE (1ULL << SNDRV_PCM_FORMAT_S18_3LE)
+#define SNDRV_PCM_FMTBIT_U18_3LE (1ULL << SNDRV_PCM_FORMAT_U18_3LE)
+#define SNDRV_PCM_FMTBIT_S18_3BE (1ULL << SNDRV_PCM_FORMAT_S18_3BE)
+#define SNDRV_PCM_FMTBIT_U18_3BE (1ULL << SNDRV_PCM_FORMAT_U18_3BE)

#ifdef SNDRV_LITTLE_ENDIAN
#define SNDRV_PCM_FMTBIT_S16 SNDRV_PCM_FMTBIT_S16_LE
@@ -217,8 +230,8 @@
};

typedef struct _snd_pcm_hw_constraints {
- unsigned int masks[SNDRV_PCM_HW_PARAM_LAST_MASK -
- SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
+ snd_mask_t masks[SNDRV_PCM_HW_PARAM_LAST_MASK -
+ SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
snd_interval_t intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
unsigned int rules_num;
@@ -226,8 +239,8 @@
snd_pcm_hw_rule_t *rules;
} snd_pcm_hw_constraints_t;

-static inline unsigned int *constrs_mask(snd_pcm_hw_constraints_t *constrs,
- snd_pcm_hw_param_t var)
+static inline snd_mask_t *constrs_mask(snd_pcm_hw_constraints_t *constrs,
+ snd_pcm_hw_param_t var)
{
return &constrs->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
}
@@ -648,13 +661,10 @@
var <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL;
}

-typedef unsigned int snd_mask_t;
-#define SND_MASK_MAX 32
-
static inline snd_mask_t *hw_param_mask(snd_pcm_hw_params_t *params,
snd_pcm_hw_param_t var)
{
- return (snd_mask_t*)&params->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
+ return &params->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
}

static inline snd_interval_t *hw_param_interval(snd_pcm_hw_params_t *params,
@@ -675,9 +685,9 @@
return (const snd_interval_t *)hw_param_interval((snd_pcm_hw_params_t*) params, var);
}

-#define params_access(p) (ffs(*hw_param_mask((p), SNDRV_PCM_HW_PARAM_ACCESS)) - 1)
-#define params_format(p) (ffs(*hw_param_mask((p), SNDRV_PCM_HW_PARAM_FORMAT)) - 1)
-#define params_subformat(p) (ffs(*hw_param_mask((p), SNDRV_PCM_HW_PARAM_SUBFORMAT)) - 1)
+#define params_access(p) snd_mask_min(hw_param_mask((p), SNDRV_PCM_HW_PARAM_ACCESS))
+#define params_format(p) snd_mask_min(hw_param_mask((p), SNDRV_PCM_HW_PARAM_FORMAT))
+#define params_subformat(p) snd_mask_min(hw_param_mask((p), SNDRV_PCM_HW_PARAM_SUBFORMAT))
#define params_channels(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_CHANNELS)->min
#define params_rate(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_RATE)->min
#define params_period_size(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min
@@ -735,7 +745,9 @@
int snd_pcm_hw_constraints_complete(snd_pcm_substream_t *substream);

int snd_pcm_hw_constraint_mask(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
- unsigned int mask);
+ u_int32_t mask);
+int snd_pcm_hw_constraint_mask64(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
+ u_int64_t mask);
int snd_pcm_hw_constraint_minmax(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
unsigned int min, unsigned int max);
int snd_pcm_hw_constraint_integer(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var);
diff -Nru a/include/sound/pcm_params.h b/include/sound/pcm_params.h
--- a/include/sound/pcm_params.h Sun Sep 29 20:20:12 2002
+++ b/include/sound/pcm_params.h Sun Sep 29 20:20:12 2002
@@ -36,10 +36,14 @@
snd_pcm_hw_param_t var, unsigned int val, int dir);

/* To share the same code we have alsa-lib */
-#define snd_mask_bits(mask) (*(mask))
#define INLINE static inline
#define assert(a) (void)(a)

+#define SNDRV_MASK_BITS 64 /* we use so far 64bits only */
+#define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32)
+#define MASK_OFS(i) ((i) >> 5)
+#define MASK_BIT(i) (1U << ((i) & 31))
+
INLINE unsigned int ld2(u_int32_t v)
{
unsigned r = 0;
@@ -72,91 +76,119 @@

INLINE void snd_mask_none(snd_mask_t *mask)
{
- snd_mask_bits(mask) = 0;
+ memset(mask, 0, sizeof(*mask));
}

INLINE void snd_mask_any(snd_mask_t *mask)
{
- snd_mask_bits(mask) = ~0U;
-}
-
-INLINE void snd_mask_load(snd_mask_t *mask, unsigned int msk)
-{
- snd_mask_bits(mask) = msk;
+ memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t));
}

INLINE int snd_mask_empty(const snd_mask_t *mask)
{
- return snd_mask_bits(mask) == 0;
+ int i;
+ for (i = 0; i < SNDRV_MASK_SIZE; i++)
+ if (mask->bits[i])
+ return 0;
+ return 1;
}

INLINE unsigned int snd_mask_min(const snd_mask_t *mask)
{
+ int i;
assert(!snd_mask_empty(mask));
- return ffs(snd_mask_bits(mask)) - 1;
+ for (i = 0; i < SNDRV_MASK_SIZE; i++) {
+ if (mask->bits[i])
+ return ffs(mask->bits[i]) - 1 + (i << 5);
+ }
+ return 0;
}

INLINE unsigned int snd_mask_max(const snd_mask_t *mask)
{
+ int i;
assert(!snd_mask_empty(mask));
- return ld2(snd_mask_bits(mask));
+ for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) {
+ if (mask->bits[i])
+ return ld2(mask->bits[i]) + (i << 5);
+ }
+ return 0;
}

INLINE void snd_mask_set(snd_mask_t *mask, unsigned int val)
{
- assert(val <= SND_MASK_MAX);
- snd_mask_bits(mask) |= (1U << val);
+ assert(val <= SNDRV_MASK_BITS);
+ mask->bits[MASK_OFS(val)] |= MASK_BIT(val);
}

INLINE void snd_mask_reset(snd_mask_t *mask, unsigned int val)
{
- assert(val <= SND_MASK_MAX);
- snd_mask_bits(mask) &= ~(1U << val);
+ assert(val <= SNDRV_MASK_BITS);
+ mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val);
}

INLINE void snd_mask_set_range(snd_mask_t *mask, unsigned int from, unsigned int to)
{
- assert(to <= SND_MASK_MAX && from <= to);
- snd_mask_bits(mask) |= ((1U << (from - to + 1)) - 1) << from;
+ int i;
+ assert(to <= SNDRV_MASK_BITS && from <= to);
+ for (i = from; i <= to; i++)
+ mask->bits[MASK_OFS(i)] |= MASK_BIT(i);
}

INLINE void snd_mask_reset_range(snd_mask_t *mask, unsigned int from, unsigned int to)
{
- assert(to <= SND_MASK_MAX && from <= to);
- snd_mask_bits(mask) &= ~(((1U << (from - to + 1)) - 1) << from);
+ int i;
+ assert(to <= SNDRV_MASK_BITS && from <= to);
+ for (i = from; i <= to; i++)
+ mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i);
}

INLINE void snd_mask_leave(snd_mask_t *mask, unsigned int val)
{
- assert(val <= SND_MASK_MAX);
- snd_mask_bits(mask) &= 1U << val;
+ unsigned int v;
+ assert(val <= SNDRV_MASK_BITS);
+ v = mask->bits[MASK_OFS(val)] & MASK_BIT(val);
+ snd_mask_none(mask);
+ mask->bits[MASK_OFS(val)] = v;
}

INLINE void snd_mask_intersect(snd_mask_t *mask, const snd_mask_t *v)
{
- snd_mask_bits(mask) &= snd_mask_bits(v);
+ int i;
+ for (i = 0; i < SNDRV_MASK_SIZE; i++)
+ mask->bits[i] &= v->bits[i];
}

INLINE int snd_mask_eq(const snd_mask_t *mask, const snd_mask_t *v)
{
- return snd_mask_bits(mask) == snd_mask_bits(v);
+ return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t));
}

INLINE void snd_mask_copy(snd_mask_t *mask, const snd_mask_t *v)
{
- snd_mask_bits(mask) = snd_mask_bits(v);
+ *mask = *v;
}

INLINE int snd_mask_test(const snd_mask_t *mask, unsigned int val)
{
- assert(val <= SND_MASK_MAX);
- return snd_mask_bits(mask) & (1U << val);
+ assert(val <= SNDRV_MASK_BITS);
+ return mask->bits[MASK_OFS(val)] & MASK_BIT(val);
}

INLINE int snd_mask_single(const snd_mask_t *mask)
{
+ int i, c = 0;
assert(!snd_mask_empty(mask));
- return !(snd_mask_bits(mask) & (snd_mask_bits(mask) - 1));
+ for (i = 0; i < SNDRV_MASK_SIZE; i++) {
+ if (! mask->bits[i])
+ continue;
+ if (mask->bits[i] & (mask->bits[i] - 1))
+ return 0;
+ if (c)
+ return 0;
+ c++;
+ }
+ return 1;
}

INLINE int snd_mask_refine(snd_mask_t *mask, const snd_mask_t *v)
@@ -204,7 +236,7 @@
assert(!snd_mask_empty(mask));
if (snd_mask_max(mask) <= val)
return 0;
- snd_mask_reset_range(mask, val + 1, SND_MASK_MAX);
+ snd_mask_reset_range(mask, val + 1, SNDRV_MASK_BITS);
if (snd_mask_empty(mask))
return -EINVAL;
return 1;
diff -Nru a/include/sound/version.h b/include/sound/version.h
--- a/include/sound/version.h Sun Sep 29 20:20:12 2002
+++ b/include/sound/version.h Sun Sep 29 20:20:12 2002
@@ -1,3 +1,3 @@
/* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc2"
-#define CONFIG_SND_DATE " (Fri Jun 21 12:21:17 2002 UTC)"
+#define CONFIG_SND_DATE " (Wed Jun 26 18:12:42 2002 UTC)"
diff -Nru a/sound/core/ioctl32/pcm32.c b/sound/core/ioctl32/pcm32.c
--- a/sound/core/ioctl32/pcm32.c Sun Sep 29 20:20:12 2002
+++ b/sound/core/ioctl32/pcm32.c Sun Sep 29 20:20:12 2002
@@ -303,12 +303,94 @@
}


+struct sndrv_pcm_hw_params_old32 {
+ u32 flags;
+ u32 masks[SNDRV_PCM_HW_PARAM_SUBFORMAT -
+ SNDRV_PCM_HW_PARAM_ACCESS + 1];
+ struct sndrv_interval32 intervals[SNDRV_PCM_HW_PARAM_TICK_TIME -
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS + 1];
+ u32 rmask;
+ u32 cmask;
+ u32 info;
+ u32 msbits;
+ u32 rate_num;
+ u32 rate_den;
+ u32 fifo_size;
+ unsigned char reserved[64];
+} __attribute__((packed));
+
+#define __OLD_TO_NEW_MASK(x) ((x&7)|((x&0x07fffff8)<<5))
+#define __NEW_TO_OLD_MASK(x) ((x&7)|((x&0xffffff00)>>5))
+
+static void snd_pcm_hw_convert_from_old_params(snd_pcm_hw_params_t *params, struct sndrv_pcm_hw_params_old32 *oparams)
+{
+ unsigned int i;
+
+ memset(params, 0, sizeof(*params));
+ params->flags = oparams->flags;
+ for (i = 0; i < sizeof(oparams->masks) / sizeof(unsigned int); i++)
+ params->masks[i].bits[0] = oparams->masks[i];
+ memcpy(params->intervals, oparams->intervals, sizeof(oparams->intervals));
+ params->rmask = __OLD_TO_NEW_MASK(oparams->rmask);
+ params->cmask = __OLD_TO_NEW_MASK(oparams->cmask);
+ params->info = oparams->info;
+ params->msbits = oparams->msbits;
+ params->rate_num = oparams->rate_num;
+ params->rate_den = oparams->rate_den;
+ params->fifo_size = oparams->fifo_size;
+}
+
+static void snd_pcm_hw_convert_to_old_params(struct sndrv_pcm_hw_params_old32 *oparams, snd_pcm_hw_params_t *params)
+{
+ unsigned int i;
+
+ memset(oparams, 0, sizeof(*oparams));
+ oparams->flags = params->flags;
+ for (i = 0; i < sizeof(oparams->masks) / sizeof(unsigned int); i++)
+ oparams->masks[i] = params->masks[i].bits[0];
+ memcpy(oparams->intervals, params->intervals, sizeof(oparams->intervals));
+ oparams->rmask = __NEW_TO_OLD_MASK(params->rmask);
+ oparams->cmask = __NEW_TO_OLD_MASK(params->cmask);
+ oparams->info = params->info;
+ oparams->msbits = params->msbits;
+ oparams->rate_num = params->rate_num;
+ oparams->rate_den = params->rate_den;
+ oparams->fifo_size = params->fifo_size;
+}
+
+static int _snd_ioctl32_pcm_hw_params_old(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+{
+ struct sndrv_pcm_hw_params_old32 data32;
+ struct sndrv_pcm_hw_params data;
+ mm_segment_t oldseg = get_fs();
+ int err;
+ set_fs(KERNEL_DS);
+ if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {
+ err = -EFAULT;
+ goto __err;
+ }
+ snd_pcm_hw_convert_from_old_params(&data, &data32);
+ err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
+ if (err < 0)
+ goto __err;
+ snd_pcm_hw_convert_to_old_params(&data32, &data);
+ if (copy_to_user((void*)arg, &data32, sizeof(data32))) {
+ err = -EFAULT;
+ goto __err;
+ }
+ __err: set_fs(oldseg);
+ return err;
+}
+
+
/*
*/

DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_refine, pcm_hw_params, SNDRV_PCM_IOCTL_HW_REFINE);
-DEFINE_ALSA_IOCTL_ENTRY(pcm_sw_params, pcm_sw_params, SNDRV_PCM_IOCTL_SW_PARAMS);
DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_params, pcm_hw_params, SNDRV_PCM_IOCTL_HW_PARAMS);
+DEFINE_ALSA_IOCTL_ENTRY(pcm_sw_params, pcm_sw_params, SNDRV_PCM_IOCTL_SW_PARAMS);
+DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_refine_old, pcm_hw_params_old, SNDRV_PCM_IOCTL_HW_REFINE);
+DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_params_old, pcm_hw_params_old, SNDRV_PCM_IOCTL_HW_PARAMS);
DEFINE_ALSA_IOCTL_ENTRY(pcm_status, pcm_status, SNDRV_PCM_IOCTL_STATUS);
DEFINE_ALSA_IOCTL_ENTRY(pcm_delay, pcm_sframes_str, SNDRV_PCM_IOCTL_DELAY);
DEFINE_ALSA_IOCTL_ENTRY(pcm_channel_info, pcm_channel_info, SNDRV_PCM_IOCTL_CHANNEL_INFO);
@@ -335,6 +417,9 @@
SNDRV_PCM_IOCTL_READI_FRAMES32 = _IOR('A', 0x51, struct sndrv_xferi32),
SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct sndrv_xfern32),
SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct sndrv_xfern32),
+ SNDRV_PCM_IOCTL_HW_REFINE_OLD32 = _IOWR('A', 0x10, struct sndrv_pcm_hw_params_old32),
+ SNDRV_PCM_IOCTL_HW_PARAMS_OLD32 = _IOWR('A', 0x11, struct sndrv_pcm_hw_params_old32),
+
};

struct ioctl32_mapper pcm_mappers[] = {
@@ -342,6 +427,8 @@
{ SNDRV_PCM_IOCTL_INFO, NULL },
{ SNDRV_PCM_IOCTL_HW_REFINE32, AP(pcm_hw_refine) },
{ SNDRV_PCM_IOCTL_HW_PARAMS32, AP(pcm_hw_params) },
+ { SNDRV_PCM_IOCTL_HW_REFINE_OLD32, AP(pcm_hw_refine_old) },
+ { SNDRV_PCM_IOCTL_HW_PARAMS_OLD32, AP(pcm_hw_params_old) },
{ SNDRV_PCM_IOCTL_HW_FREE, NULL },
{ SNDRV_PCM_IOCTL_SW_PARAMS32, AP(pcm_sw_params) },
{ SNDRV_PCM_IOCTL_STATUS32, AP(pcm_status) },
diff -Nru a/sound/core/oss/io.c b/sound/core/oss/io.c
--- a/sound/core/oss/io.c Sun Sep 29 20:20:12 2002
+++ b/sound/core/oss/io.c Sun Sep 29 20:20:12 2002
@@ -24,6 +24,7 @@
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include "pcm_plugin.h"

#define pcm_write(plug,buf,count) snd_pcm_oss_write3(plug,buf,count,1)
diff -Nru a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
--- a/sound/core/oss/pcm_oss.c Sun Sep 29 20:20:12 2002
+++ b/sound/core/oss/pcm_oss.c Sun Sep 29 20:20:12 2002
@@ -267,8 +267,8 @@
int err;
int direct;
int format, sformat, n;
- unsigned int sformat_mask;
- unsigned int mask;
+ snd_mask_t sformat_mask;
+ snd_mask_t mask;

if (atomic_read(&runtime->mmap_count)) {
direct = 1;
@@ -280,12 +280,13 @@
_snd_pcm_hw_params_any(&sparams);
_snd_pcm_hw_param_setinteger(&sparams, SNDRV_PCM_HW_PARAM_PERIODS);
_snd_pcm_hw_param_min(&sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0);
+ snd_mask_none(&mask);
if (atomic_read(&runtime->mmap_count))
- mask = 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED;
+ snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
else {
- mask = 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED;
+ snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_INTERLEAVED);
if (!direct)
- mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED;
+ snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
}
err = snd_pcm_hw_param_mask(substream, &sparams, SNDRV_PCM_HW_PARAM_ACCESS, &mask);
if (err < 0) {
@@ -301,11 +302,11 @@
if (direct)
sformat = format;
else
- sformat = snd_pcm_plug_slave_format(format, sformat_mask);
+ sformat = snd_pcm_plug_slave_format(format, &sformat_mask);

- if (sformat < 0 || !(sformat_mask & (1 << sformat))) {
+ if (sformat < 0 || !snd_mask_test(&sformat_mask, sformat)) {
for (sformat = 0; sformat <= SNDRV_PCM_FORMAT_LAST; sformat++) {
- if ((sformat_mask & (1 << sformat)) &&
+ if (snd_mask_test(&sformat_mask, sformat) &&
snd_pcm_oss_format_to(sformat) >= 0)
break;
}
@@ -935,7 +936,7 @@
int direct;
snd_pcm_hw_params_t params;
unsigned int formats = 0;
- unsigned int format_mask;
+ snd_mask_t format_mask;
int fmt;
if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
return err;
@@ -955,7 +956,7 @@
snd_assert(err >= 0, return err);
format_mask = *hw_param_mask(&params, SNDRV_PCM_HW_PARAM_FORMAT);
for (fmt = 0; fmt < 32; ++fmt) {
- if (format_mask & (1 << fmt)) {
+ if (snd_mask_test(&format_mask, fmt)) {
int f = snd_pcm_oss_format_to(fmt);
if (f >= 0)
formats |= f;
diff -Nru a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
--- a/sound/core/oss/pcm_plugin.c Sun Sep 29 20:20:12 2002
+++ b/sound/core/oss/pcm_plugin.c Sun Sep 29 20:20:12 2002
@@ -31,6 +31,7 @@
#include <linux/vmalloc.h>
#include <sound/core.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include "pcm_plugin.h"

#define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first)
@@ -280,20 +281,23 @@
return frames;
}

-unsigned int snd_pcm_plug_formats(unsigned int formats)
+static int snd_pcm_plug_formats(snd_mask_t *mask, int format)
{
- int linfmts = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
+ snd_mask_t formats = *mask;
+ u64 linfmts = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_U24_BE | SNDRV_PCM_FMTBIT_S24_BE |
SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE |
SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE);
- formats |= SNDRV_PCM_FMTBIT_MU_LAW;
+ snd_mask_set(&formats, SNDRV_PCM_FORMAT_MU_LAW);

- if (formats & linfmts)
- formats |= linfmts;
- return formats;
+ if (formats.bits[0] & (u32)linfmts)
+ formats.bits[0] |= (u32)linfmts;
+ if (formats.bits[1] & (u32)(linfmts >> 32))
+ formats.bits[1] |= (u32)(linfmts >> 32);
+ return snd_mask_test(&formats, format);
}

static int preferred_formats[] = {
@@ -313,11 +317,11 @@
SNDRV_PCM_FORMAT_U8
};

-int snd_pcm_plug_slave_format(int format, unsigned int format_mask)
+int snd_pcm_plug_slave_format(int format, snd_mask_t *format_mask)
{
- if (format_mask & (1 << format))
+ if (snd_mask_test(format_mask, format))
return format;
- if ((snd_pcm_plug_formats(format_mask) & (1 << format)) == 0)
+ if (! snd_pcm_plug_formats(format_mask, format))
return -EINVAL;
if (snd_pcm_format_linear(format)) {
int width = snd_pcm_format_width(format);
@@ -333,7 +337,7 @@
for (sgn = 0; sgn < 2; ++sgn) {
format1 = snd_pcm_build_linear_format(width1, unsignd1, big1);
if (format1 >= 0 &&
- format_mask & (1 << format1))
+ snd_mask_test(format_mask, format1))
goto _found;
unsignd1 = !unsignd1;
}
@@ -354,7 +358,7 @@
case SNDRV_PCM_FORMAT_MU_LAW:
for (i = 0; i < sizeof(preferred_formats) / sizeof(preferred_formats[0]); ++i) {
int format1 = preferred_formats[i];
- if (format_mask & (1 << format1))
+ if (snd_mask_test(format_mask, format1))
return format1;
}
default:
diff -Nru a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h
--- a/sound/core/oss/pcm_plugin.h Sun Sep 29 20:20:12 2002
+++ b/sound/core/oss/pcm_plugin.h Sun Sep 29 20:20:12 2002
@@ -197,13 +197,11 @@
snd_pcm_plugin_format_t *dst_format,
snd_pcm_plugin_t **r_plugin);

-unsigned int snd_pcm_plug_formats(unsigned int formats);
-
int snd_pcm_plug_format_plugins(snd_pcm_plug_t *substream,
snd_pcm_hw_params_t *params,
snd_pcm_hw_params_t *slave_params);

-int snd_pcm_plug_slave_format(int format, unsigned int format_mask);
+int snd_pcm_plug_slave_format(int format, snd_mask_t *format_mask);

int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin);

diff -Nru a/sound/core/pcm.c b/sound/core/pcm.c
--- a/sound/core/pcm.c Sun Sep 29 20:20:12 2002
+++ b/sound/core/pcm.c Sun Sep 29 20:20:13 2002
@@ -184,6 +184,18 @@
FORMAT(MPEG),
FORMAT(GSM),
FORMAT(SPECIAL),
+ FORMAT(S24_3LE),
+ FORMAT(S24_3BE),
+ FORMAT(U24_3LE),
+ FORMAT(U24_3BE),
+ FORMAT(S20_3LE),
+ FORMAT(S20_3BE),
+ FORMAT(U20_3LE),
+ FORMAT(U20_3BE),
+ FORMAT(S18_3LE),
+ FORMAT(S18_3BE),
+ FORMAT(U18_3LE),
+ FORMAT(U18_3BE),
};

char *snd_pcm_subformat_names[] = {
diff -Nru a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
--- a/sound/core/pcm_lib.c Sun Sep 29 20:20:12 2002
+++ b/sound/core/pcm_lib.c Sun Sep 29 20:20:12 2002
@@ -810,12 +810,26 @@
}

int snd_pcm_hw_constraint_mask(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
- unsigned int mask)
+ u_int32_t mask)
{
snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints;
- unsigned int *maskp = constrs_mask(constrs, var);
- *maskp &= mask;
- if (*maskp == 0)
+ snd_mask_t *maskp = constrs_mask(constrs, var);
+ *maskp->bits &= mask;
+ memset(maskp->bits + 1, 0, (SNDRV_MASK_MAX-32) / 8); /* clear rest */
+ if (*maskp->bits == 0)
+ return -EINVAL;
+ return 0;
+}
+
+int snd_pcm_hw_constraint_mask64(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
+ u_int64_t mask)
+{
+ snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints;
+ snd_mask_t *maskp = constrs_mask(constrs, var);
+ maskp->bits[0] &= (u_int32_t)mask;
+ maskp->bits[1] &= (u_int32_t)(mask >> 32);
+ memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
+ if (! maskp->bits[0] && ! maskp->bits[1])
return -EINVAL;
return 0;
}
@@ -982,7 +996,9 @@
{
unsigned int k;
memset(params, 0, sizeof(*params));
- for (k = 0; k <= SNDRV_PCM_HW_PARAM_LAST; k++)
+ for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++)
+ _snd_pcm_hw_param_any(params, k);
+ for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++)
_snd_pcm_hw_param_any(params, k);
params->info = ~0U;
}
diff -Nru a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
--- a/sound/core/pcm_misc.c Sun Sep 29 20:20:12 2002
+++ b/sound/core/pcm_misc.c Sun Sep 29 20:20:12 2002
@@ -41,6 +41,12 @@
case SNDRV_PCM_FORMAT_S24_BE:
case SNDRV_PCM_FORMAT_S32_LE:
case SNDRV_PCM_FORMAT_S32_BE:
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ case SNDRV_PCM_FORMAT_S24_3BE:
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ case SNDRV_PCM_FORMAT_S20_3BE:
+ case SNDRV_PCM_FORMAT_S18_3LE:
+ case SNDRV_PCM_FORMAT_S18_3BE:
return 1;
case SNDRV_PCM_FORMAT_U8:
case SNDRV_PCM_FORMAT_U16_LE:
@@ -49,6 +55,12 @@
case SNDRV_PCM_FORMAT_U24_BE:
case SNDRV_PCM_FORMAT_U32_LE:
case SNDRV_PCM_FORMAT_U32_BE:
+ case SNDRV_PCM_FORMAT_U24_3LE:
+ case SNDRV_PCM_FORMAT_U24_3BE:
+ case SNDRV_PCM_FORMAT_U20_3LE:
+ case SNDRV_PCM_FORMAT_U20_3BE:
+ case SNDRV_PCM_FORMAT_U18_3LE:
+ case SNDRV_PCM_FORMAT_U18_3BE:
return 0;
default:
return -EINVAL;
@@ -82,6 +94,12 @@
case SNDRV_PCM_FORMAT_FLOAT_LE:
case SNDRV_PCM_FORMAT_FLOAT64_LE:
case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ case SNDRV_PCM_FORMAT_S18_3LE:
+ case SNDRV_PCM_FORMAT_U24_3LE:
+ case SNDRV_PCM_FORMAT_U20_3LE:
+ case SNDRV_PCM_FORMAT_U18_3LE:
return 1;
case SNDRV_PCM_FORMAT_S16_BE:
case SNDRV_PCM_FORMAT_U16_BE:
@@ -92,6 +110,12 @@
case SNDRV_PCM_FORMAT_FLOAT_BE:
case SNDRV_PCM_FORMAT_FLOAT64_BE:
case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
+ case SNDRV_PCM_FORMAT_S24_3BE:
+ case SNDRV_PCM_FORMAT_S20_3BE:
+ case SNDRV_PCM_FORMAT_S18_3BE:
+ case SNDRV_PCM_FORMAT_U24_3BE:
+ case SNDRV_PCM_FORMAT_U20_3BE:
+ case SNDRV_PCM_FORMAT_U18_3BE:
return 0;
default:
return -EINVAL;
@@ -128,10 +152,24 @@
case SNDRV_PCM_FORMAT_U16_LE:
case SNDRV_PCM_FORMAT_U16_BE:
return 16;
+ case SNDRV_PCM_FORMAT_S18_3LE:
+ case SNDRV_PCM_FORMAT_S18_3BE:
+ case SNDRV_PCM_FORMAT_U18_3LE:
+ case SNDRV_PCM_FORMAT_U18_3BE:
+ return 18;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ case SNDRV_PCM_FORMAT_S20_3BE:
+ case SNDRV_PCM_FORMAT_U20_3LE:
+ case SNDRV_PCM_FORMAT_U20_3BE:
+ return 20;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S24_BE:
case SNDRV_PCM_FORMAT_U24_LE:
case SNDRV_PCM_FORMAT_U24_BE:
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ case SNDRV_PCM_FORMAT_S24_3BE:
+ case SNDRV_PCM_FORMAT_U24_3LE:
+ case SNDRV_PCM_FORMAT_U24_3BE:
return 24;
case SNDRV_PCM_FORMAT_S32_LE:
case SNDRV_PCM_FORMAT_S32_BE:
@@ -167,6 +205,19 @@
case SNDRV_PCM_FORMAT_U16_LE:
case SNDRV_PCM_FORMAT_U16_BE:
return 16;
+ case SNDRV_PCM_FORMAT_S18_3LE:
+ case SNDRV_PCM_FORMAT_S18_3BE:
+ case SNDRV_PCM_FORMAT_U18_3LE:
+ case SNDRV_PCM_FORMAT_U18_3BE:
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ case SNDRV_PCM_FORMAT_S20_3BE:
+ case SNDRV_PCM_FORMAT_U20_3LE:
+ case SNDRV_PCM_FORMAT_U20_3BE:
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ case SNDRV_PCM_FORMAT_S24_3BE:
+ case SNDRV_PCM_FORMAT_U24_3LE:
+ case SNDRV_PCM_FORMAT_U24_3BE:
+ return 24;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S24_BE:
case SNDRV_PCM_FORMAT_U24_LE:
@@ -204,6 +255,19 @@
case SNDRV_PCM_FORMAT_U16_LE:
case SNDRV_PCM_FORMAT_U16_BE:
return samples * 2;
+ case SNDRV_PCM_FORMAT_S18_3LE:
+ case SNDRV_PCM_FORMAT_S18_3BE:
+ case SNDRV_PCM_FORMAT_U18_3LE:
+ case SNDRV_PCM_FORMAT_U18_3BE:
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ case SNDRV_PCM_FORMAT_S20_3BE:
+ case SNDRV_PCM_FORMAT_U20_3LE:
+ case SNDRV_PCM_FORMAT_U20_3BE:
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ case SNDRV_PCM_FORMAT_S24_3BE:
+ case SNDRV_PCM_FORMAT_U24_3LE:
+ case SNDRV_PCM_FORMAT_U24_3BE:
+ return samples * 3;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S24_BE:
case SNDRV_PCM_FORMAT_U24_LE:
@@ -243,6 +307,12 @@
case SNDRV_PCM_FORMAT_S24_BE:
case SNDRV_PCM_FORMAT_S32_LE:
case SNDRV_PCM_FORMAT_S32_BE:
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ case SNDRV_PCM_FORMAT_S24_3BE:
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ case SNDRV_PCM_FORMAT_S20_3BE:
+ case SNDRV_PCM_FORMAT_S18_3LE:
+ case SNDRV_PCM_FORMAT_S18_3BE:
return 0;
case SNDRV_PCM_FORMAT_U8:
return 0x8080808080808080ULL;
@@ -273,6 +343,15 @@
case SNDRV_PCM_FORMAT_U32_BE:
return 0x8000000080000000ULL;
#endif
+ case SNDRV_PCM_FORMAT_U24_3LE:
+ case SNDRV_PCM_FORMAT_U24_3BE:
+ return 0x0000800000800000ULL;
+ case SNDRV_PCM_FORMAT_U20_3LE:
+ case SNDRV_PCM_FORMAT_U20_3BE:
+ return 0x0000080000080000ULL;
+ case SNDRV_PCM_FORMAT_U18_3LE:
+ case SNDRV_PCM_FORMAT_U18_3BE:
+ return 0x0000020000020000ULL;
case SNDRV_PCM_FORMAT_FLOAT_LE:
{
union {
@@ -379,20 +458,45 @@
}
case 16: {
u_int16_t silence = snd_pcm_format_silence_64(format);
- while (samples-- > 0)
- *((u_int16_t *)data)++ = silence;
+ if (! silence)
+ memset(data, 0, samples * 2);
+ else {
+ while (samples-- > 0)
+ *((u_int16_t *)data)++ = silence;
+ }
break;
}
+ case 24: {
+ u_int32_t silence = snd_pcm_format_silence_64(format);
+ if (! silence)
+ memset(data, 0, samples * 3);
+ else {
+ /* FIXME: rewrite in the more better way.. */
+ int i;
+ while (samples-- > 0) {
+ for (i = 0; i < 3; i++)
+ *((u_int8_t *)data)++ = silence >> (i * 8);
+ }
+ }
+ }
case 32: {
u_int32_t silence = snd_pcm_format_silence_64(format);
- while (samples-- > 0)
- *((u_int32_t *)data)++ = silence;
+ if (! silence)
+ memset(data, 0, samples * 4);
+ else {
+ while (samples-- > 0)
+ *((u_int32_t *)data)++ = silence;
+ }
break;
}
case 64: {
u_int64_t silence = snd_pcm_format_silence_64(format);
- while (samples-- > 0)
- *((u_int64_t *)data)++ = silence;
+ if (! silence)
+ memset(data, 0, samples * 8);
+ else {
+ while (samples-- > 0)
+ *((u_int64_t *)data)++ = silence;
+ }
break;
}
default:
diff -Nru a/sound/core/pcm_native.c b/sound/core/pcm_native.c
--- a/sound/core/pcm_native.c Sun Sep 29 20:20:12 2002
+++ b/sound/core/pcm_native.c Sun Sep 29 20:20:12 2002
@@ -32,6 +32,36 @@
#include <sound/pcm_params.h>
#include <sound/minors.h>

+/*
+ * Compatibility
+ */
+
+struct sndrv_pcm_hw_params_old {
+ unsigned int flags;
+ unsigned int masks[SNDRV_PCM_HW_PARAM_SUBFORMAT -
+ SNDRV_PCM_HW_PARAM_ACCESS + 1];
+ struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_TICK_TIME -
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS + 1];
+ unsigned int rmask;
+ unsigned int cmask;
+ unsigned int info;
+ unsigned int msbits;
+ unsigned int rate_num;
+ unsigned int rate_den;
+ sndrv_pcm_uframes_t fifo_size;
+ unsigned char reserved[64];
+};
+
+#define SNDRV_PCM_IOCTL_HW_REFINE_OLD _IOWR('A', 0x10, struct sndrv_pcm_hw_params_old)
+#define SNDRV_PCM_IOCTL_HW_PARAMS_OLD _IOWR('A', 0x11, struct sndrv_pcm_hw_params_old)
+
+static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams);
+static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams);
+
+/*
+ *
+ */
+
static rwlock_t pcm_link_lock = RW_LOCK_UNLOCKED;

static inline mm_segment_t snd_enter_user(void)
@@ -52,6 +82,8 @@
__MOD_DEC_USE_COUNT(module);
}

+
+
int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info)
{
snd_pcm_runtime_t * runtime;
@@ -121,7 +153,7 @@
snd_mask_t *m = NULL;
snd_pcm_hw_constraints_t *constrs = &substream->runtime->hw_constraints;
unsigned int rstamps[constrs->rules_num];
- unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST + 1];
+ unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1];
unsigned int stamp = 2;
int changed, again;

@@ -187,7 +219,7 @@

for (k = 0; k < constrs->rules_num; k++)
rstamps[k] = 0;
- for (k = 0; k <= SNDRV_PCM_HW_PARAM_LAST; k++)
+ for (k = 0; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++)
vstamps[k] = (params->rmask & (1 << k)) ? 1 : 0;
do {
again = 0;
@@ -211,7 +243,7 @@
printk("%s = ", snd_pcm_hw_param_names[r->var]);
if (hw_is_mask(r->var)) {
m = hw_param_mask(params, r->var);
- printk("%x", *m);
+ printk("%x", *m->bits);
} else {
i = hw_param_interval(params, r->var);
if (i->empty)
@@ -228,7 +260,7 @@
if (r->var >= 0) {
printk(" -> ");
if (hw_is_mask(r->var))
- printk("%x", *m);
+ printk("%x", *m->bits);
else {
if (i->empty)
printk("empty");
@@ -1369,16 +1401,17 @@
{
unsigned int k;
snd_interval_t *i = hw_param_interval(params, rule->deps[0]);
- unsigned int m = ~0U;
- unsigned int *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ snd_mask_t m;
+ snd_mask_t *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ snd_mask_any(&m);
for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) {
int bits;
- if (!(*mask & (1U << k)))
+ if (! snd_mask_test(mask, k))
continue;
bits = snd_pcm_format_physical_width(k);
snd_assert(bits > 0, continue);
if ((unsigned)bits < i->min || (unsigned)bits > i->max)
- m &= ~(1U << k);
+ snd_mask_reset(&m, k);
}
return snd_mask_refine(mask, &m);
}
@@ -1394,7 +1427,7 @@
t.openmax = 0;
for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) {
int bits;
- if (!(*hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT) & (1U << k)))
+ if (! snd_mask_test(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k))
continue;
bits = snd_pcm_format_physical_width(k);
snd_assert(bits > 0, continue);
@@ -1582,7 +1615,8 @@
err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask);
snd_assert(err >= 0, return -EINVAL);

- err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats);
+ err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats);
+ //err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats);
snd_assert(err >= 0, return -EINVAL);

err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD);
@@ -1808,12 +1842,7 @@
snd_assert(substream != NULL, return -ENXIO);
snd_assert(!atomic_read(&substream->runtime->mmap_count), );
pcm = substream->pcm;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if ((substream->ffile->f_flags & O_NONBLOCK) ||
- snd_pcm_playback_drain(substream) == -ERESTARTSYS)
- snd_pcm_playback_drop(substream);
- } else
- snd_pcm_capture_drop(substream);
+ snd_pcm_capture_drop(substream);
fasync_helper(-1, file, 0, &substream->runtime->fasync);
down(&pcm->open_mutex);
snd_pcm_release_file(pcm_file);
@@ -2053,6 +2082,10 @@
return snd_pcm_resume(substream);
case SNDRV_PCM_IOCTL_XRUN:
return snd_pcm_xrun(substream);
+ case SNDRV_PCM_IOCTL_HW_REFINE_OLD:
+ return snd_pcm_hw_refine_old_user(substream, (struct sndrv_pcm_hw_params_old *) arg);
+ case SNDRV_PCM_IOCTL_HW_PARAMS_OLD:
+ return snd_pcm_hw_params_old_user(substream, (struct sndrv_pcm_hw_params_old *) arg);
}
snd_printd("unknown ioctl = 0x%x\n", cmd);
return -ENOTTY;
@@ -2723,6 +2756,79 @@
if (err < 0)
return err;
return 0;
+}
+
+/*
+ * To be removed helpers to keep binary compatibility
+ */
+
+#define __OLD_TO_NEW_MASK(x) ((x&7)|((x&0x07fffff8)<<5))
+#define __NEW_TO_OLD_MASK(x) ((x&7)|((x&0xffffff00)>>5))
+
+static void snd_pcm_hw_convert_from_old_params(snd_pcm_hw_params_t *params, struct sndrv_pcm_hw_params_old *oparams)
+{
+ unsigned int i;
+
+ memset(params, 0, sizeof(*params));
+ params->flags = oparams->flags;
+ for (i = 0; i < sizeof(oparams->masks) / sizeof(unsigned int); i++)
+ params->masks[i].bits[0] = oparams->masks[i];
+ memcpy(params->intervals, oparams->intervals, sizeof(oparams->intervals));
+ params->rmask = __OLD_TO_NEW_MASK(oparams->rmask);
+ params->cmask = __OLD_TO_NEW_MASK(oparams->cmask);
+ params->info = oparams->info;
+ params->msbits = oparams->msbits;
+ params->rate_num = oparams->rate_num;
+ params->rate_den = oparams->rate_den;
+ params->fifo_size = oparams->fifo_size;
+}
+
+static void snd_pcm_hw_convert_to_old_params(struct sndrv_pcm_hw_params_old *oparams, snd_pcm_hw_params_t *params)
+{
+ unsigned int i;
+
+ memset(oparams, 0, sizeof(*oparams));
+ oparams->flags = params->flags;
+ for (i = 0; i < sizeof(oparams->masks) / sizeof(unsigned int); i++)
+ oparams->masks[i] = params->masks[i].bits[0];
+ memcpy(oparams->intervals, params->intervals, sizeof(oparams->intervals));
+ oparams->rmask = __NEW_TO_OLD_MASK(params->rmask);
+ oparams->cmask = __NEW_TO_OLD_MASK(params->cmask);
+ oparams->info = params->info;
+ oparams->msbits = params->msbits;
+ oparams->rate_num = params->rate_num;
+ oparams->rate_den = params->rate_den;
+ oparams->fifo_size = params->fifo_size;
+}
+
+static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams)
+{
+ snd_pcm_hw_params_t params;
+ struct sndrv_pcm_hw_params_old oparams;
+ int err;
+ if (copy_from_user(&oparams, _oparams, sizeof(oparams)))
+ return -EFAULT;
+ snd_pcm_hw_convert_from_old_params(&params, &oparams);
+ err = snd_pcm_hw_refine(substream, &params);
+ snd_pcm_hw_convert_to_old_params(&oparams, &params);
+ if (copy_to_user(_oparams, &oparams, sizeof(oparams)))
+ return -EFAULT;
+ return err;
+}
+
+static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams)
+{
+ snd_pcm_hw_params_t params;
+ struct sndrv_pcm_hw_params_old oparams;
+ int err;
+ if (copy_from_user(&oparams, _oparams, sizeof(oparams)))
+ return -EFAULT;
+ snd_pcm_hw_convert_from_old_params(&params, &oparams);
+ err = snd_pcm_hw_params(substream, &params);
+ snd_pcm_hw_convert_to_old_params(&oparams, &params);
+ if (copy_to_user(_oparams, &oparams, sizeof(oparams)))
+ return -EFAULT;
+ return err;
}

/*
diff -Nru a/sound/core/seq/oss/Makefile b/sound/core/seq/oss/Makefile
--- a/sound/core/seq/oss/Makefile Sun Sep 29 20:20:12 2002
+++ b/sound/core/seq/oss/Makefile Sun Sep 29 20:20:12 2002
@@ -7,8 +7,8 @@
seq_oss_event.o seq_oss_rw.o seq_oss_synth.o \
seq_oss_midi.o seq_oss_readq.o seq_oss_writeq.o

-obj-$(CONFIG_SND_SEQUENCER) += snd-seq-oss.o
-
ifeq ($(CONFIG_SND_SEQUENCER_OSS),y)
- include $(TOPDIR)/Rules.make
+ obj-$(CONFIG_SND_SEQUENCER) += snd-seq-oss.o
endif
+
+include $(TOPDIR)/Rules.make
diff -Nru a/sound/isa/Makefile b/sound/isa/Makefile
--- a/sound/isa/Makefile Sun Sep 29 20:20:12 2002
+++ b/sound/isa/Makefile Sun Sep 29 20:20:12 2002
@@ -3,8 +3,6 @@
# Copyright (c) 2001 by Jaroslav Kysela <[email protected]>
#

-mod-subdirs := ad1816a ad1848 cs423x es1688 gus opti9xx sb wavefront
-
snd-als100-objs := als100.o
snd-azt2320-objs := azt2320.o
snd-cmi8330-objs := cmi8330.o
diff -Nru a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
--- a/sound/isa/ad1848/ad1848_lib.c Sun Sep 29 20:20:12 2002
+++ b/sound/isa/ad1848/ad1848_lib.c Sun Sep 29 20:20:12 2002
@@ -24,11 +24,13 @@
#include <asm/io.h>
#include <asm/dma.h>
#include <linux/delay.h>
+#include <linux/init.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <sound/core.h>
#include <sound/ad1848.h>
+#include <sound/pcm_params.h>

MODULE_AUTHOR("Jaroslav Kysela <[email protected]>");
MODULE_DESCRIPTION("Routines for control of AD1848/AD1847/CS4248");
diff -Nru a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
--- a/sound/isa/cs423x/cs4231_lib.c Sun Sep 29 20:20:12 2002
+++ b/sound/isa/cs423x/cs4231_lib.c Sun Sep 29 20:20:12 2002
@@ -35,6 +35,7 @@
#include <linux/ioport.h>
#include <sound/core.h>
#include <sound/cs4231.h>
+#include <sound/pcm_params.h>

MODULE_AUTHOR("Jaroslav Kysela <[email protected]>");
MODULE_DESCRIPTION("Routines for control of CS4231(A)/CS4232/InterWave & compatible chips");
diff -Nru a/sound/isa/es18xx.c b/sound/isa/es18xx.c
--- a/sound/isa/es18xx.c Sun Sep 29 20:20:12 2002
+++ b/sound/isa/es18xx.c Sun Sep 29 20:20:12 2002
@@ -78,6 +78,7 @@
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include <sound/mpu401.h>
#include <sound/opl3.h>
#define SNDRV_LEGACY_AUTO_PROBE
diff -Nru a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
--- a/sound/isa/gus/gus_pcm.c Sun Sep 29 20:20:12 2002
+++ b/sound/isa/gus/gus_pcm.c Sun Sep 29 20:20:12 2002
@@ -32,6 +32,7 @@
#include <sound/core.h>
#include <sound/control.h>
#include <sound/gus.h>
+#include <sound/pcm_params.h>
#include "gus_tables.h"

#define chip_t snd_gus_card_t
diff -Nru a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
--- a/sound/pci/korg1212/korg1212.c Sun Sep 29 20:20:12 2002
+++ b/sound/pci/korg1212/korg1212.c Sun Sep 29 20:20:12 2002
@@ -29,6 +29,7 @@
#include <sound/info.h>
#include <sound/control.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#define SNDRV_GET_ID
#include <sound/initval.h>

diff -Nru a/sound/pci/rme32.c b/sound/pci/rme32.c
--- a/sound/pci/rme32.c Sun Sep 29 20:20:12 2002
+++ b/sound/pci/rme32.c Sun Sep 29 20:20:12 2002
@@ -23,8 +23,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
- * ToDo: - ADAT (32/8)
- * - full duplex (32, 32/8, 32Pro)
+ * ToDo: full duplex (32, 32/8, 32Pro)
*/

#include <sound/driver.h>
@@ -37,6 +36,7 @@
#include <sound/info.h>
#include <sound/control.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include <sound/asoundef.h>
#define SNDRV_GET_ID
#include <sound/initval.h>
@@ -327,6 +327,54 @@
fifo_size: 0,
};

+/*
+ * Digital output capabilites (ADAT)
+ */
+static snd_pcm_hardware_t snd_rme32_playback_adat_info =
+{
+ info: (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_PAUSE),
+ formats: SNDRV_PCM_FMTBIT_S16_LE,
+ rates: (SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000),
+ rate_min: 44100,
+ rate_max: 48000,
+ channels_min: 8,
+ channels_max: 8,
+ buffer_bytes_max: RME32_BUFFER_SIZE,
+ period_bytes_min: RME32_BLOCK_SIZE,
+ period_bytes_max: RME32_BLOCK_SIZE,
+ periods_min: RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
+ periods_max: RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
+ fifo_size: 0,
+};
+
+/*
+ * Digital input capabilites (ADAT)
+ */
+static snd_pcm_hardware_t snd_rme32_capture_adat_info =
+{
+ info: (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_PAUSE),
+ formats: SNDRV_PCM_FMTBIT_S16_LE,
+ rates: (SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000),
+ rate_min: 44100,
+ rate_max: 48000,
+ channels_min: 8,
+ channels_max: 8,
+ buffer_bytes_max: RME32_BUFFER_SIZE,
+ period_bytes_min: RME32_BLOCK_SIZE,
+ period_bytes_max: RME32_BLOCK_SIZE,
+ periods_min: RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
+ periods_max: RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
+ fifo_size: 0,
+};
+
static void snd_rme32_reset_dac(rme32_t *rme32)
{
writel(rme32->wcreg | RME32_WCR_PD,
@@ -359,15 +407,20 @@
static int snd_rme32_capture_getrate(rme32_t * rme32, int *is_adat)
{
int n;
- *is_adat = 0;

+ *is_adat = 0;
+ if (rme32->rcreg & RME32_RCR_LOCK) {
+ /* ADAT rate */
+ *is_adat = 1;
+ }
if (rme32->rcreg & RME32_RCR_ERF) {
return -1;
}

+ /* S/PDIF rate */
n = ((rme32->rcreg >> RME32_RCR_BITPOS_F0) & 1) +
- (((rme32->rcreg >> RME32_RCR_BITPOS_F1) & 1) << 1) +
- (((rme32->rcreg >> RME32_RCR_BITPOS_F2) & 1) << 2);
+ (((rme32->rcreg >> RME32_RCR_BITPOS_F1) & 1) << 1) +
+ (((rme32->rcreg >> RME32_RCR_BITPOS_F2) & 1) << 2);

if (RME32_PRO_WITH_8414(rme32))
switch (n) { /* supporting the CS8414 */
@@ -388,7 +441,8 @@
default:
return -1;
break;
- } else
+ }
+ else
switch (n) { /* supporting the CS8412 */
case 0:
return -1;
@@ -816,6 +870,62 @@
return 0;
}

+static int
+snd_rme32_playback_adat_open(snd_pcm_substream_t *substream)
+{
+ unsigned long flags;
+ rme32_t *rme32 = _snd_pcm_substream_chip(substream);
+ snd_pcm_runtime_t *runtime = substream->runtime;
+
+ snd_pcm_set_sync(substream);
+
+ spin_lock_irqsave(&rme32->lock, flags);
+ rme32->wcreg |= RME32_WCR_ADAT;
+ writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
+ rme32->playback_substream = substream;
+ rme32->playback_last_appl_ptr = 0;
+ rme32->playback_ptr = 0;
+ spin_unlock_irqrestore(&rme32->lock, flags);
+
+ runtime->hw = snd_rme32_playback_adat_info;
+ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+ RME32_BUFFER_SIZE, RME32_BUFFER_SIZE);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
+ &hw_constraints_period_bytes);
+ return 0;
+}
+
+static int
+snd_rme32_capture_adat_open(snd_pcm_substream_t *substream)
+{
+ unsigned long flags;
+ int isadat;
+ rme32_t *rme32 = _snd_pcm_substream_chip(substream);
+ snd_pcm_runtime_t *runtime = substream->runtime;
+
+ rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
+ if (snd_rme32_capture_getrate(rme32, &isadat) < 0) {
+ /* no input */
+ return -EIO;
+ }
+ if (!isadat) {
+ /* S/PDIF input */
+ return -EBUSY;
+ }
+ snd_pcm_set_sync(substream);
+
+ spin_lock_irqsave(&rme32->lock, flags);
+ rme32->capture_substream = substream;
+ rme32->capture_ptr = 0;
+ spin_unlock_irqrestore(&rme32->lock, flags);
+
+ runtime->hw = snd_rme32_capture_adat_info;
+ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+ RME32_BUFFER_SIZE, RME32_BUFFER_SIZE);
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
+ &hw_constraints_period_bytes);
+ return 0;
+}

static int snd_rme32_playback_close(snd_pcm_substream_t * substream)
{
@@ -1004,7 +1114,31 @@
snd_rme32_capture_pointer(snd_pcm_substream_t * substream)
{
rme32_t *rme32 = _snd_pcm_substream_chip(substream);
- return snd_rme32_capture_ptr(rme32);
+ snd_pcm_runtime_t *runtime = substream->runtime;
+ snd_pcm_uframes_t frameptr;
+ size_t ptr;
+
+ frameptr = snd_rme32_capture_ptr(rme32);
+ if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
+ ptr = frameptr << rme32->capture_frlog;
+ if (ptr > rme32->capture_ptr) {
+ memcpy_fromio(runtime->dma_area + rme32->capture_ptr,
+ rme32->iobase + RME32_IO_DATA_BUFFER +
+ rme32->capture_ptr,
+ ptr - rme32->capture_ptr);
+ rme32->capture_ptr += ptr - rme32->capture_ptr;
+ } else if (ptr < rme32->capture_ptr) {
+ memcpy_fromio(runtime->dma_area + rme32->capture_ptr,
+ rme32->iobase + RME32_IO_DATA_BUFFER +
+ rme32->capture_ptr,
+ RME32_BUFFER_SIZE - rme32->capture_ptr);
+ memcpy_fromio(runtime->dma_area,
+ rme32->iobase + RME32_IO_DATA_BUFFER,
+ ptr);
+ rme32->capture_ptr = ptr;
+ }
+ }
+ return frameptr;
}

static snd_pcm_ops_t snd_rme32_playback_spdif_ops = {
@@ -1032,6 +1166,31 @@
copy: snd_rme32_capture_copy,
};

+static snd_pcm_ops_t snd_rme32_playback_adat_ops = {
+ open: snd_rme32_playback_adat_open,
+ close: snd_rme32_playback_close,
+ ioctl: snd_pcm_lib_ioctl,
+ hw_params: snd_rme32_playback_hw_params,
+ hw_free: snd_rme32_playback_hw_free,
+ prepare: snd_rme32_playback_prepare,
+ trigger: snd_rme32_playback_trigger,
+ pointer: snd_rme32_playback_pointer,
+ copy: snd_rme32_playback_copy,
+ silence: snd_rme32_playback_silence,
+};
+
+static snd_pcm_ops_t snd_rme32_capture_adat_ops = {
+ open: snd_rme32_capture_adat_open,
+ close: snd_rme32_capture_close,
+ ioctl: snd_pcm_lib_ioctl,
+ hw_params: snd_rme32_capture_hw_params,
+ hw_free: snd_rme32_capture_hw_free,
+ prepare: snd_rme32_capture_prepare,
+ trigger: snd_rme32_capture_trigger,
+ pointer: snd_rme32_capture_pointer,
+ copy: snd_rme32_capture_copy,
+};
+
static void snd_rme32_free(void *private_data)
{
rme32_t *rme32 = (rme32_t *) private_data;
@@ -1063,6 +1222,14 @@
snd_pcm_lib_preallocate_free_for_all(pcm);
}

+static void
+snd_rme32_free_adat_pcm(snd_pcm_t *pcm)
+{
+ rme32_t *rme32 = (rme32_t *) pcm->private_data;
+ rme32->adat_pcm = NULL;
+ snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
static int __devinit snd_rme32_create(rme32_t * rme32)
{
struct pci_dev *pci = rme32->pci;
@@ -1117,10 +1284,33 @@
GFP_KERNEL);

/* set up ALSA pcm device for ADAT */
- if (pci->device == PCI_DEVICE_ID_DIGI32) {
- /* ADAT is not available on the base model */
+ if ((pci->device == PCI_DEVICE_ID_DIGI32) ||
+ (pci->device == PCI_DEVICE_ID_DIGI32_PRO)) {
+ /* ADAT is not available on DIGI32 and DIGI32 Pro */
rme32->adat_pcm = NULL;
}
+ else {
+ if ((err = snd_pcm_new(rme32->card, "Digi32 ADAT", 1,
+ 1, 1, &rme32->adat_pcm)) < 0)
+ {
+ return err;
+ }
+ rme32->adat_pcm->private_data = rme32;
+ rme32->adat_pcm->private_free = snd_rme32_free_adat_pcm;
+ strcpy(rme32->adat_pcm->name, "Digi32 ADAT");
+ snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ &snd_rme32_playback_adat_ops);
+ snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_CAPTURE,
+ &snd_rme32_capture_adat_ops);
+
+ rme32->adat_pcm->info_flags = 0;
+
+ snd_pcm_lib_preallocate_pages_for_all(rme32->adat_pcm,
+ RME32_BUFFER_SIZE,
+ RME32_BUFFER_SIZE,
+ GFP_KERNEL);
+ }
+

rme32->playback_periodsize = 0;
rme32->capture_periodsize = 0;
@@ -1137,8 +1327,8 @@

/* set default values in registers */
rme32->wcreg = RME32_WCR_SEL | /* normal playback */
- RME32_WCR_INP_0 | /* input select */
- RME32_WCR_MUTE; /* setting muting on */
+ RME32_WCR_INP_0 | /* input select */
+ RME32_WCR_MUTE; /* muting on */
writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);


diff -Nru a/sound/pci/rme96.c b/sound/pci/rme96.c
--- a/sound/pci/rme96.c Sun Sep 29 20:20:12 2002
+++ b/sound/pci/rme96.c Sun Sep 29 20:20:12 2002
@@ -33,6 +33,7 @@
#include <sound/info.h>
#include <sound/control.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include <sound/asoundef.h>
#define SNDRV_GET_ID
#include <sound/initval.h>
diff -Nru a/sound/pci/via8233.c b/sound/pci/via8233.c
--- a/sound/pci/via8233.c Sun Sep 29 20:20:12 2002
+++ b/sound/pci/via8233.c Sun Sep 29 20:20:12 2002
@@ -366,9 +366,9 @@
switch (runtime->channels) {
case 1: slots = (1<<0); break;
case 2: slots = (1<<0) | (2<<4); break;
- case 4: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12);
+ case 4: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12); break;
case 6: slots = (1<<0) | (2<<4) | (5<<8) | (6<<12) | (3<<16) | (4<<20); break;
- default: slots = 0;
+ default: slots = 0; break;
}
/* STOP index is never reached */
outl(0xff000000 | slots, chip->port + VIA_REG_MULTPLAY_STOP_IDX);

===================================================================


This BitKeeper patch contains the following changesets:
1.605.2.13
## Wrapped with gzip_uu ##


begin 664 bkpatch2308
M'XL(`%U$EST``^Q=>W?;-K+_6_H4:'NN5W(L&P\^K<1G%5OI:FO'.;:5[+E-
MCPY%4HF.)=$KRDZRJ^QGOP.`+_$%R4F:GMYU6U$B!S\,!H/!##[email protected]?T+#T%\>
M-^[\I?^Q^1/Z6Q"NCAOA?>@?NO^"WU=!`+^/[email protected]=S_TC0'(UOCV;3Q?W'3AC<
M+[SL]R;0OW)6[GOTX"_#XP8Y9,F=U:<[_[AQU?]Y>-Z[:C:?/4.G[YW%.__:
M7Z%GSYJK8/[email protected]+SPK\[J_2Q8'*Z6SB*<^ROGT`WFZX1T33&F\(].3(9U8TT,
MK)EKEWB$.!KQ/4PUR]":@M&_WBV"E7\HOG>FBQ6T)P]D4QU;F&G:FC*=XN89
M(H<&[email protected]_I(6$(TR-L'U$=$?V8LF.=/<'T&&-4!8Z>4(8ZN/D<?=W&G#9=U#N_
M[J'[.\]9^8B7.L+&[email protected]`4(=U%\`HNM[:#Q=S9WP-D33!7IU>@&/',^#^^']
MW5VP7*%)L$3S8.GS+W-G%:+Q)W3CW#KA^RER%AZ:^Q'BU46?4>0MI]"/I2B]
ML]X-:IU-WTT1HT=6N_D+8C9C=O-5VJW-SHY_S29V</,D$G"[email protected]?N]&@Y
M]QD]=*78-&IC0C5FK+%.37WM>X;CN41GSGAB8<>K[*8J0-`%[email protected]%K3-6)7
M\.&"^([email protected];N:0;OOW'E:GF&36-C2C+7!3([email protected]>Y5K>>.Q8*H:JD2/.
M*%M3G=IZPIGXS`$$8<@+C^YF]^^FB\/WD8Y!>9M13-;4MC5K;5A,]PS+UEW/
M,1QM.][*H6/F8`AIMFT4F9LNW-F]YQ]))$=<BGQA&(AD;;F>Y1#H6$-C8]LG
MU7S5H48L,;S636R0*GE-0^?(\8BE6=%E-)N.8YG'G-$U,['%UCK1J#^VF:E;
MCNXR7R6Q6O"806,[email protected]:C:F4=RB5>PA=9PY7::\W3=0/;GNT1![O>>*N>S&'&
M74C6FF%9N(H=/F)[email protected]^4[[email protected]+`TVU*9MX!H.>)&-CK)[email protected]\-,TU
M-K&M*>6U<%[email protected]$!FH*'>IAE[B.9NC4L<:>N[7(-F%CJ8&]8##L58H/`$6M
MYVT"NS]QJ$E=QYN88^+JYK9:GX&,-8H;+XN4C,)<4^;3T"V1#[[email protected]*O0FD['%
M[/&$&A/LU+%3`YK1*9U/8BJ;-0V*[%!3P]8:AI\^\7W'8!/#M+;C9A,QM9^:
M`6-EBYX:W3E+9QZ6=)A&=&B29U'-=77?!<#QQ-BAPW+(:;]1FYCF5J8=KB6R
M`F,.'3BVP7UPB*8QSS?U:E]%@9LQZF"EK#H+>N'<^I/IS"^834W701MM\&D(
M<XGM>$RW]6W,YB9B+"%M#8:.5$Y^O*`?$NOCQZ)%TL"WLX"5B>F#"[email protected]+=
ML7+8%Q%C5G08*)15#C)[email protected]_/"UIB8.NBA:_J6ZYJFX]LNN)[;6,<<
M9&P3H8LL4CV'\%:\NP_Y?R-N+XK"L6P0CCEVG8EI,=<P,;/<R3;"*8&-)62M
MN2M4.9/PTFZH4?917DC%S&O#;+OV0%;CB3ZFEC[VR'8J5`F>SKS8)[email protected]^
M3G'([email protected]#Z5,-:Y[!E0HF8=UYC"M5&'6$85S/7$E?<I=`L_2U#:;`A^D7(HB)
MJ=.MY[>BZ:8&-FK=`7"@;:/$!;!-PM9$US#S;&V,N<?D;>4";`#&*[email protected]:$
MULHC]/\II%IECC"U&7A+OJ7;Q*$>[email protected]!CM,:_5$+'4C+!&)BLQ,G<-/T\()X&
M90XY-H$Q!SL,C-,8O``R(:Q&BVIA([email protected])B"4$BS"[')/F<?<7]%1;V[&2G50
[email protected]]Y,2,6>.<Z9B+FMC:";<*.&58&VPRC#B'?)-K^N[,,[email protected]'[Y%/HS!SW=
M:-W)028$1\0ZQB:PC(Y%[-R3H?)J.7578LU#!MT0E2,GA!#ZW3L_7/%0_1/J
MC<$3"':LCDN%'FMV5-W7#/U_03)<ND2=Y0?Q+X3DKRKTYQ'!_1GH$"[email protected];S\
MY,%@6OCH^N79U>L1L#QZW;^Z'ER^;#2B6U>7-Y>GE^?Q_18][email protected]`
M_,*:C13BQ>751>]F=$VU$3OOHV>(T8/&T3X7RNK]TO>AU2L_1/M'586>][>F
M'\I*=J/?`?^:XIWP!?U._.^&/]P1_YI8N_'/Z7?A?T?\X8[XY[WK&]"@2ISF
M&85H!-107C(`?WLS>M6[ZEV,KGL7K\[[H^>#FVM`[email protected]/U\"H,/[email protected]*G?G=
MS.=UGS%,$&T.&*850)R7T>#E3?_J=>]\@ZF$Y&9P^@M\7/0!AVC(R`VPB][U
M+_#QCP;5C>;;)ABH>S!0X<);/HR$=?IWLW$_`MO*Z&C%K4GX:VNSY!-&VD>,
M_M9M?NX"PADCIF":6`C&8!%0F*-?JQK#4<%(-1N-!I)_)90O!E<QZ1-$H.:R
M:I9^^*O^6Y=W*WSUEP]@]:0I%**E4K24%KB$QOI\YD!3#F'G(.*G4CON%^'T
MW4+>1DL.WVUP\C?'4.*?]]*F)[5NDKLI^=4Q<L5\M,FBQ=5(7M*B0+A,V/G5
MT'+\<8,^N5_=+R,5TB2([email protected]"V*)0>DK[+"V4>LH9'!2+X%!K$V%EZ`7
MO`2J]!)[email protected],_J^7\!6]!+G"5.LEB(Y\A(LPT#&H+Q<(&"]4'.SP57P9K;K-
M,Y/3#L1GX][08IY!P[F*9^SVQ0U8X-&^&"<$%((:X#N8!F)6B1<245];C4:+
M#,_/[email protected]%QW6%AW6%;TFQNB\7UNSH%!`/%="/*^#&"JY&*JX&"JY
M&*JXX/Z80A:"[email protected]&AD([email protected]&N(DHNABHNADHNABHMKF)45LA`4"@B%+`1%74.4
M7`Q57`R57`Q57+PXO^3>6;\&(R91HCQ7HZAY,;0MN#$42A(3J3DR%+HRZ)_:
MNC6Z'CY_`3Y4'ZI%U8A%XAV0G^^"7,OSQ1"\PC=U:B$I:B!Z*H2>`F!PT1OU
MSN!&#49"4]>65_V?:UL"SVN*_WQ]45<:'M<-\E?]TT'OO&Z02PJ%T62U"AU1
M*$Q>/<90B1'%XRH^E-:['F.HQ(CB\%H^L%(>*HRA$B.*[U5\*[email protected],:*X
MOM;!L%3R4&(,E1C1>H&*#X6GH\(8QAAGE&(>25(14#923W2'0'>;$!?JL44]
MC%<7KIS5U`7O>L;YSU2Z[P8+\(]#\;O%'_#]A/<?1O*^`_%/F"$[X/7'D7:&
M6NQ&`MV#LX0F&N`<,WX1ZQKRTECZ$!XNT)[<N.R<R.9"`6A5;8-X8PR3KPX,
M#`O#)>X&B31R7-</P]9=.VW7?+IH)5R)EL'[email protected][)J>J>G_>OK=CL/*H.`1X+*
M/B^"AO?C+\+EDV`,?68R$:GS"\LL?Z2++QRJW6WRI8/2?A5U&5K2Z<O[Q6HZ
M]WEO1U\/*[email protected])1%;@1256E<7^R4[U-^+_CAGF:[L?S"G.QN`K<(`"L:QBO
[email protected]!`Z,.M?Z[-/`5EP9D$H-J:2#IS\=L(C";CQZ-(KULA9,OM38,C2\`
M?/`1M!^%`9J`K3(TOJ:)@L7L$U\'*"EZ/?A?F`[email protected](,9K:`W'_\L5U:]IN
MM.`#[email protected]/?<8BHG'9,@G%$&UAQB!H?\6!K\NQC[_;,S]>>BO6ESJ8F<CG/[+
M#R:M?3$H852>@[email protected]/CC9'*0YQWMQPB)*[email protected]@4^]V>`V9=IM-GAG
MMJ;H&<)=-$5/\U!P\\F3-AB+Z02)*CLG8D5X^AN_&<\(N)M,#J0+-?`]F;B&
M,]L0M1J\UJUJXPO0]?5-)F'N([email protected]@6D3L$'2.C2V\;F9X6Y`,,[R1,3Z^H!?
[email protected],\3R6^GLP5K,X_F6:MF"[email protected]*^<$6]R3<,+07ZY:?"'ZZ;.\+O/"
M&>!$_X"Z_1M:/TM5CM_AV&!(.#;1OA![[QGZ3Q%<N"[email protected]?Y&6*E-4R2HHJ0/M
M[:'),[email protected]]?EOH`W^2:%P90]-<4Z>"%S#[email protected]?C=^=E0S22&29V&[email protected]
MFK6Q^O_0W:(;'H"'FJ[(]W+J?2Z"A=^*9O&:SGS&V0`N3;G_:G+/8U=;L*'?
M7`8/R2^.K<FQ)2ZQLO\`L\+<G=]%9NMA:YM%-,FIN#2$100&]T4C="I$K;.M
M%#SB9`?A`K296(T#Y`K)\'K%Q",N>%>;]@,[email protected]%;3Q;W?+3,NP%;N!EBE
M=M[ZBG)NX:[[Y,F&S2$\JL!RKU)<4OWA&T&KT9)[.'[email protected]@A$CDH$6;134S2
M3Y0^XH[Y+]4G.%3Y+]C01`85A&O2-20X[QOJ1.D;$M3Y-JDE0W&&PT/\\XC[
MZG$3I&E:O??E68_3U]=HM?2Y4R53>6J=JD0,C_*HQ,9A)B7C]/+EB\'/(U"`
MT5GOIH]^1*TWP/+?[Q=(^JL$'[email protected]$HTO#[email protected]]MD0K'IOVF]LWK(&Q
M*[email protected]#6081&L#R"D#51WG(MSK)\X?QU64N=$ZM2N3ZF&T\KB;-GR(=14^+
MGO])F<HD2<AJO=DQ#[I>>W)@Z=8SS#6&[email protected]"G$C\B=7(ID>7J][email protected]?
M8YRH*5?=S/RJ6RC9$C^[A?6X+D_+H1M3G7"5]B)?Z8Q:FLS=$5%+2L6#K#TY
M$Z8+.7*Q:71QT7LELW#.^[W7_3.)[email protected]<8WN<JS=%%$NBB.R-[6%>7K[,(3$L
MVB4O`"2E!'Y*O"+$4XY'7'?\>*U,[email protected][07E:D$LN06*)MW->(X9XBC-9K]$,J
M=3\$1K,`!W$/M;D;!%@R/P5'+11HVY0&KQVB2;EF)[email protected];EV2ZK*2D
MCHTJ)G/)7(4IBI.SM[-&NV6)JPU2'B^>UG2+6';%M+:%3=+_$$FSW]0FR>1Y
MM4V*)?R8"8XQY00'@YK)0<TOR4+^:G,[email protected][email protected],<"Q=8NDY,[email protected]+
MXIDLUI6I,+/I`I2;WVV5I*>@=5F^"UI#-;:([email protected]*>R31WBRW8[;&
ME_NI7/?AXR\J=2C"&"SBFGM&VQ&#/'3)4T"DGR7IEN"0!*<5M_3DA"_4%?!(
MBI<C36/#4A,![8R$SPTAD8907`I=N&%,TUX[V-BNR9I6#BBMH;B4V*E-,Q69
M49XIB&6F((Z+_5"N357EF6P'DY-5M/[email protected])J(LG)32%X:I1:\HFB]>2T+';_X
M//.C`>D:9KO(OM+'V%?487]NZRI/>6]M71\5D4);P,S!1?I6^.L,NVY>$\69
MIWKUV^&[email protected]')Q!;P897O7=$MUB?HGSX^E8?/JA5-2/4Q<S?AOCK,HG+V
M:L79+`>;=YYG[PP+-,,"39P%DKN3P\G3#`LT<?9$[LXF3H%FF-`4E5P>@%0J
M^BZO&:A5]BQ0]K07M:7"&X]0>`J65?_N"O]GVJN5[WJH'5^R(Q]CP2TB?%]Y
MJ4QRX'0&[email protected][@B9&XZM<&?OP(/=2'2)TUE$PDHWVAJXDZOD?$\B\H$SNZ7Q
M0[&FC0]0[E1+!UQ!=(2L=I<?SG%GOCPOL1+'.+B+LU$##"W,?<S(<^ST!R]?
M]\Z[V=V]S\VWOU_J1O/?4F:UN3\@P[T(O7.R2=5]A,@S\A`./7>OD\V;6/X9
M&I*G$=V2>N&E?45+^\K0ZOM*;K-DF=M#F_?(;[email protected]^(5%.SFWY8>JTF2F
M+KI-=YC*L[R`1.Z4C0I=Z"P^M61D>(!NDYW'VDKCTUZ*BC-DO/(2XR_?RJ&V
M_KN\$J3>_&\BQ0L7$+O:[email protected]\!*..\[email protected]&]]L`98JK?(4K:/<7LTAHQF
MPW5"OQC!1S[0<>WSYW7/L:(\KB\O_9GZY[S\0"[email protected]%4M&*H:,50T8JA
MHA7#I!66]B5]H9"[email protected]!12B/%YQD]]*U0:H]*(VK[:HB][email protected]`L=O2_
M4#._5"<2IX)8W6\US+97\)@9*M*HF,9S;+Z-Z=AZT`Z(88OC_M^[H[YWWWSG
M?DAU0^M&BS/_[90_3*?(MPJ$:!\QWCN:_F>8]*FI(_OKR0A_Q/!GX?1S>'Y>
M:71W-YH2/UM!+?[.,T2$3]-/@7_&+)$:QRSAZ<7[`].9#RZJ2!*+0BW/63DR
MXSA1%A&)-?P9,,!SUAH?WD,QU(H(.AUT(@/?1F._)4,Y8O"(L<VQVD^>\`UF
M61''^<R9T%.[0+5C`9N&_Q%Q9E\Z6JF-'[email protected]$[V7W9K"LLU!4+%%X-_7/3Y
MFQH^+*<K7[[]PY?^^-A?K?PE^N!\.CP4<60C28RLD()$+20`LB11,B,DJUQ&
M//B%LOL\E.4%/@N9P;_0A9;L0GOG+M1V[D+1$Y5=>,9L3?!BZSOS8NW,BUC3
MJ.2E)*R-7\:I#FQW>QMH?6B[B94N;FJ,8)DI9!:"6_5)%$(IZI#O']TFJ7TR
MNKWRYP%_28C'%XN0Z\QF:9(B#W*7_LSGPYL_&3ON;:H!#HPL9P:#*H3"P9WO
M_:'";/&ZUOHP.^[G1^4&:(CAYM%^$P8"[email protected]=X`UGLZFJT]-;F%R+]_)KA.%
MHV#FB3?Q9#/()S/G'5^IV[A9>>@P.6N&.M'":^7IN=*[email protected]%-62_*V
M(5E+0_7VHZBFDM?HE+XL)[email protected]$!0&$?$&[email protected]_-'B?EYZW_,7<L$S$OO]
M!&3N\Z72R702C'@F>K?VW3GRS4?%TZ2#R].;<][PJ_Z+P<O^Z/+\#,'--U>M
MO_3^PH_K$&X=:WN][)!J`BOD>5T"2]2P;\M23X!F*6KC-",[email protected]<MD23J\'P.D
M+]:=]U'R2U41T(X"^1-L?WF5*?4WJ/*M'''1$!OH?.YZRX]<$2I?%B<NN;,9
MP.?\KOKL;O+&K>AH+I%GJ>0E7</%.ZW1HN89)3+YD&AQ'L;=$OBY;?WX/Q]_
M/$#[<[E:+3)JY#OSY*6>E#!3'[email protected])A,ON\JD1)8L]`/CFZ=7XP7JZH.Q612^
MI+TWC^HUHG,E1I)W]T,NK40FA=SR3!+"[email protected]]@!;)I3N*[email protected]`*U?)@=*.3JS8
M9B7RKHV(N=#E+H"XTF;#7RXSWFCIKDVR15,)[email protected]`B[9Q$DP\7U]&1"O<1J&?$
M(GP9=$`LD9&4;`&YSAU_E=>(S[FM9!RU19BNZR5K."6&*QM+UEB+=)"V5*.T
M#>[`NW8Q_BDQ;^65%^S&(RJ'&!(\,I.)_;EH;KX)P/T'"R^]G/?^##R2$%PP
M=.O[=^!K+)SE)^263."QJ1YQGD<WEZ.7_3=B"ZCUL8U:K8][9GO-+Q"HF1/^
M9[6?/M4SY\I'[email protected]+"XIB$XS;)R=Z.V/%'X*IE].F!W^Y&G''3$A(-KY5
M%!\,^WAPJ(066]5FWA69<CL;^_TQ6N;H:E2.=W;\[email protected]#AO<`("#9NE)P[BS`2
M.N'A\/V^^(18AI%[email protected]^EN21IBI,[email protected]^#@'*77F7IZE
MY-%&"Y>1-2UJ0[!!DBWCJLNX^3+<"\HV*_**DE:&<HLZT^[814K8B+RC+%'&
M8]JX!<[email protected]$E'QD[31N^FGM1GM=:[email protected]@V=W4XMBUOD&>56Z&Q0HK1!1FN#
MO-I^&ZTMJ&:FIKPFIUI;IJ([:VU05-N\+2IH;5!4VZHR;J%,I+8YK0T*:EO0
MVH**[email protected][MU1K?S^/.9?'D2BU_)(/T8I004+(>0:7(\J:
M=H.[3W)J$!SO)>H_2L?2AK:TVQOI+2]ZP_.;;C['I'3"V8L!XTJX$A2<'RG#
M[`R^EU(K#43*[email protected]%:U,V[:W6RNC&T)\U6KP#:.8_S=J$!O\/[P:Y!8>
M\_\[email protected]/]K[^A_TT:6/Y._8G7O%.&6I,8V!`B)[email protected]'DGNJ5(ERX!#?'4P
MSS;M5:7_^YN9]<?ZDX]>[MJ^1!$8[^SL>F9V/3L[.U-N?-PM)T&Q`3(?GQ`I
MEQ(1Y'M8'JV/I__/NZ[#<KC=4>0.7`06R*5M>H</\+SL8>GYJ*X'9VZF#,V1
MN'#"U'/TX,[email protected]>3R[IW*V1/AESQG\<_%H53DM?]_]]V[\\[X\D]ISD
M_0!:/L"SCPX&,R"+1'AFZ-?JS=6P-QA)+^*'%,1-3(13*&7;Y]_)%:XLFEBF
MFH"0YT5L9T(LK3\[email protected]&[email protected]>[email protected]\.L&<YGEJNAZD/*[email protected])Y-E%<IK`
M]R1C<Q+#E?)XYRQU>X9MS'^S7&<^`TWHT/L$=#>-0TK9>>BXL\/EATV:@:5S
MO:$<:1I(E::V\Z<8M;G>B?LG/[2PI5RV.DJC`ST2G<D?+,^SYC/6)1Z]L.:6
M?WA_RF<]#/'`$VW6"P[N%W#Q+SC"G^@.GES;XH!_04:F4I'?.3U4X0Q7B#%,
MW-E:R4VU711/;KUT?T<A(QKRH^R<4<JL0L'+(?!.VV='6XI6F*2M5)ZVRPVW
M]\&P?O,7]4-W>>\>+.?6P=B9W"\?#J=F(<X&/'6S7I<Q]Z76*CCIHC9^)#%Z
MI`U8GCVO4(Y"LNXB/"UY2^%))+$KE:`[email protected],2H(ZK*9R$M(SZM'TE\
M'FD6XJD%"\4G0=L=]^\WEZ&"O+6%DO1-271SY:D48RA5[96LJ5HS7Y'7UB\.
M?WZIHL3"N4)50."=1&L;M4G([email protected]&Q4605.Y89`TGZH*%J/
M)#8\,V6AW`14W4E6&EO*[email protected]:MLQ,N_D*,@=YL&YL:"NEV0Y2/69GG_5F
M!.6QS`@A.P>?#(MU?0N^N`Q-S91G''15ZRBA#<%(K-7&KFE\.,0CZY2)MU`8
M(NKL%*6O2?$G^5>%[Z5K'>;9#H_S4N]V98FM6%7I=C6Z4+O=%EUHW6Y=D8YY
M/]%/^(C\+_A7I3(U[XRE[<>XY`@T9?ZTG(EOJPI*H9IXR>48*U.PR:56<]54
MCUKUU5&[+M>GTVEKTIJ.QT84MZ,T'VLN9A[Y40%V*QKP-U]]VB#N7ZOU6)$?
M-Y>[email protected]?^4[(F3DIHZH^,Z(S(0=+74-H%)JP\NNTT)\D-!KI7^3:$JI`+(WQ%
MGHMP_>@.B]#&H[@L`M[(4Q&N)\)UZ)>(CQ>Y(R*\X(48_N2[D$2539T-F:X;
MON]:XR74UZO5A3'Y8$XEZ?BG=T$!*CTYH3PYH7Q_3BB"8#ZYH3RYH?QM;[email protected]
M4B)[email protected]>ELIH\+S"ML91/[email protected]'M)D9.D5&<S!M,3[#SU0][email protected]"AT:Y9\*ZD8&'
M=U2EU$V!8%"4'G3/G#V8<QA^J,_`#Z##S(2WB%>[email protected],'K_YNC^Z[+_1>]>)
MS7[!J8&W7F-5'.?/)/Z$7`9YD23QLUO<&R'>[Z_,'-\!6>+-?=W,S8$?>@H:
MC7T<D(K`1][email protected](@ANZKA'6"_[WX^.`4VSITID)H3/*8Q]#S!(XF0AT^+Z+O\
MT%2BN^N=)4*Z)-`E/"[email protected]>:1C+$T[QE+$XY>PEN!<[email protected]&SC6409J'
M,[email protected]!SP//X/[ES>A=E5QK0O&!B2;Y,^U-?!UZ$Z.;=`G&A#L7QYJ0
MYBSFR$EZ/681S6:8HSX/5)Z<H=1%&X;:R;;G2X"'M5RTL?-U#MJUYTL([7NT
MF5*^D2_EON4H5V?#+`,D]K564%[email protected][@)5SEC-RM:G`@A?OVE*6ZXKFMI<
MR6BN6)G3IC&=U!NJ,;YKR<9T,RRQT4Q3VYJ6OP35UI\&[email protected]*K<Z
M#:TC:]$BU/`/%H8_N4<KV%O#]:TY+Z&/@\3Z%(&#96N5$B[UK)G%8.79DKXG
MTYW6T,JL-0%O=XI?V>0QR]%+Z!G#@P8]I\/NEK;-ILN%;?[)JBC-2!'\'+J.
MA.=LU]K[!JK29EHK.+^`5/4-FSE+?[&$M[RQ,[email protected][$:BTPJ!$A&]
M)PQW^LEP,>08WJ*'U!>V\1D/<.K(.9UK2OC&QZM.$+Q-""0\N+RXHF#H;!7'
M=LLIUG\_>S/HE0`)L<M+H(9GM]<[email protected]>)?]E(QG7,[email protected]'5YG4H"6GB*
MT=E-7]<TS!&U8GF-<P`\OR\%V##E7Z)UJAX5&G\F"[$J%,+2?CXW;2]1NY4H
[email protected])J5Z/9X>7=GNOKX,W0_1#IZV\>\R+<7%_T1)[email protected][email protected],-X3CN`.[-U?GK
M?+`$NBP81\3[DFD3EA-E%:.'V+!BI.T&U8!67Z-S?)%T6_-O%.[P4-23;#_)
M]C\@[email protected]'OJ4V%V_)5#)/^S/)(.'FB*5+/27)AW3AQ85VT'S0P.A_IV`:H
MXFR/I?Y>/&,X+,C6B",C72XT4B=%'5JG]U-<__K%L#>XB##[email protected]/&?Z`,')5*
MM9KLUNFIT"\0SN'5M7Y1QV2'\-'MXN?S3:LI<36%`JZW^0Y%F[)^5+Z"#&,P
M"1XHM-$45L9[16\Q9V'.\WWSXX.1"2,-K8M#^PK'B&$Y\0+UXBRJR;V5/&49
M+<:R83W1_3V$!$KPFU`CKH,+)N_S?)+`^![*%]9<MQUX+,O]KV=\-*O[`3WQ
M9HWW6#JN!'T^./U$9%Z=!&3^#Y`9)0,:H^@G=E6$J['@E^6,<4?I>5!K<*6?
M7\&:YNH-J.^O!M<PETG'41,1I:.^BL^7`V<;GJ\;BX6M+WPWD/,T3%Q"C[R<
MAP^-(3Y!E\M_;B2A$-PT.&90I-9D%LS125QK#F.\]"QN,.9?OKOI7POIE+.S
M5_96]E1#V*YM>7[<JIS;\+`_&[email protected]\*]BC.AL-R6TY:DO8(7X[<-%S)P
M>HCH[QL[[R,1XA/+"0.`:23>FPETF,[email protected]&9Z>,LR%'5V#Y_-(D,,&1"@MER
M[@2J"[email protected],"7W$;$IU4#^L%58()-J_:R]OK=TGCTU\V'X0/M6:LAF`[#L/W
MQ<,PHX#]?X["'JA3/)H!?BN-75X780TA<@E>`,^P$-0-/"R&/X`=84DN+^`^
ME^YP$$3,XUG9,=+U^OQ7)-B\B:@U>(6G).K.M9W9<1"]`4%.TQ!P,PBKQ;<8
MR-QJ.7&[email protected]^&#GJ]`<,Y6U7,;5\X^.$->!8(`ZDEJ0H%Z+"W!WF]/::<F]F1
M\_RDL,XQ*3(4$RLD1(94WRTALFIO,5G6='W;7J;X44CZ$Q826<Q]&H\/&'>J
MAN,NM6AT%EZ),01*`?,[email protected]?%0*5,W<=EC.YZ9#T9%`$+;`@%($&.?[^Q`
M6638[.1AB$HYY)UKFD5P6(;K%]>$&OE001E`^:[email protected]<VL'+Q\7+
MD`#.XG/!\T-)#6<IBNN6BR8H"Y9):_B44E^*V)31<G*Y%$+MS*00P1H>"6#%
M+(JDNHQ#(5`[email protected]),Q?R)GIS80X2'D=)LL):X;[email protected]*0RXL[WA*N(
M&?VO&MV1<#\$='[7^DA;HGPS,!C,(4ZH<<D#9HK4!V([email protected]<6(^Z<.>X.MS!
M#0&):[F].F8FI^SG2IU27,,\"^463#[F1PO#39ZPX?E`[_5_'YSW]4%/[PU>
M#3`#Q&JU1U/,)M#Z<'0E14H=K;HM#_1!GQD?#<LVQK;)G#GCP&1N#BZ'KH-J
M'W9/98JR%P=(I(XF3TG/S4_5:)9SIS7V"UK$``LV^$N-U<5Y$7-;P/]^BI*2
M%.X9?A%R1/.MNLK72F6ODJ9]DC>H4V/Y<[email protected],B.A8R0$!*N"'H-^`QD,<P/5
MK<1ST>PNJL`PL-,51?7L^F;41^7LS=F[EV?GKVMD[*KLE\SF.[9P?C:\N1WU
MLPVDIR'"GT<OU'SUT)]#)A6M4,`[email protected]#",[WC_FM%K^8MRU]=#'6^N2[1
M"H3&D1:,(XT;8&)3PN!RJ*-1$22?KV,\TS8GP7(F!GM[>],_KB#4P])''UD8
B$`"R]R\VI$VDR;TY^>`M'TZ,[email protected];L:<I[_P-\2%<MB*X`````
`
end

-----
Jaroslav Kysela <[email protected]>
Linux Kernel Sound Maintainer
ALSA Project http://www.alsa-project.org
SuSE Linux http://www.suse.com