All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] RME HDSP fixes
@ 2013-01-15 14:18 Adrian Knoth
  2013-01-15 14:18 ` [PATCH 1/4] ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes Adrian Knoth
  0 siblings, 1 reply; 9+ messages in thread
From: Adrian Knoth @ 2013-01-15 14:18 UTC (permalink / raw)
  To: patch; +Cc: Adrian Knoth, alsa-devel

Hi,

here's v2 of my previous series of patches for the RME HDSP.

Changes to the previous version:
   - correct time value in verbose output ("iobox found after %d ms")
   - define and use constants for iobox detection (no more 0x10a0)
   - hdsp_toggle_setting: only change register if newval != oldval

Adrian Knoth (4):
  ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes
  ALSA: hdsp - Implement generic function to toggle settings
  ALSA: hdsp - Use HDSP_TOGGLE_SETTING to alter settings
  ALSA: hdsp - Remove obsolete settings functions

 sound/pci/rme9652/hdsp.c |  461 ++++++++++++----------------------------------
 1 file changed, 116 insertions(+), 345 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/4] ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes
  2013-01-15 14:18 [PATCH v2 0/4] RME HDSP fixes Adrian Knoth
@ 2013-01-15 14:18 ` Adrian Knoth
  2013-01-15 14:18   ` [PATCH 2/4] ALSA: hdsp - Implement generic function to toggle settings Adrian Knoth
  2013-01-15 15:11   ` [PATCH 1/4] ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes Takashi Iwai
  0 siblings, 2 replies; 9+ messages in thread
From: Adrian Knoth @ 2013-01-15 14:18 UTC (permalink / raw)
  To: patch; +Cc: Adrian Knoth, alsa-devel

The current iobox detection code reportedly fails for various users, so
simply do what the Win32 driver does instead.

Patch originally by Karl Grill <kgrill@chello.at> and then modified to
comply with kernel coding guidelines + current HEAD.

Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>

diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 4fae81f..ba190d5 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -154,10 +154,12 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
 #define HDSP_BIGENDIAN_MODE     0x200
 #define HDSP_RD_MULTIPLE        0x400
 #define HDSP_9652_ENABLE_MIXER  0x800
+#define HDSP_S200		0x800
+#define HDSP_CYCLIC_MODE	0x1000
 #define HDSP_TDO                0x10000000
 
-#define HDSP_S_PROGRAM     	(HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
-#define HDSP_S_LOAD		(HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
+#define HDSP_S_PROGRAM	    (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
+#define HDSP_S_LOAD	    (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
 
 /* Control Register bits */
 
@@ -671,13 +673,23 @@ static unsigned int hdsp_read(struct hdsp *hdsp, int reg)
 
 static int hdsp_check_for_iobox (struct hdsp *hdsp)
 {
+	int i;
+
 	if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
-	if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
-		snd_printk("Hammerfall-DSP: no IO box connected!\n");
-		hdsp->state &= ~HDSP_FirmwareLoaded;
-		return -EIO;
+	for (i = 0; i < 500; i++) {
+		if (0 == (hdsp_read(hdsp, HDSP_statusRegister) &
+					HDSP_ConfigError)) {
+			if (i) {
+				snd_printk("Hammerfall-DSP: IO box found after %d ms\n",
+						(20 * i));
+			}
+			return 0;
+		}
+		msleep(20);
 	}
-	return 0;
+	snd_printk("Hammerfall-DSP: no IO box connected!\n");
+	hdsp->state &= ~HDSP_FirmwareLoaded;
+	return -EIO;
 }
 
 static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
@@ -728,6 +740,7 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
 
 		if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
 			snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n");
+			hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
 			return -EIO;
 		}
 
@@ -737,17 +750,15 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
 			hdsp_write(hdsp, HDSP_fifoData, cache[i]);
 			if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
 				snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
+				hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
 				return -EIO;
 			}
 		}
 
-		ssleep(3);
-
-		if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
-			snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
-		    	return -EIO;
-		}
+		hdsp_fifo_wait(hdsp, 3, HDSP_LONG_WAIT);
+		hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
 
+		ssleep(3);
 #ifdef SNDRV_BIG_ENDIAN
 		hdsp->control2_register = HDSP_BIGENDIAN_MODE;
 #else
@@ -773,24 +784,51 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
 {
 	if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
 
-		hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
-		hdsp_write (hdsp, HDSP_fifoData, 0);
-		if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
-			return -EIO;
+		hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
+		hdsp_write(hdsp, HDSP_fifoData, 0);
 
-		hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
+		if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+			hdsp_write(hdsp, HDSP_control2Reg, 0x100 | HDSP_S200);
+			hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
+		}
+
+		hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200 | HDSP_PROGRAM);
 		hdsp_write (hdsp, HDSP_fifoData, 0);
+		if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+			hdsp->io_type = Multiface;
+			snd_printk("Hammerfall-DSP: Multiface found\n");
+			return 0;
+		}
 
