--- hdsp.c.0.9.6	2003-07-18 12:04:59.000000000 +0200
+++ hdsp.c	2003-08-16 16:14:18.000000000 +0200
@@ -121,7 +121,10 @@
 #define HDSP_playbackRmsLevel   4612  /* 26 * 64 bit values */
 #define HDSP_inputRmsLevel      4868  /* 26 * 64 bit values */
 
-#define HDSP_IO_EXTENT     5192
+#define HDSP_9652_peakBase	7164	
+#define HDSP_9652_rmsBase	4096
+
+#define HDSP_IO_EXTENT     7168
 
 /* control2 register bits */
 
@@ -495,6 +498,7 @@
 static int hdsp_update_simple_mixer_controls(hdsp_t *hdsp);
 static int hdsp_autosync_ref(hdsp_t *hdsp);
 static int snd_hdsp_set_defaults(hdsp_t *hdsp);
+static inline void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp);
 
 static inline int hdsp_playback_to_output_key (hdsp_t *hdsp, int in, int out)
 {
@@ -716,8 +720,9 @@
 		   corresponding memory location, we need
 		   to access 0 to 2703 ...
 		*/
-
-		hdsp_write (hdsp, 4096 + (addr*2), 
+		ad = addr/2;
+	
+		hdsp_write (hdsp, 4096 + (ad*4), 
 			    (hdsp->mixer_matrix[(addr&0x7fe)+1] << 16) + 
 			    hdsp->mixer_matrix[addr&0x7fe]);
 		
@@ -3078,8 +3083,21 @@
 		                 HDSP_SPDIFInputCoaxial | 
 		                 hdsp_encode_latency(7) | 
 		                 HDSP_LineOut;
+	
 
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
+
+#ifdef SNDRV_BIG_ENDIAN
+	hdsp->control2_register = HDSP_BIGENDIAN_MODE;
+#else
+	hdsp->control2_register = 0;
+#endif
+	if (hdsp->io_type == H9652) {
+	        snd_hdsp_9652_enable_mixer (hdsp);
+	} else {
+	    hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
+	} 
+
 	hdsp_reset_hw_pointer(hdsp);
 	hdsp_compute_period_size(hdsp);
 
@@ -3800,8 +3818,47 @@
 	switch (cmd) {
 	case SNDRV_HDSP_IOCTL_GET_PEAK_RMS:
 		if (hdsp->io_type == H9652) {
-		    snd_printk("hardware metering isn't supported yet for hdsp9652 cards\n");
-		    return -EINVAL;
+			unsigned long rms_low, rms_high;
+			int i;
+			int doublespeed = 0;
+			if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
+				doublespeed = 1;
+			peak_rms = (hdsp_peak_rms_t *)arg;
+			for (i = 0; i < 26; ++i) {
+				if (!(doublespeed && (i & 4))) {
+					if (copy_to_user_fromio((void *)peak_rms->input_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-i*4, 4) != 0)
+						return -EFAULT;
+					if (copy_to_user_fromio((void *)peak_rms->playback_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
+						return -EFAULT;
+					if (copy_to_user_fromio((void *)peak_rms->output_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-2*(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
+						return -EFAULT;
+					rms_low = *(unsigned long *)(hdsp->iobase+HDSP_9652_rmsBase+i*8) & 0xFFFFFF00;
+					rms_high = *(unsigned long *)(hdsp->iobase+HDSP_9652_rmsBase+i*8+4) & 0xFFFFFF00;
+					rms_high += (rms_low >> 24);
+					rms_low <<= 8;
+					if (copy_to_user((void *)peak_rms->input_rms+i*8, &rms_low, 4) != 0)
+						return -EFAULT;
+					if (copy_to_user((void *)peak_rms->input_rms+i*8+4, &rms_high, 4) != 0)
+						return -EFAULT;					
+					rms_low = *(unsigned long *)(hdsp->iobase+HDSP_9652_rmsBase+(doublespeed ? 14 : 26)*8+i*8) & 0xFFFFFF00;
+					rms_high = *(unsigned long *)(hdsp->iobase+HDSP_9652_rmsBase+(doublespeed ? 14 : 26)*8+i*8+4) & 0xFFFFFF00;
+					rms_high += (rms_low >> 24);
+					rms_low <<= 8;
+					if (copy_to_user((void *)peak_rms->playback_rms+i*8, &rms_low, 4) != 0)
+						return -EFAULT;
+					if (copy_to_user((void *)peak_rms->playback_rms+i*8+4, &rms_high, 4) != 0)
+						return -EFAULT;					
+					rms_low = *(unsigned long *)(hdsp->iobase+HDSP_9652_rmsBase+2*(doublespeed ? 14 : 26)*8+i*8) & 0xFFFFFF00;
+					rms_high = *(unsigned long *)(hdsp->iobase+HDSP_9652_rmsBase+2*(doublespeed ? 14 : 26)*8+i*8+4) & 0xFFFFFF00;
+					rms_high += (rms_low >> 24);
+					rms_low <<= 8;
+					if (copy_to_user((void *)peak_rms->output_rms+i*8, &rms_low, 4) != 0)
+						return -EFAULT;
+					if (copy_to_user((void *)peak_rms->output_rms+i*8+4, &rms_high, 4) != 0)
+						return -EFAULT;					
+				}
+			}
+			return 0;
 		}
 		if (!(hdsp->state & HDSP_FirmwareLoaded)) {
 			snd_printk("firmware needs to be uploaded to the card.\n");	
@@ -4108,6 +4165,8 @@
 	spin_lock_init(&hdsp->midi[1].lock);
 	hdsp->iobase = 0;
 	hdsp->res_port = 0;
+	hdsp->control_register = 0;
+	hdsp->control2_register = 0;
 	hdsp->io_type = Undefined;
 	for (i = 0; i < HDSP_MAX_CHANNELS; ++i)
 		hdsp->playback_mixer_ctls[i] = 0;
@@ -4125,6 +4184,7 @@
 	switch (hdsp->firmware_rev & 0xff) {
 	case 0xa:
 	case 0xb:
+	case 0x32:
 		hdsp->card_name = "RME Hammerfall DSP";
 		break;
 
@@ -4200,6 +4260,7 @@
 
 	if (is_9652) {
 	        hdsp->io_type = H9652;
+		/* FIXME : no more needed here */
 	        snd_hdsp_9652_enable_mixer (hdsp);
 	}
 
