* [PATCH v2 1/4] ALSA: emu10k1: automate encoding of sub-register definitions
@ 2023-05-14 17:03 Oswald Buddenhagen
2023-05-14 17:03 ` [PATCH v2 2/4] ALSA: emu10k1: validate parameters of snd_emu10k1_ptr_{read,write}() Oswald Buddenhagen
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Oswald Buddenhagen @ 2023-05-14 17:03 UTC (permalink / raw)
To: alsa-devel; +Cc: Takashi Iwai, Jaroslav Kysela
The idea to encode the bitfield manipulation in the register address is
quite clever, but doing that by hand is ugly and error-prone. So derive
it automatically from the mask instead.
Macros cannot #define other macros, so we now declare enums instead.
This also adds macros for decoding the register definitions. These will
be used by later commits.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
---
v2: added comments
---
include/sound/emu10k1.h | 123 ++++++++++++++++++++--------------------
1 file changed, 60 insertions(+), 63 deletions(-)
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 7129b9249eb3..e9b1729ade60 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -38,6 +38,32 @@
#define IP_TO_CP(ip) ((ip == 0) ? 0 : (((0x00001000uL | (ip & 0x00000FFFL)) << (((ip >> 12) & 0x000FL) + 4)) & 0xFFFF0000uL))
+// This is used to define hardware bit-fields (sub-registers) by combining
+// the bit shift and count with the actual register address. The passed
+// mask must represent a single run of adjacent bits.
+// The non-concatenating (_NC) variant should be used directly only for
+// sub-registers that do not follow the <register>_<field> naming pattern.
+#define SUB_REG_NC(reg, field, mask) \
+ enum { \
+ field ## _MASK = mask, \
+ field = reg | \
+ (__builtin_ctz(mask) << 16) | \
+ (__builtin_popcount(mask) << 24), \
+ };
+#define SUB_REG(reg, field, mask) SUB_REG_NC(reg, reg ## _ ## field, mask)
+
+// Macros for manipulating values of bit-fields declared using the above macros.
+// Best used with constant register addresses, as otherwise quite some code is
+// generated. The actual register read/write functions handle combined addresses
+// automatically, so use of these macros conveys no advantage when accessing a
+// single sub-register at a time.
+#define REG_SHIFT(r) (((r) >> 16) & 0x1f)
+#define REG_SIZE(r) (((r) >> 24) & 0x1f)
+#define REG_MASK0(r) ((1U << REG_SIZE(r)) - 1U)
+#define REG_MASK(r) (REG_MASK0(r) << REG_SHIFT(r))
+#define REG_VAL_GET(r, v) ((v & REG_MASK(r)) >> REG_SHIFT(r))
+#define REG_VAL_PUT(r, v) ((v) << REG_SHIFT(r))
+
// Audigy specify registers are prefixed with 'A_'
/************************************************************************************************/
@@ -148,12 +174,10 @@
#define INTE_MIDIRXENABLE 0x00000001 /* Enable MIDI receive-buffer-empty interrupts */
#define WC 0x10 /* Wall Clock register */
-#define WC_SAMPLECOUNTER_MASK 0x03FFFFC0 /* Sample periods elapsed since reset */
-#define WC_SAMPLECOUNTER 0x14060010
-#define WC_CURRENTCHANNEL_MASK 0x0000003F /* Channel [0..63] currently being serviced */
+SUB_REG(WC, SAMPLECOUNTER, 0x03FFFFC0) /* Sample periods elapsed since reset */
+SUB_REG(WC, CURRENTCHANNEL, 0x0000003F) /* Channel [0..63] currently being serviced */
/* NOTE: Each channel takes 1/64th of a sample */
/* period to be serviced. */
-#define WC_CURRENTCHANNEL 0x06000010
#define HCFG 0x14 /* Hardware config register */
/* NOTE: There is no reason to use the legacy */
@@ -225,9 +249,8 @@
/* async audio source */
#define HCFG_LOCKSOUNDCACHE 0x00000008 /* 1 = Cancel bustmaster accesses to soundcache */
/* NOTE: This should generally never be used. */
-#define HCFG_LOCKTANKCACHE_MASK 0x00000004 /* 1 = Cancel bustmaster accesses to tankcache */
+SUB_REG(HCFG, LOCKTANKCACHE, 0x00000004) /* 1 = Cancel bustmaster accesses to tankcache */
/* NOTE: This should generally never be used. */
-#define HCFG_LOCKTANKCACHE 0x01020014
#define HCFG_MUTEBUTTONENABLE 0x00000002 /* 1 = Master mute button sets AUDIOENABLE = 0. */
/* NOTE: This is a 'cheap' way to implement a */
/* master mute function on the mute button, and */
@@ -382,55 +405,38 @@
// which the current registers "swerve" gradually.
#define CPF 0x00 /* Current pitch and fraction register */
-#define CPF_CURRENTPITCH_MASK 0xffff0000 /* Current pitch (linear, 0x4000 == unity pitch shift) */
-#define CPF_CURRENTPITCH 0x10100000
+SUB_REG(CPF, CURRENTPITCH, 0xffff0000) /* Current pitch (linear, 0x4000 == unity pitch shift) */
#define CPF_STEREO_MASK 0x00008000 /* 1 = Even channel interleave, odd channel locked */
#define CPF_STOP_MASK 0x00004000 /* 1 = Current pitch forced to 0 */
#define CPF_FRACADDRESS_MASK 0x00003fff /* Linear fractional address of the current channel */
#define PTRX 0x01 /* Pitch target and send A/B amounts register */
-#define PTRX_PITCHTARGET_MASK 0xffff0000 /* Pitch target of specified channel */
-#define PTRX_PITCHTARGET 0x10100001
-#define PTRX_FXSENDAMOUNT_A_MASK 0x0000ff00 /* Linear level of channel output sent to FX send bus A */
-#define PTRX_FXSENDAMOUNT_A 0x08080001
-#define PTRX_FXSENDAMOUNT_B_MASK 0x000000ff /* Linear level of channel output sent to FX send bus B */
-#define PTRX_FXSENDAMOUNT_B 0x08000001
+SUB_REG(PTRX, PITCHTARGET, 0xffff0000) /* Pitch target of specified channel */
+SUB_REG(PTRX, FXSENDAMOUNT_A, 0x0000ff00) /* Linear level of channel output sent to FX send bus A */
+SUB_REG(PTRX, FXSENDAMOUNT_B, 0x000000ff) /* Linear level of channel output sent to FX send bus B */
#define CVCF 0x02 /* Current volume and filter cutoff register */
-#define CVCF_CURRENTVOL_MASK 0xffff0000 /* Current linear volume of specified channel */
-#define CVCF_CURRENTVOL 0x10100002
-#define CVCF_CURRENTFILTER_MASK 0x0000ffff /* Current filter cutoff frequency of specified channel */
-#define CVCF_CURRENTFILTER 0x10000002
+SUB_REG(CVCF, CURRENTVOL, 0xffff0000) /* Current linear volume of specified channel */
+SUB_REG(CVCF, CURRENTFILTER, 0x0000ffff) /* Current filter cutoff frequency of specified channel */
#define VTFT 0x03 /* Volume target and filter cutoff target register */
-#define VTFT_VOLUMETARGET_MASK 0xffff0000 /* Volume target of specified channel */
-#define VTFT_VOLUMETARGET 0x10100003
-#define VTFT_FILTERTARGET_MASK 0x0000ffff /* Filter cutoff target of specified channel */
-#define VTFT_FILTERTARGET 0x10000003
+SUB_REG(VTFT, VOLUMETARGET, 0xffff0000) /* Volume target of specified channel */
+SUB_REG(VTFT, FILTERTARGET, 0x0000ffff) /* Filter cutoff target of specified channel */
#define Z1 0x05 /* Filter delay memory 1 register */
#define Z2 0x04 /* Filter delay memory 2 register */
#define PSST 0x06 /* Send C amount and loop start address register */
-#define PSST_FXSENDAMOUNT_C_MASK 0xff000000 /* Linear level of channel output sent to FX send bus C */
-
-#define PSST_FXSENDAMOUNT_C 0x08180006
-
-#define PSST_LOOPSTARTADDR_MASK 0x00ffffff /* Loop start address of the specified channel */
-#define PSST_LOOPSTARTADDR 0x18000006
+SUB_REG(PSST, FXSENDAMOUNT_C, 0xff000000) /* Linear level of channel output sent to FX send bus C */
+SUB_REG(PSST, LOOPSTARTADDR, 0x00ffffff) /* Loop start address of the specified channel */
#define DSL 0x07 /* Send D amount and loop end address register */
-#define DSL_FXSENDAMOUNT_D_MASK 0xff000000 /* Linear level of channel output sent to FX send bus D */
-
-#define DSL_FXSENDAMOUNT_D 0x08180007
-
-#define DSL_LOOPENDADDR_MASK 0x00ffffff /* Loop end address of the specified channel */
-#define DSL_LOOPENDADDR 0x18000007
+SUB_REG(DSL, FXSENDAMOUNT_D, 0xff000000) /* Linear level of channel output sent to FX send bus D */
+SUB_REG(DSL, LOOPENDADDR, 0x00ffffff) /* Loop end address of the specified channel */
#define CCCA 0x08 /* Filter Q, interp. ROM, byte size, cur. addr register */
-#define CCCA_RESONANCE_MASK 0xf0000000 /* Lowpass filter resonance (Q) height */
-#define CCCA_RESONANCE 0x041c0008
+SUB_REG(CCCA, RESONANCE, 0xf0000000) /* Lowpass filter resonance (Q) height */
#define CCCA_INTERPROM_MASK 0x0e000000 /* Selects passband of interpolation ROM */
/* 1 == full band, 7 == lowpass */
/* ROM 0 is used when pitch shifting downward or less */
@@ -447,27 +453,24 @@
#define CCCA_INTERPROM_7 0x0e000000 /* Select interpolation ROM 7 */
#define CCCA_8BITSELECT 0x01000000 /* 1 = Sound memory for this channel uses 8-bit samples */
/* 8-bit samples are unsigned, 16-bit ones signed */
-#define CCCA_CURRADDR_MASK 0x00ffffff /* Current address of the selected channel */
-#define CCCA_CURRADDR 0x18000008
+SUB_REG(CCCA, CURRADDR, 0x00ffffff) /* Current address of the selected channel */
#define CCR 0x09 /* Cache control register */
-#define CCR_CACHEINVALIDSIZE 0x07190009
-#define CCR_CACHEINVALIDSIZE_MASK 0xfe000000 /* Number of invalid samples before the read address */
+SUB_REG(CCR, CACHEINVALIDSIZE, 0xfe000000) /* Number of invalid samples before the read address */
#define CCR_CACHELOOPFLAG 0x01000000 /* 1 = Cache has a loop service pending */
#define CCR_INTERLEAVEDSAMPLES 0x00800000 /* 1 = A cache service will fetch interleaved samples */
/* Auto-set from CPF_STEREO_MASK */
#define CCR_WORDSIZEDSAMPLES 0x00400000 /* 1 = A cache service will fetch word sized samples */
/* Auto-set from CCCA_8BITSELECT */
-#define CCR_READADDRESS 0x06100009
-#define CCR_READADDRESS_MASK 0x003f0000 /* Next cached sample to play */
-#define CCR_LOOPINVALSIZE 0x0000fe00 /* Number of invalid samples in cache prior to loop */
+SUB_REG(CCR, READADDRESS, 0x003f0000) /* Next cached sample to play */
+SUB_REG(CCR, LOOPINVALSIZE, 0x0000fe00) /* Number of invalid samples in cache prior to loop */
/* NOTE: This is valid only if CACHELOOPFLAG is set */
#define CCR_LOOPFLAG 0x00000100 /* Set for a single sample period when a loop occurs */
-#define CCR_CACHELOOPADDRHI 0x000000ff /* CLP_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set */
+SUB_REG(CCR, CACHELOOPADDRHI, 0x000000ff) /* CLP_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set */
#define CLP 0x0a /* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */
/* NOTE: This register is normally not used */
-#define CLP_CACHELOOPADDR 0x0000ffff /* Cache loop address low word */
+SUB_REG(CLP, CACHELOOPADDR, 0x0000ffff) /* Cache loop address low word */
#define FXRT 0x0b /* Effects send routing register */
/* NOTE: It is illegal to assign the same routing to */
@@ -537,20 +540,17 @@
#define IP_UNITY 0x0000e000 /* Unity pitch shift */
#define IFATN 0x19 /* Initial filter cutoff and attenuation register */
-#define IFATN_FILTERCUTOFF_MASK 0x0000ff00 /* Initial filter cutoff frequency in exponential units */
+SUB_REG(IFATN, FILTERCUTOFF, 0x0000ff00) /* Initial filter cutoff frequency in exponential units */
/* 6 most significant bits are semitones */
/* 2 least significant bits are fractions */
-#define IFATN_FILTERCUTOFF 0x08080019
-#define IFATN_ATTENUATION_MASK 0x000000ff /* Initial attenuation in 0.375dB steps */
-#define IFATN_ATTENUATION 0x08000019
+SUB_REG(IFATN, ATTENUATION, 0x000000ff) /* Initial attenuation in 0.375dB steps */
#define PEFE 0x1a /* Pitch envelope and filter envelope amount register */
-#define PEFE_PITCHAMOUNT_MASK 0x0000ff00 /* Pitch envlope amount */
+SUB_REG(PEFE, PITCHAMOUNT, 0x0000ff00) /* Pitch envlope amount */
/* Signed 2's complement, +/- one octave peak extremes */
-#define PEFE_PITCHAMOUNT 0x0808001a
-#define PEFE_FILTERAMOUNT_MASK 0x000000ff /* Filter envlope amount */
+SUB_REG(PEFE, FILTERAMOUNT, 0x000000ff) /* Filter envlope amount */
/* Signed 2's complement, +/- six octaves peak extremes */
-#define PEFE_FILTERAMOUNT 0x0800001a
+
#define FMMOD 0x1b /* Vibrato/filter modulation from LFO register */
#define FMMOD_MODVIBRATO 0x0000ff00 /* Vibrato LFO modulation depth */
@@ -793,22 +793,19 @@
#define SRCS_SPDIFRATE_96 0x00080000
#define MICIDX 0x63 /* Microphone recording buffer index register */
-#define MICIDX_MASK 0x0000ffff /* 16-bit value */
-#define MICIDX_IDX 0x10000063
+SUB_REG(MICIDX, IDX, 0x0000ffff)
#define ADCIDX 0x64 /* ADC recording buffer index register */
-#define ADCIDX_MASK 0x0000ffff /* 16 bit index field */
-#define ADCIDX_IDX 0x10000064
+SUB_REG(ADCIDX, IDX, 0x0000ffff)
#define A_ADCIDX 0x63
-#define A_ADCIDX_IDX 0x10000063
+SUB_REG(A_ADCIDX, IDX, 0x0000ffff)
#define A_MICIDX 0x64
-#define A_MICIDX_IDX 0x10000064
+SUB_REG(A_MICIDX, IDX, 0x0000ffff)
#define FXIDX 0x65 /* FX recording buffer index register */
-#define FXIDX_MASK 0x0000ffff /* 16-bit value */
-#define FXIDX_IDX 0x10000065
+SUB_REG(FXIDX, IDX, 0x0000ffff)
/* The 32-bit HLIEx and HLIPx registers all have one bit per channel control/status */
#define HLIEL 0x66 /* Channel half loop interrupt enable low register */
@@ -852,8 +849,8 @@
#define A_SPDIF_44100 0x00000080
#define A_SPDIF_MUTED 0x000000c0
-#define A_I2S_CAPTURE_RATE_MASK 0x00000e00 /* This sets the capture PCM rate, but it is */
-#define A_I2S_CAPTURE_RATE 0x03090076 /* unclear if this sets the ADC rate as well. */
+SUB_REG_NC(A_EHC, A_I2S_CAPTURE_RATE, 0x00000e00) /* This sets the capture PCM rate, but it is */
+ /* unclear if this sets the ADC rate as well. */
#define A_I2S_CAPTURE_48000 0x0
#define A_I2S_CAPTURE_192000 0x1
#define A_I2S_CAPTURE_96000 0x2
--
2.40.0.152.g15d061e6df
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 2/4] ALSA: emu10k1: validate parameters of snd_emu10k1_ptr_{read,write}()
2023-05-14 17:03 [PATCH v2 1/4] ALSA: emu10k1: automate encoding of sub-register definitions Oswald Buddenhagen
@ 2023-05-14 17:03 ` Oswald Buddenhagen
2023-05-14 17:03 ` [PATCH v2 3/4] ALSA: emu10k1: merge common paths in snd_emu10k1_ptr_{read,write}() Oswald Buddenhagen
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Oswald Buddenhagen @ 2023-05-14 17:03 UTC (permalink / raw)
To: alsa-devel; +Cc: Takashi Iwai, Jaroslav Kysela
Rather than applying masks to the provided values, make assertions
about them being valid - otherwise we'd just try to paper over bugs.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
---
sound/pci/emu10k1/io.c | 29 ++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index aee84c3f9f37..ced69165d69a 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -18,14 +18,27 @@
#include <linux/export.h>
#include "p17v.h"
+static inline bool check_ptr_reg(struct snd_emu10k1 *emu, unsigned int reg)
+{
+ if (snd_BUG_ON(!emu))
+ return false;
+ if (snd_BUG_ON(reg & (emu->audigy ? (0xffff0000 & ~A_PTR_ADDRESS_MASK)
+ : (0xffff0000 & ~PTR_ADDRESS_MASK))))
+ return false;
+ if (snd_BUG_ON(reg & 0x0000ffff & ~PTR_CHANNELNUM_MASK))
+ return false;
+ return true;
+}
+
unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
{
unsigned long flags;
unsigned int regptr, val;
unsigned int mask;
- mask = emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK;
- regptr = ((reg << 16) & mask) | (chn & PTR_CHANNELNUM_MASK);
+ regptr = (reg << 16) | chn;
+ if (!check_ptr_reg(emu, regptr))
+ return 0;
if (reg & 0xff000000) {
unsigned char size, offset;
@@ -57,18 +70,20 @@ void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned i
unsigned long flags;
unsigned int mask;
- if (snd_BUG_ON(!emu))
+ regptr = (reg << 16) | chn;
+ if (!check_ptr_reg(emu, regptr))
return;
- mask = emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK;
- regptr = ((reg << 16) & mask) | (chn & PTR_CHANNELNUM_MASK);
if (reg & 0xff000000) {
unsigned char size, offset;
size = (reg >> 24) & 0x3f;
offset = (reg >> 16) & 0x1f;
- mask = ((1 << size) - 1) << offset;
- data = (data << offset) & mask;
+ mask = (1 << size) - 1;
+ if (snd_BUG_ON(data & ~mask))
+ return;
+ mask <<= offset;
+ data <<= offset;
spin_lock_irqsave(&emu->emu_lock, flags);
outl(regptr, emu->port + PTR);
--
2.40.0.152.g15d061e6df
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 3/4] ALSA: emu10k1: merge common paths in snd_emu10k1_ptr_{read,write}()
2023-05-14 17:03 [PATCH v2 1/4] ALSA: emu10k1: automate encoding of sub-register definitions Oswald Buddenhagen
2023-05-14 17:03 ` [PATCH v2 2/4] ALSA: emu10k1: validate parameters of snd_emu10k1_ptr_{read,write}() Oswald Buddenhagen
@ 2023-05-14 17:03 ` Oswald Buddenhagen
2023-05-14 17:03 ` [PATCH v2 4/4] ALSA: emu10k1: optimize mask calculation in snd_emu10k1_ptr_read() Oswald Buddenhagen
2023-05-15 20:01 ` [PATCH v2 1/4] ALSA: emu10k1: automate encoding of sub-register definitions Takashi Iwai
3 siblings, 0 replies; 5+ messages in thread
From: Oswald Buddenhagen @ 2023-05-14 17:03 UTC (permalink / raw)
To: alsa-devel; +Cc: Takashi Iwai, Jaroslav Kysela
Avoids some code duplication.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
---
sound/pci/emu10k1/io.c | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index ced69165d69a..2d6bbb77c961 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -40,24 +40,20 @@ unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, un
if (!check_ptr_reg(emu, regptr))
return 0;
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ outl(regptr, emu->port + PTR);
+ val = inl(emu->port + DATA);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+
if (reg & 0xff000000) {
unsigned char size, offset;
size = (reg >> 24) & 0x3f;
offset = (reg >> 16) & 0x1f;
mask = ((1 << size) - 1) << offset;
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + PTR);
- val = inl(emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-
return (val & mask) >> offset;
} else {
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + PTR);
- val = inl(emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
return val;
}
}
@@ -88,14 +84,12 @@ void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned i
spin_lock_irqsave(&emu->emu_lock, flags);
outl(regptr, emu->port + PTR);
data |= inl(emu->port + DATA) & ~mask;
- outl(data, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
} else {
spin_lock_irqsave(&emu->emu_lock, flags);
outl(regptr, emu->port + PTR);
- outl(data, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
+ outl(data, emu->port + DATA);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
}
EXPORT_SYMBOL(snd_emu10k1_ptr_write);
--
2.40.0.152.g15d061e6df
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 4/4] ALSA: emu10k1: optimize mask calculation in snd_emu10k1_ptr_read()
2023-05-14 17:03 [PATCH v2 1/4] ALSA: emu10k1: automate encoding of sub-register definitions Oswald Buddenhagen
2023-05-14 17:03 ` [PATCH v2 2/4] ALSA: emu10k1: validate parameters of snd_emu10k1_ptr_{read,write}() Oswald Buddenhagen
2023-05-14 17:03 ` [PATCH v2 3/4] ALSA: emu10k1: merge common paths in snd_emu10k1_ptr_{read,write}() Oswald Buddenhagen
@ 2023-05-14 17:03 ` Oswald Buddenhagen
2023-05-15 20:01 ` [PATCH v2 1/4] ALSA: emu10k1: automate encoding of sub-register definitions Takashi Iwai
3 siblings, 0 replies; 5+ messages in thread
From: Oswald Buddenhagen @ 2023-05-14 17:03 UTC (permalink / raw)
To: alsa-devel; +Cc: Takashi Iwai, Jaroslav Kysela
Unlike in snd_emu10k1_ptr_write(), we don't need to keep the value's
bits in place, so we can save one shift.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
---
sound/pci/emu10k1/io.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index 2d6bbb77c961..59b0f4d08c6b 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -50,9 +50,9 @@ unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, un
size = (reg >> 24) & 0x3f;
offset = (reg >> 16) & 0x1f;
- mask = ((1 << size) - 1) << offset;
+ mask = (1 << size) - 1;
- return (val & mask) >> offset;
+ return (val >> offset) & mask;
} else {
return val;
}
--
2.40.0.152.g15d061e6df
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v2 1/4] ALSA: emu10k1: automate encoding of sub-register definitions
2023-05-14 17:03 [PATCH v2 1/4] ALSA: emu10k1: automate encoding of sub-register definitions Oswald Buddenhagen
` (2 preceding siblings ...)
2023-05-14 17:03 ` [PATCH v2 4/4] ALSA: emu10k1: optimize mask calculation in snd_emu10k1_ptr_read() Oswald Buddenhagen
@ 2023-05-15 20:01 ` Takashi Iwai
3 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2023-05-15 20:01 UTC (permalink / raw)
To: Oswald Buddenhagen; +Cc: alsa-devel, Jaroslav Kysela
On Sun, 14 May 2023 19:03:20 +0200,
Oswald Buddenhagen wrote:
>
> The idea to encode the bitfield manipulation in the register address is
> quite clever, but doing that by hand is ugly and error-prone. So derive
> it automatically from the mask instead.
>
> Macros cannot #define other macros, so we now declare enums instead.
>
> This also adds macros for decoding the register definitions. These will
> be used by later commits.
>
> Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
> ---
> v2: added comments
Applied all four patches now. Thanks.
Takashi
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-05-15 20:02 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-14 17:03 [PATCH v2 1/4] ALSA: emu10k1: automate encoding of sub-register definitions Oswald Buddenhagen
2023-05-14 17:03 ` [PATCH v2 2/4] ALSA: emu10k1: validate parameters of snd_emu10k1_ptr_{read,write}() Oswald Buddenhagen
2023-05-14 17:03 ` [PATCH v2 3/4] ALSA: emu10k1: merge common paths in snd_emu10k1_ptr_{read,write}() Oswald Buddenhagen
2023-05-14 17:03 ` [PATCH v2 4/4] ALSA: emu10k1: optimize mask calculation in snd_emu10k1_ptr_read() Oswald Buddenhagen
2023-05-15 20:01 ` [PATCH v2 1/4] ALSA: emu10k1: automate encoding of sub-register definitions Takashi Iwai
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.