-		if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) {
-			hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
-			hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
-			if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT))
-				hdsp->io_type = RPM;
-			else
-				hdsp->io_type = Multiface;
-		} else {
+		hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
+		hdsp_write(hdsp, HDSP_fifoData, 0);
+		if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) {
 			hdsp->io_type = Digiface;
+			snd_printk("Hammerfall-DSP: Digiface found\n");
+			return 0;
 		}
+
+		hdsp_write(hdsp, HDSP_control2Reg, 0x100 | HDSP_S200);
+		hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
+		hdsp_write(hdsp, HDSP_fifoData, 0);
+		if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) {
+			hdsp->io_type = Multiface;
+			snd_printk("Hammerfall-DSP: Multiface found\n");
+			return 0;
+		}
+
+		hdsp_write(hdsp, HDSP_control2Reg, 0x100 | HDSP_S200);
+		hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
+		hdsp_write(hdsp, HDSP_fifoData, 0);
+		if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+			hdsp->io_type = Multiface;
+			snd_printk("Hammerfall-DSP: Multiface found\n");
+			return 0;
+		}
+
+		hdsp->io_type = RPM;
+		snd_printk("Hammerfall-DSP: RPM found\n");
+		return 0;
 	} else {
 		/* firmware was already loaded, get iobox type */
 		if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/4] ALSA: hdsp - Implement generic function to toggle settings
  2013-01-15 14:18 ` [PATCH 1/4] ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes Adrian Knoth
@ 2013-01-15 14:18   ` Adrian Knoth
  2013-01-15 14:18     ` [PATCH 3/4] ALSA: hdsp - Use HDSP_TOGGLE_SETTING to alter settings Adrian Knoth
  2013-01-15 15:11   ` [PATCH 1/4] ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes Takashi Iwai
  1 sibling, 1 reply; 9+ messages in thread
From: Adrian Knoth @ 2013-01-15 14:18 UTC (permalink / raw)
  To: patch; +Cc: Adrian Knoth, alsa-devel

The driver contains multiple similar functions that change only a single
bit in the control register, only the bit position varies.

This patch implements a generic function to toggle a certain bit
position that will be used to replace the old code.

Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>

diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index ba190d5..cdc2b20 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -1712,6 +1712,65 @@ static int snd_hdsp_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_e
 	return change;
 }
 
+#define HDSP_TOGGLE_SETTING(xname, xindex) \
+{   .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.private_value = xindex, \
+	.info = snd_hdsp_info_toggle_setting, \
+	.get = snd_hdsp_get_toggle_setting, \
+	.put = snd_hdsp_put_toggle_setting \
+}
+
+static int hdsp_toggle_setting(struct hdsp *hdsp, u32 regmask)
+{
+	return (hdsp->control_register & regmask) ? 1 : 0;
+}
+
+static int hdsp_set_toggle_setting(struct hdsp *hdsp, u32 regmask, int out)
+{
+	if (out)
+		hdsp->control_register |= regmask;
+	else
+		hdsp->control_register &= ~regmask;
+	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
+
+	return 0;
+}
+
+#define snd_hdsp_info_toggle_setting		   snd_ctl_boolean_mono_info
+
+static int snd_hdsp_get_toggle_setting(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+	u32 regmask = kcontrol->private_value;
+
+	spin_lock_irq(&hdsp->lock);
+	ucontrol->value.integer.value[0] = hdsp_toggle_setting(hdsp, regmask);
+	spin_unlock_irq(&hdsp->lock);
+	return 0;
+}
+
+static int snd_hdsp_put_toggle_setting(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+	u32 regmask = kcontrol->private_value;
+	int change;
+	unsigned int val;
+
+	if (!snd_hdsp_use_is_exclusive(hdsp))
+		return -EBUSY;
+	val = ucontrol->value.integer.value[0] & 1;
+	spin_lock_irq(&hdsp->lock);
+	change = (int) val != hdsp_toggle_setting(hdsp, regmask);
+	if (change)
+		hdsp_set_toggle_setting(hdsp, regmask, val);
+	spin_unlock_irq(&hdsp->lock);
+	return change;
+}
+
+
 #define HDSP_SPDIF_OUT(xname, xindex) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
   .info = snd_hdsp_info_spdif_bits, \
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/4] ALSA: hdsp - Use HDSP_TOGGLE_SETTING to alter settings
  2013-01-15 14:18   ` [PATCH 2/4] ALSA: hdsp - Implement generic function to toggle settings Adrian Knoth
@ 2013-01-15 14:18     ` Adrian Knoth
  2013-01-15 14:18       ` [PATCH 4/4] ALSA: hdsp - Remove obsolete settings functions Adrian Knoth
  0 siblings, 1 reply; 9+ messages in thread
From: Adrian Knoth @ 2013-01-15 14:18 UTC (permalink / raw)
  To: patch; +Cc: Adrian Knoth, alsa-devel

HDSP_TOGGLE_SETTING and its corresponding functions allow to change
settings in the control register. Instead of using the specialised
functions, use the generic code to make the code DRY.

Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>

diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index cdc2b20..45a101a 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -3287,7 +3287,7 @@ static struct snd_kcontrol_new snd_hdsp_9632_controls[] = {
 HDSP_DA_GAIN("DA Gain", 0),
 HDSP_AD_GAIN("AD Gain", 0),
 HDSP_PHONE_GAIN("Phones Gain", 0),
-HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0),
+HDSP_TOGGLE_SETTING("XLR Breakout Cable", HDSP_XLRBreakoutCable),
 HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0)
 };
 
@@ -3329,10 +3329,10 @@ static struct snd_kcontrol_new snd_hdsp_controls[] = {
 },
 HDSP_MIXER("Mixer", 0),
 HDSP_SPDIF_IN("IEC958 Input Connector", 0),
-HDSP_SPDIF_OUT("IEC958 Output also on ADAT1", 0),
-HDSP_SPDIF_PROFESSIONAL("IEC958 Professional Bit", 0),
-HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0),
-HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0),
+HDSP_TOGGLE_SETTING("IEC958 Output also on ADAT1", HDSP_SPDIFOpticalOut),
+HDSP_TOGGLE_SETTING("IEC958 Professional Bit", HDSP_SPDIFProfessional),
+HDSP_TOGGLE_SETTING("IEC958 Emphasis Bit", HDSP_SPDIFEmphasis),
+HDSP_TOGGLE_SETTING("IEC958 Non-audio Bit", HDSP_SPDIFNonAudio),
 /* 'Sample Clock Source' complies with the alsa control naming scheme */
 HDSP_CLOCK_SOURCE("Sample Clock Source", 0),
 {
@@ -3352,7 +3352,7 @@ HDSP_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
 HDSP_WC_SYNC_CHECK("Word Clock Lock Status", 0),
 HDSP_SPDIF_SYNC_CHECK("SPDIF Lock Status", 0),
 HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0),
-HDSP_LINE_OUT("Line Out", 0),
+HDSP_TOGGLE_SETTING("Line Out", HDSP_LineOut),
 HDSP_PRECISE_POINTER("Precise Pointer", 0),
 HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0),
 };
@@ -3669,7 +3669,9 @@ static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = {
 	HDSP_MIXER("Mixer", 0)
 };
 
-static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
+static struct snd_kcontrol_new snd_hdsp_96xx_aeb =
+	HDSP_TOGGLE_SETTING("Analog Extension Board",
+			HDSP_AnalogExtensionBoard);
 static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
 
 static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
@@ -4092,7 +4094,9 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 		}
 		snd_iprintf(buffer, "Phones Gain : %s\n", tmp);
 
-		snd_iprintf(buffer, "XLR Breakout Cable : %s\n", hdsp_xlr_breakout_cable(hdsp) ? "yes" : "no");
+		snd_iprintf(buffer, "XLR Breakout Cable : %s\n",
+			hdsp_toggle_setting(hdsp, HDSP_XLRBreakoutCable) ?
+			"yes" : "no");
 
 		if (hdsp->control_register & HDSP_AnalogExtensionBoard)
 			snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n");
@@ -5123,29 +5127,38 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
 		for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i)
 			info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
 		info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
-		info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
-		info.spdif_professional = (unsigned char)hdsp_spdif_professional(hdsp);
-		info.spdif_emphasis = (unsigned char)hdsp_spdif_emphasis(hdsp);
-		info.spdif_nonaudio = (unsigned char)hdsp_spdif_nonaudio(hdsp);
+		info.spdif_out = (unsigned char)hdsp_toggle_setting(hdsp,
+				HDSP_SPDIFOpticalOut);
+		info.spdif_professional = (unsigned char)
+			hdsp_toggle_setting(hdsp, HDSP_SPDIFProfessional);
+		info.spdif_emphasis = (unsigned char)
+			hdsp_toggle_setting(hdsp, HDSP_SPDIFEmphasis);
+		info.spdif_nonaudio = (unsigned char)
+			hdsp_toggle_setting(hdsp, HDSP_SPDIFNonAudio);
 		info.spdif_sample_rate = hdsp_spdif_sample_rate(hdsp);
 		info.system_sample_rate = hdsp->system_sample_rate;
 		info.autosync_sample_rate = hdsp_external_sample_rate(hdsp);
 		info.system_clock_mode = (unsigned char)hdsp_system_clock_mode(hdsp);
 		info.clock_source = (unsigned char)hdsp_clock_source(hdsp);
 		info.autosync_ref = (unsigned char)hdsp_autosync_ref(hdsp);
-		info.line_out = (unsigned char)hdsp_line_out(hdsp);
+		info.line_out = (unsigned char)
+			hdsp_toggle_setting(hdsp, HDSP_LineOut);
 		if (hdsp->io_type == H9632) {
 			info.da_gain = (unsigned char)hdsp_da_gain(hdsp);
 			info.ad_gain = (unsigned char)hdsp_ad_gain(hdsp);
 			info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp);
-			info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
+			info.xlr_breakout_cable =
+				(unsigned char)hdsp_toggle_setting(hdsp,
+					HDSP_XLRBreakoutCable);
 
 		} else if (hdsp->io_type == RPM) {
 			info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp);
 			info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp);
 		}
 		if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
-			info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
+			info.analog_extension_board =
+				(unsigned char)hdsp_toggle_setting(hdsp,
+					    HDSP_AnalogExtensionBoard);
 		spin_unlock_irqrestore(&hdsp->lock, flags);
 		if (copy_to_user(argp, &info, sizeof(info)))
 			return -EFAULT;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/4] ALSA: hdsp - Remove obsolete settings functions
  2013-01-15 14:18     ` [PATCH 3/4] ALSA: hdsp - Use HDSP_TOGGLE_SETTING to alter settings Adrian Knoth
@ 2013-01-15 14:18       ` Adrian Knoth
  0 siblings, 0 replies; 9+ messages in thread
From: Adrian Knoth @ 2013-01-15 14:18 UTC (permalink / raw)
  To: patch; +Cc: Adrian Knoth, alsa-devel

With HDSP_TOGGLE_SETTING in place, these functions are no longer
required. Removing them makes the code DRY and considerably shorter.

Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>

diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 45a101a..6cce259 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -1770,185 +1770,6 @@ static int snd_hdsp_put_toggle_setting(struct snd_kcontrol *kcontrol,
 	return change;
 }
 
-
-#define HDSP_SPDIF_OUT(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
-  .info = snd_hdsp_info_spdif_bits, \
-  .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out }
-
-static int hdsp_spdif_out(struct hdsp *hdsp)
-{
-	return (hdsp->control_register & HDSP_SPDIFOpticalOut) ? 1 : 0;
-}
-
-static int hdsp_set_spdif_output(struct hdsp *hdsp, int out)
-{
-	if (out)
-		hdsp->control_register |= HDSP_SPDIFOpticalOut;
-	else
-		hdsp->control_register &= ~HDSP_SPDIFOpticalOut;
-	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
-	return 0;
-}
-
-#define snd_hdsp_info_spdif_bits	snd_ctl_boolean_mono_info
-
-static int snd_hdsp_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
-	ucontrol->value.integer.value[0] = hdsp_spdif_out(hdsp);
-	return 0;
-}
-
-static int snd_hdsp_put_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-	int change;
-	unsigned int val;
-
-	if (!snd_hdsp_use_is_exclusive(hdsp))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdsp->lock);
-	change = (int)val != hdsp_spdif_out(hdsp);
-	hdsp_set_spdif_output(hdsp, val);
-	spin_unlock_irq(&hdsp->lock);
-	return change;
-}
-
-#define HDSP_SPDIF_PROFESSIONAL(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
-  .info = snd_hdsp_info_spdif_bits, \
-  .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional }
-
-static int hdsp_spdif_professional(struct hdsp *hdsp)
-{
-	return (hdsp->control_register & HDSP_SPDIFProfessional) ? 1 : 0;
-}
-
-static int hdsp_set_spdif_professional(struct hdsp *hdsp, int val)
-{
-	if (val)
-		hdsp->control_register |= HDSP_SPDIFProfessional;
-	else
-		hdsp->control_register &= ~HDSP_SPDIFProfessional;
-	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
-	return 0;
-}
-
-static int snd_hdsp_get_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
-	ucontrol->value.integer.value[0] = hdsp_spdif_professional(hdsp);
-	return 0;
-}
-
-static int snd_hdsp_put_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-	int change;
-	unsigned int val;
-
-	if (!snd_hdsp_use_is_exclusive(hdsp))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdsp->lock);
-	change = (int)val != hdsp_spdif_professional(hdsp);
-	hdsp_set_spdif_professional(hdsp, val);
-	spin_unlock_irq(&hdsp->lock);
-	return change;
-}
-
-#define HDSP_SPDIF_EMPHASIS(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
-  .info = snd_hdsp_info_spdif_bits, \
-  .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis }
-
-static int hdsp_spdif_emphasis(struct hdsp *hdsp)
-{
-	return (hdsp->control_register & HDSP_SPDIFEmphasis) ? 1 : 0;
-}
-
-static int hdsp_set_spdif_emphasis(struct hdsp *hdsp, int val)
-{
-	if (val)
-		hdsp->control_register |= HDSP_SPDIFEmphasis;
-	else
-		hdsp->control_register &= ~HDSP_SPDIFEmphasis;
-	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
-	return 0;
-}
-
-static int snd_hdsp_get_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
-	ucontrol->value.integer.value[0] = hdsp_spdif_emphasis(hdsp);
-	return 0;
-}
-
-static int snd_hdsp_put_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-	int change;
-	unsigned int val;
-
-	if (!snd_hdsp_use_is_exclusive(hdsp))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdsp->lock);
-	change = (int)val != hdsp_spdif_emphasis(hdsp);
-	hdsp_set_spdif_emphasis(hdsp, val);
-	spin_unlock_irq(&hdsp->lock);
-	return change;
-}
-
-#define HDSP_SPDIF_NON_AUDIO(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
-  .info = snd_hdsp_info_spdif_bits, \
-  .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio }
-
-static int hdsp_spdif_nonaudio(struct hdsp *hdsp)
-{
-	return (hdsp->control_register & HDSP_SPDIFNonAudio) ? 1 : 0;
-}
-
-static int hdsp_set_spdif_nonaudio(struct hdsp *hdsp, int val)
-{
-	if (val)
-		hdsp->control_register |= HDSP_SPDIFNonAudio;
-	else
-		hdsp->control_register &= ~HDSP_SPDIFNonAudio;
-	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
-	return 0;
-}
-
-static int snd_hdsp_get_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
-	ucontrol->value.integer.value[0] = hdsp_spdif_nonaudio(hdsp);
-	return 0;
-}
-
-static int snd_hdsp_put_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-	int change;
-	unsigned int val;
-
-	if (!snd_hdsp_use_is_exclusive(hdsp))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdsp->lock);
-	change = (int)val != hdsp_spdif_nonaudio(hdsp);
-	hdsp_set_spdif_nonaudio(hdsp, val);
-	spin_unlock_irq(&hdsp->lock);
-	return change;
-}
-
 #define HDSP_SPDIF_SAMPLE_RATE(xname, xindex) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
   .name = xname, \
@@ -2548,114 +2369,6 @@ static int snd_hdsp_put_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl
 	return change;
 }
 
-#define HDSP_XLR_BREAKOUT_CABLE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdsp_info_xlr_breakout_cable, \
-  .get = snd_hdsp_get_xlr_breakout_cable, \
-  .put = snd_hdsp_put_xlr_breakout_cable \
-}
-
-static int hdsp_xlr_breakout_cable(struct hdsp *hdsp)
-{
-	if (hdsp->control_register & HDSP_XLRBreakoutCable)
-		return 1;
-	return 0;
-}
-
-static int hdsp_set_xlr_breakout_cable(struct hdsp *hdsp, int mode)
-{
-	if (mode)
-		hdsp->control_register |= HDSP_XLRBreakoutCable;
-	else
-		hdsp->control_register &= ~HDSP_XLRBreakoutCable;
-	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
-	return 0;
-}
-
-#define snd_hdsp_info_xlr_breakout_cable	snd_ctl_boolean_mono_info
-
-static int snd_hdsp_get_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
-	ucontrol->value.enumerated.item[0] = hdsp_xlr_breakout_cable(hdsp);
-	return 0;
-}
-
-static int snd_hdsp_put_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-	int change;
-	int val;
-
-	if (!snd_hdsp_use_is_exclusive(hdsp))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdsp->lock);
-	change = (int)val != hdsp_xlr_breakout_cable(hdsp);
-	hdsp_set_xlr_breakout_cable(hdsp, val);
-	spin_unlock_irq(&hdsp->lock);
-	return change;
-}
-
-/* (De)activates old RME Analog Extension Board
-   These are connected to the internal ADAT connector
-   Switching this on desactivates external ADAT
-*/
-#define HDSP_AEB(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdsp_info_aeb, \
-  .get = snd_hdsp_get_aeb, \
-  .put = snd_hdsp_put_aeb \
-}
-
-static int hdsp_aeb(struct hdsp *hdsp)
-{
-	if (hdsp->control_register & HDSP_AnalogExtensionBoard)
-		return 1;
-	return 0;
-}
-
-static int hdsp_set_aeb(struct hdsp *hdsp, int mode)
-{
-	if (mode)
-		hdsp->control_register |= HDSP_AnalogExtensionBoard;
-	else
-		hdsp->control_register &= ~HDSP_AnalogExtensionBoard;
-	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
-	return 0;
-}
-
-#define snd_hdsp_info_aeb		snd_ctl_boolean_mono_info
-
-static int snd_hdsp_get_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
-	ucontrol->value.enumerated.item[0] = hdsp_aeb(hdsp);
-	return 0;
-}
-
-static int snd_hdsp_put_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-	int change;
-	int val;
-
-	if (!snd_hdsp_use_is_exclusive(hdsp))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdsp->lock);
-	change = (int)val != hdsp_aeb(hdsp);
-	hdsp_set_aeb(hdsp, val);
-	spin_unlock_irq(&hdsp->lock);
-	return change;
-}
-
 #define HDSP_PREF_SYNC_REF(xname, xindex) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
   .name = xname, \
@@ -2844,58 +2557,6 @@ static int snd_hdsp_get_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_c
 	return 0;
 }
 
-#define HDSP_LINE_OUT(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdsp_info_line_out, \
-  .get = snd_hdsp_get_line_out, \
-  .put = snd_hdsp_put_line_out \
-}
-
-static int hdsp_line_out(struct hdsp *hdsp)
-{
-	return (hdsp->control_register & HDSP_LineOut) ? 1 : 0;
-}
-
-static int hdsp_set_line_output(struct hdsp *hdsp, int out)
-{
-	if (out)
-		hdsp->control_register |= HDSP_LineOut;
-	else
-		hdsp->control_register &= ~HDSP_LineOut;
-	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
-	return 0;
-}
-
-#define snd_hdsp_info_line_out		snd_ctl_boolean_mono_info
-
-static int snd_hdsp_get_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
-	spin_lock_irq(&hdsp->lock);
-	ucontrol->value.integer.value[0] = hdsp_line_out(hdsp);
-	spin_unlock_irq(&hdsp->lock);
-	return 0;
-}
-
-static int snd_hdsp_put_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-	int change;
-	unsigned int val;
-
-	if (!snd_hdsp_use_is_exclusive(hdsp))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdsp->lock);
-	change = (int)val != hdsp_line_out(hdsp);
-	hdsp_set_line_output(hdsp, val);
-	spin_unlock_irq(&hdsp->lock);
-	return change;
-}
-
 #define HDSP_PRECISE_POINTER(xname, xindex) \
 { .iface = SNDRV_CTL_ELEM_IFACE_CARD, \
   .name = xname, \
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/4] ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes
  2013-01-15 14:18 ` [PATCH 1/4] ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes Adrian Knoth
  2013-01-15 14:18   ` [PATCH 2/4] ALSA: hdsp - Implement generic function to toggle settings Adrian Knoth
@ 2013-01-15 15:11   ` Takashi Iwai
  1 sibling, 0 replies; 9+ messages in thread
From: Takashi Iwai @ 2013-01-15 15:11 UTC (permalink / raw)
  To: Adrian Knoth; +Cc: alsa-devel

At Tue, 15 Jan 2013 15:18:10 +0100,
Adrian Knoth wrote:
> 
> The current iobox detection code reportedly fails for various users, so
> simply do what the Win32 driver does instead.
> 
> Patch originally by Karl Grill <kgrill@chello.at> and then modified to
> comply with kernel coding guidelines + current HEAD.
> 
> Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>
> 
> diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
> index 4fae81f..ba190d5 100644
> --- a/sound/pci/rme9652/hdsp.c
> +++ b/sound/pci/rme9652/hdsp.c
> @@ -154,10 +154,12 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
>  #define HDSP_BIGENDIAN_MODE     0x200
>  #define HDSP_RD_MULTIPLE        0x400
>  #define HDSP_9652_ENABLE_MIXER  0x800
> +#define HDSP_S200		0x800
> +#define HDSP_CYCLIC_MODE	0x1000
>  #define HDSP_TDO                0x10000000
>  
> -#define HDSP_S_PROGRAM     	(HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
> -#define HDSP_S_LOAD		(HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
> +#define HDSP_S_PROGRAM	    (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
> +#define HDSP_S_LOAD	    (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
>  
>  /* Control Register bits */
>  
> @@ -671,13 +673,23 @@ static unsigned int hdsp_read(struct hdsp *hdsp, int reg)
>  
>  static int hdsp_check_for_iobox (struct hdsp *hdsp)
>  {
> +	int i;
> +
>  	if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
> -	if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
> -		snd_printk("Hammerfall-DSP: no IO box connected!\n");
> -		hdsp->state &= ~HDSP_FirmwareLoaded;
> -		return -EIO;
> +	for (i = 0; i < 500; i++) {
> +		if (0 == (hdsp_read(hdsp, HDSP_statusRegister) &
> +					HDSP_ConfigError)) {
> +			if (i) {
> +				snd_printk("Hammerfall-DSP: IO box found after %d ms\n",
> +						(20 * i));

One more favor: please make it only as a debug print.
It's not good to print this positive result always.
That is, simply replace it with snd_printd().

> +			}
> +			return 0;
> +		}
> +		msleep(20);
>  	}
> -	return 0;
> +	snd_printk("Hammerfall-DSP: no IO box connected!\n");

Also, recommended to put KERN_ERR prefix here.

> +	hdsp->state &= ~HDSP_FirmwareLoaded;
> +	return -EIO;
>  }
>  
>  static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
> @@ -728,6 +740,7 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
>  
>  		if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
>  			snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n");
> +			hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
>  			return -EIO;
>  		}
>  
> @@ -737,17 +750,15 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
>  			hdsp_write(hdsp, HDSP_fifoData, cache[i]);
>  			if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
>  				snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
> +				hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
>  				return -EIO;
>  			}
>  		}
>  
> -		ssleep(3);
> -
> -		if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
> -			snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
> -		    	return -EIO;
> -		}
> +		hdsp_fifo_wait(hdsp, 3, HDSP_LONG_WAIT);
> +		hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
>  
> +		ssleep(3);
>  #ifdef SNDRV_BIG_ENDIAN
>  		hdsp->control2_register = HDSP_BIGENDIAN_MODE;
>  #else
> @@ -773,24 +784,51 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
>  {
>  	if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
>  
> -		hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
> -		hdsp_write (hdsp, HDSP_fifoData, 0);
> -		if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
> -			return -EIO;
> +		hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
> +		hdsp_write(hdsp, HDSP_fifoData, 0);
>  
> -		hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
> +		if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) {
> +			hdsp_write(hdsp, HDSP_control2Reg, 0x100 | HDSP_S200);

0x100 isn't replaced with a literal?
Maybe worth to define (0x100 | HDSP_S200) to something meaningful, as
this appears repeatedly?


thanks,

Takashi

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/4] ALSA: hdsp - Implement generic function to toggle settings
  2013-01-15  6:48   ` Takashi Iwai
@ 2013-01-15  8:59     ` Takashi Iwai
  0 siblings, 0 replies; 9+ messages in thread
From: Takashi Iwai @ 2013-01-15  8:59 UTC (permalink / raw)
  To: Adrian Knoth; +Cc: alsa-devel

At Tue, 15 Jan 2013 07:48:52 +0100,
Takashi Iwai wrote:
> 
> At Mon, 14 Jan 2013 21:37:18 +0100,
> Adrian Knoth wrote:
> > 
> > The driver contains multiple similar functions that change only a single
> > bit in the control register, only the bit position varies.
> > 
> > This patch implements a generic function to toggle a certain bit
> > position that will be used to replace the old code.
> > 
> > Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>
> > 
> > diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
> > index bcad9ba..f51726a 100644
> > --- a/sound/pci/rme9652/hdsp.c
> > +++ b/sound/pci/rme9652/hdsp.c
> > @@ -1711,6 +1711,64 @@ static int snd_hdsp_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_e
> >  	return change;
> >  }
> >  
> > +#define HDSP_TOGGLE_SETTING(xname, xindex) \
> > +{   .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
> > +	.name = xname, \
> > +	.private_value = xindex, \
> > +	.info = snd_hdsp_info_toggle_setting, \
> > +	.get = snd_hdsp_get_toggle_setting, \
> > +	.put = snd_hdsp_put_toggle_setting \
> > +}
> > +
> > +static int hdsp_toggle_setting(struct hdsp *hdsp, u32 regmask)
> > +{
> > +	return (hdsp->control_register & regmask) ? 1 : 0;
> > +}
> > +
> > +static int hdsp_set_toggle_setting(struct hdsp *hdsp, u32 regmask, int out)
> > +{
> > +	if (out)
> > +		hdsp->control_register |= regmask;
> > +	else
> > +		hdsp->control_register &= ~regmask;
> > +	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
> > +
> > +	return 0;
> > +}
> > +
> > +#define snd_hdsp_info_toggle_setting		   snd_ctl_boolean_mono_info
> > +
> > +static int snd_hdsp_get_toggle_setting(struct snd_kcontrol *kcontrol,
> > +		struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
> > +	u32 regmask = kcontrol->private_value;
> > +
> > +	spin_lock_irq(&hdsp->lock);
> > +	ucontrol->value.integer.value[0] = hdsp_toggle_setting(hdsp, regmask);
> > +	spin_unlock_irq(&hdsp->lock);
> > +	return 0;
> > +}
> > +
> > +static int snd_hdsp_put_toggle_setting(struct snd_kcontrol *kcontrol,
> > +		struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
> > +	u32 regmask = kcontrol->private_value;
> > +	int change;
> > +	unsigned int val;
> > +
> > +	if (!snd_hdsp_use_is_exclusive(hdsp))
> > +		return -EBUSY;
> > +	val = ucontrol->value.integer.value[0] & 1;
> > +	spin_lock_irq(&hdsp->lock);
> > +	change = (int) val != hdsp_toggle_setting(hdsp, regmask);
> > +	hdsp_set_toggle_setting(hdsp, regmask, val);
> 
> If it doesn't change, you don't have to call
> hdsp_set_toggle_setting().

I know the old code does it so, but we don't have to follow it in the
new code, too.


Takashi

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/4] ALSA: hdsp - Implement generic function to toggle settings
  2013-01-14 20:37 ` [PATCH 2/4] ALSA: hdsp - Implement generic function to toggle settings Adrian Knoth
@ 2013-01-15  6:48   ` Takashi Iwai
  2013-01-15  8:59     ` Takashi Iwai
  0 siblings, 1 reply; 9+ messages in thread
From: Takashi Iwai @ 2013-01-15  6:48 UTC (permalink / raw)
  To: Adrian Knoth; +Cc: alsa-devel

At Mon, 14 Jan 2013 21:37:18 +0100,
Adrian Knoth wrote:
> 
> The driver contains multiple similar functions that change only a single
> bit in the control register, only the bit position varies.
> 
> This patch implements a generic function to toggle a certain bit
> position that will be used to replace the old code.
> 
> Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>
> 
> diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
> index bcad9ba..f51726a 100644
> --- a/sound/pci/rme9652/hdsp.c
> +++ b/sound/pci/rme9652/hdsp.c
> @@ -1711,6 +1711,64 @@ static int snd_hdsp_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_e
>  	return change;
>  }
>  
> +#define HDSP_TOGGLE_SETTING(xname, xindex) \
> +{   .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
> +	.name = xname, \
> +	.private_value = xindex, \
> +	.info = snd_hdsp_info_toggle_setting, \
> +	.get = snd_hdsp_get_toggle_setting, \
> +	.put = snd_hdsp_put_toggle_setting \
> +}
> +
> +static int hdsp_toggle_setting(struct hdsp *hdsp, u32 regmask)
> +{
> +	return (hdsp->control_register & regmask) ? 1 : 0;
> +}
> +
> +static int hdsp_set_toggle_setting(struct hdsp *hdsp, u32 regmask, int out)
> +{
> +	if (out)
> +		hdsp->control_register |= regmask;
> +	else
> +		hdsp->control_register &= ~regmask;
> +	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
> +
> +	return 0;
> +}
> +
> +#define snd_hdsp_info_toggle_setting		   snd_ctl_boolean_mono_info
> +
> +static int snd_hdsp_get_toggle_setting(struct snd_kcontrol *kcontrol,
> +		struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
> +	u32 regmask = kcontrol->private_value;
> +
> +	spin_lock_irq(&hdsp->lock);
> +	ucontrol->value.integer.value[0] = hdsp_toggle_setting(hdsp, regmask);
> +	spin_unlock_irq(&hdsp->lock);
> +	return 0;
> +}
> +
> +static int snd_hdsp_put_toggle_setting(struct snd_kcontrol *kcontrol,
> +		struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
> +	u32 regmask = kcontrol->private_value;
> +	int change;
> +	unsigned int val;
> +
> +	if (!snd_hdsp_use_is_exclusive(hdsp))
> +		return -EBUSY;
> +	val = ucontrol->value.integer.value[0] & 1;
> +	spin_lock_irq(&hdsp->lock);
> +	change = (int) val != hdsp_toggle_setting(hdsp, regmask);
> +	hdsp_set_toggle_setting(hdsp, regmask, val);

If it doesn't change, you don't have to call
hdsp_set_toggle_setting().


Takashi

> +	spin_unlock_irq(&hdsp->lock);
> +	return change;
> +}
> +
> +
>  #define HDSP_SPDIF_OUT(xname, xindex) \
>  { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
>    .info = snd_hdsp_info_spdif_bits, \
> -- 
> 1.7.10.4
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/4] ALSA: hdsp - Implement generic function to toggle settings
  2013-01-14 20:37 Adrian Knoth
@ 2013-01-14 20:37 ` Adrian Knoth
  2013-01-15  6:48   ` Takashi Iwai
  0 siblings, 1 reply; 9+ messages in thread
From: Adrian Knoth @ 2013-01-14 20:37 UTC (permalink / raw)
  To: patch; +Cc: Adrian Knoth, alsa-devel

The driver contains multiple similar functions that change only a single
bit in the control register, only the bit position varies.

This patch implements a generic function to toggle a certain bit
position that will be used to replace the old code.

Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>

diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index bcad9ba..f51726a 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -1711,6 +1711,64 @@ static int snd_hdsp_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_e
 	return change;
 }
 
+#define HDSP_TOGGLE_SETTING(xname, xindex) \
+{   .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.private_value = xindex, \
+	.info = snd_hdsp_info_toggle_setting, \
+	.get = snd_hdsp_get_toggle_setting, \
+	.put = snd_hdsp_put_toggle_setting \
+}
+
+static int hdsp_toggle_setting(struct hdsp *hdsp, u32 regmask)
+{
+	return (hdsp->control_register & regmask) ? 1 : 0;
+}
+
+static int hdsp_set_toggle_setting(struct hdsp *hdsp, u32 regmask, int out)
+{
+	if (out)
+		hdsp->control_register |= regmask;
+	else
+		hdsp->control_register &= ~regmask;
+	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
+
+	return 0;
+}
+
+#define snd_hdsp_info_toggle_setting		   snd_ctl_boolean_mono_info
+
+static int snd_hdsp_get_toggle_setting(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+	u32 regmask = kcontrol->private_value;
+
+	spin_lock_irq(&hdsp->lock);
+	ucontrol->value.integer.value[0] = hdsp_toggle_setting(hdsp, regmask);
+	spin_unlock_irq(&hdsp->lock);
+	return 0;
+}
+
+static int snd_hdsp_put_toggle_setting(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+	u32 regmask = kcontrol->private_value;
+	int change;
+	unsigned int val;
+
+	if (!snd_hdsp_use_is_exclusive(hdsp))
+		return -EBUSY;
+	val = ucontrol->value.integer.value[0] & 1;
+	spin_lock_irq(&hdsp->lock);
+	change = (int) val != hdsp_toggle_setting(hdsp, regmask);
+	hdsp_set_toggle_setting(hdsp, regmask, val);
+	spin_unlock_irq(&hdsp->lock);
+	return change;
+}
+
+
 #define HDSP_SPDIF_OUT(xname, xindex) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
   .info = snd_hdsp_info_spdif_bits, \
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-01-15 15:11 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-15 14:18 [PATCH v2 0/4] RME HDSP fixes Adrian Knoth
2013-01-15 14:18 ` [PATCH 1/4] ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes Adrian Knoth
2013-01-15 14:18   ` [PATCH 2/4] ALSA: hdsp - Implement generic function to toggle settings Adrian Knoth
2013-01-15 14:18     ` [PATCH 3/4] ALSA: hdsp - Use HDSP_TOGGLE_SETTING to alter settings Adrian Knoth
2013-01-15 14:18       ` [PATCH 4/4] ALSA: hdsp - Remove obsolete settings functions Adrian Knoth
2013-01-15 15:11   ` [PATCH 1/4] ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes Takashi Iwai
  -- strict thread matches above, loose matches on Subject: below --
2013-01-14 20:37 Adrian Knoth
2013-01-14 20:37 ` [PATCH 2/4] ALSA: hdsp - Implement generic function to toggle settings Adrian Knoth
2013-01-15  6:48   ` Takashi Iwai
2013-01-15  8:59     ` 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.