diff -urp ../../sane-backends-1.0.24-orig/backend/rts8891.c ./rts8891.c
--- ../../sane-backends-1.0.24-orig/backend/rts8891.c	2013-08-25 23:22:58.000000000 +0200
+++ ./rts8891.c	2015-05-26 21:53:11.000000000 +0200
@@ -111,7 +111,8 @@
 #define MARGIN_LEVEL            128	/* white level for margin detection */
 
 /* width used for calibration */
-#define CALIBRATION_WIDTH       637
+//#define CALIBRATION_WIDTH       637
+#define CALIBRATION_WIDTH       1500
 
 /* data size for calibration: one RGB line*/
 #define CALIBRATION_SIZE        CALIBRATION_WIDTH*3
@@ -1052,6 +1053,8 @@ static char *sensor_name (int sensor)
       return "SENSOR_TYPE_4400";
     case SENSOR_TYPE_4400_BARE:
       return "SENSOR_TYPE_4400_BARE";
+    case SENSOR_TYPE_UMAX:
+      return "SENSOR_TYPE_UMAX";
     default:
       return "BOGUS";
     }
@@ -1214,6 +1217,11 @@ sane_start (SANE_Handle handle)
 		   "sane_start: sensor changed to type 'SENSOR_TYPE_4400'!\n");
 	      dev->sensor = SENSOR_TYPE_4400;
 	      break;
+	    case SENSOR_TYPE_UMAX:
+	      DBG (DBG_info,
+		   "sane_start: sensor changed to type 'SENSOR_TYPE_XPA'!\n");
+	      dev->sensor = SENSOR_TYPE_XPA;
+	      break;
 	    }
 	}
     }
@@ -1227,6 +1235,7 @@ sane_start (SANE_Handle handle)
       mode = 0x20;
       break;
     case SENSOR_TYPE_BARE:
+    case SENSOR_TYPE_UMAX:
       light = 0x3b;
       mode = 0x20;
       break;
@@ -1772,8 +1781,8 @@ sane_read (SANE_Handle handle, SANE_Byte
       return SANE_STATUS_EOF;
     }
 
-  dev->regs[LAMP_REG] = 0xad;
-  sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &(dev->regs[LAMP_REG]));
+//  dev->regs[LAMP_REG] = 0xad;
+//  sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &(dev->regs[LAMP_REG]));
 
   /* byte length for high dpi mode */
   length = (session->params.bytes_per_line * 8) / session->params.depth;
@@ -2949,6 +2958,7 @@ set_lamp_brightness (struct Rts8891_Devi
       dev->regs[0x10] = 0x10;
       dev->regs[0x11] = 0x2f;
     }
+  /////////UMAX???? 0x20 0x3b???
   reg = dev->regs[LAMP_REG];
   sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
   status = sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &reg);
@@ -2982,7 +2992,12 @@ init_lamp (struct Rts8891_Device *dev)
   sanei_rts88xx_write_regs (dev->devnum, 0x14, dev->regs + 0x14, 2);
   sanei_rts88xx_write_control (dev->devnum, 0x00);
   sanei_rts88xx_write_control (dev->devnum, 0x00);
-  if (dev->sensor != SENSOR_TYPE_4400 && dev->sensor != SENSOR_TYPE_4400_BARE)
+  if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x20, 0x3b);
+      dev->regs[0x11] = 0x3b;
+    }
+  else if (dev->sensor != SENSOR_TYPE_4400 && dev->sensor != SENSOR_TYPE_4400_BARE)
     {
       sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x28, 0x3f);
       dev->regs[0x11] = 0x3f;
@@ -3015,9 +3030,13 @@ find_origin (struct Rts8891_Device *dev,
   SANE_Word total;
   int startx = 300;
   int width = 1200;
+//  int startx=75;
+//  int width=3000;
   int x, y, sum, current;
-  int starty = 18;
+  int starty = (dev->sensor == SENSOR_TYPE_UMAX) ? 42 : 18;
   int height = 180;
+//  int starty=0;
+//  int height=1500;
   int timing;
 
   DBG (DBG_proc, "find_origin: start\n");
@@ -3146,6 +3165,38 @@ find_origin (struct Rts8891_Device *dev,
       dev->regs[0xd7] = 0x30;	/* 0x10 */
       dev->regs[0xda] = 0xa7;	/* 0xa0 */
     }
+  if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      dev->regs[0x14] = 0xf0;
+      dev->regs[0x16] = 0x0f;
+      dev->regs[0x23] = 0x00;
+      dev->regs[0x35] = 0x0e;
+      dev->regs[0x36] = 0x2c;
+      dev->regs[0x3a] = 0x0e;
+      dev->regs[0xc0] = 0x87;
+      dev->regs[0xc1] = 0x07;
+      dev->regs[0xc2] = 0xf8;
+      dev->regs[0xc3] = 0x78;
+      dev->regs[0xc4] = 0xf8;
+      dev->regs[0xc5] = 0x07;
+      dev->regs[0xc6] = 0x87;
+      dev->regs[0xc7] = 0x07;
+      dev->regs[0xc8] = 0xf8;
+      dev->regs[0xc9] = 0xfc;
+      dev->regs[0xca] = 0x0f;
+      dev->regs[0xcd] = 0x00;
+      dev->regs[0xce] = 0x80;
+      dev->regs[0xcf] = 0xe2;
+      dev->regs[0xd0] = 0xe4;
+      dev->regs[0xd7] = 0x10;
+      dev->regs[0xd8] = 0xa6;
+      dev->regs[0xd9] = 0x2d;////
+      dev->regs[0xda] = 0x00;////
+      dev->regs[0xe2] = 0x03;
+      SET_DOUBLE (dev->regs, EXPOSURE_REG, 2061);
+      /* dev->regs[0xe5] = 0x0d;
+         dev->regs[0xe6] = 0x08;     080d=2061 */
+    }
   SET_DOUBLE (dev->regs, TIMING_REG, timing);
   SET_DOUBLE (dev->regs, TIMING1_REG, timing+1);
   SET_DOUBLE (dev->regs, TIMING2_REG, timing+2);
@@ -3174,8 +3225,11 @@ find_origin (struct Rts8891_Device *dev,
   sanei_rts88xx_set_gain (dev->regs, 0x10, 0x10, 0x10);
 
   /* gray level scan */
-  dev->regs[LAMP_REG] = 0xad;
-  sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, dev->regs + LAMP_REG);
+  if (dev->sensor != SENSOR_TYPE_UMAX)
+    {
+      dev->regs[LAMP_REG] = 0xad;
+      sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, dev->regs + LAMP_REG);
+    }
   if (dev->sensor != SENSOR_TYPE_4400
       && (dev->sensor != SENSOR_TYPE_4400_BARE))
     {
@@ -3293,6 +3347,19 @@ find_origin (struct Rts8891_Device *dev,
 	     dev->regs[0xe6] = 0x08;     0x10 080d=2061=1030*2+1 */
 	  SET_DOUBLE (dev->regs, EXPOSURE_REG, 2061);
 	}
+      else if (dev->sensor == SENSOR_TYPE_UMAX)
+        {
+	  dev->regs[0x36] = 0x24;	/* direction reverse (& ~0x08) */
+	  dev->regs[0xb2] = 0x02;
+	  dev->regs[0xd9] = 0x2d;////
+	  dev->regs[0xda] = 0x00;////
+	  dev->regs[0xe2] = 0x07;
+
+	  /*
+	     dev->regs[0xe5] = 0x06;
+	     dev->regs[0xe6] = 0x04;     406=1030 */
+	  SET_DOUBLE (dev->regs, EXPOSURE_REG, 1030);
+        }
       else
 	{
 	  dev->regs[0x11] = 0x3f;	/* 0x3b */
@@ -3343,6 +3410,7 @@ find_margin (struct Rts8891_Device *dev)
   int height = 1;
   SANE_Byte reg = 0xa2;
   int timing=0;
+  unsigned char margin_level = MARGIN_LEVEL;
 
   DBG (DBG_proc, "find_margin: start\n");
 
@@ -3354,12 +3422,24 @@ find_margin (struct Rts8891_Device *dev)
     {
       sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x10, 0x23);
     }
+  else if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x20, 0x3b);
+    }
   else
     {
       sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x28, 0x3b);
     }
 
-  sanei_rts88xx_set_gain (dev->regs, 0x3f, 0x3f, 0x3f);
+  if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      sanei_rts88xx_set_gain (dev->regs, 0x00, 0x00, 0x00);
+      startx = 66;
+    }
+  else
+    {
+      sanei_rts88xx_set_gain (dev->regs, 0x3f, 0x3f, 0x3f);
+    }
 
   /* set scan parameters */
   dev->regs[0x33] = 0x01;
@@ -3449,6 +3529,49 @@ find_margin (struct Rts8891_Device *dev)
       dev->regs[0x8d] = 0x3b;	/* 0x00 */
       timing=0x00b0;
     }
+  if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      dev->regs[0x35] = 0x0e;
+      dev->regs[0x3a] = 0x0e;
+      dev->regs[0x40] = 0x20;
+      dev->regs[0x72] = 0xe1;
+      dev->regs[0x73] = 0x14;
+      dev->regs[0x74] = 0x18;
+      dev->regs[0x7a] = 0x01;
+      dev->regs[0x8d] = 0x07;
+      timing=0x32;
+      dev->regs[0xc1] = 0x07;
+      dev->regs[0xc2] = 0x80;
+      dev->regs[0xc4] = 0xf8;
+      dev->regs[0xc5] = 0x7f;
+      dev->regs[0xc6] = 0xff;
+      dev->regs[0xc7] = 0x07;
+      dev->regs[0xc8] = 0x80;
+      dev->regs[0xc9] = 0x00;
+      dev->regs[0xca] = 0x0f;
+      dev->regs[0xcb] = 0x00;
+      dev->regs[0xcc] = 0xfe;
+      dev->regs[0xcd] = 0x00;
+      dev->regs[0xce] = 0x00;
+      dev->regs[0xcf] = 0xf7;
+      dev->regs[0xd0] = 0xe1;
+      dev->regs[0xd1] = 0xea;
+      dev->regs[0xd2] = 0x0b;
+      dev->regs[0xd3] = 0x03;
+      dev->regs[0xd4] = 0x05;
+      dev->regs[0xd6] = 0xab;
+      dev->regs[0xd7] = 0x10;
+      dev->regs[0xd8] = 0xa6;
+      dev->regs[0xda] = 0x00;
+      dev->regs[0xe2] = 0x03;
+      dev->regs[0xee] = 0x00;
+      dev->regs[0xf1] = 0x00;
+
+      /* dev->regs[0xe5] = 0xbd;
+         dev->regs[0xe6] = 0x0a;     0abd=2749 */
+      SET_DOUBLE (dev->regs, EXPOSURE_REG, 2749);
+      margin_level = 32;
+    }
   SET_DOUBLE (dev->regs, TIMING_REG, timing);
   SET_DOUBLE (dev->regs, TIMING1_REG, timing+1);
   SET_DOUBLE (dev->regs, TIMING2_REG, timing+2);
@@ -3484,9 +3607,9 @@ find_margin (struct Rts8891_Device *dev)
 
   /* we search from left to right the first white pixel */
   x = 0;
-  while (x < width && data[x] < MARGIN_LEVEL)
+  while (x < width && data[x] < margin_level)
     x++;
-  if (x == width)
+  if (x == width || x == 0)///////////////////////////
     {
       DBG (DBG_warn, "find_margin: failed to find left margin!\n");
       DBG (DBG_warn, "find_margin: using default...\n");
@@ -4016,6 +4139,38 @@ int i;
 	  dev->regs[0x90] = 0x80;	/* 0x00 */
 	}
       break;
+    case SENSOR_TYPE_UMAX:
+      for (i = 0; i < dev->reg_count; i++)
+	dev->regs[i] = 0x00;
+      dev->regs[0x00] = 0xe5;
+      dev->regs[0x01] = 0x41;
+      dev->regs[0x0b] = 0x70;
+      dev->regs[0x10] = 0xd0;
+      dev->regs[0x11] = 0x1b;
+      dev->regs[0x13] = 0x20;
+      dev->regs[0x15] = 0x20;
+      dev->regs[0x1d] = 0x20;
+      dev->regs[0x20] = 0x3a;
+      dev->regs[0x21] = 0xf2;
+      dev->regs[0x34] = 0x10;
+      dev->regs[0x36] = 0x07;
+      dev->regs[0x40] = 0x20;
+      dev->regs[0x44] = 0x8c;
+      dev->regs[0x45] = 0x76;
+      dev->regs[0x8d] = 0x80;
+      dev->regs[0x8e] = 0x68;
+      dev->regs[0x93] = 0x02;
+      dev->regs[0x94] = 0x0e;
+      dev->regs[0xa3] = 0xcc;
+      dev->regs[0xa4] = 0x27;
+      dev->regs[0xa5] = 0x64;
+      dev->regs[0xb2] = 0x02;
+      dev->regs[0xd5] = 0x86;
+      dev->regs[0xd6] = 0x1b;
+      dev->regs[0xd8] = 0xff;
+      dev->regs[0xe2] = 0x01;
+      dev->regs[0xe5] = 0x14;
+      break;
     }
   return SANE_STATUS_GOOD;
 }
@@ -4633,7 +4788,14 @@ dark_calibration (struct Rts8891_Device
 
   /* set up starting values */
   sanei_rts88xx_set_gain (dev->regs, 0, 0, 0);
-  sanei_rts88xx_set_scan_area (dev->regs, 1, 2, 4, 4 + CALIBRATION_WIDTH);
+  if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      sanei_rts88xx_set_scan_area (dev->regs, 1, 2, 2, 2 + CALIBRATION_WIDTH);
+    }
+  else
+    {
+      sanei_rts88xx_set_scan_area (dev->regs, 1, 2, 4, 4 + CALIBRATION_WIDTH);
+    }
 
   sanei_rts88xx_set_status (dev->devnum, dev->regs, mode, light);
 
@@ -4668,7 +4830,7 @@ dark_calibration (struct Rts8891_Device
   dev->regs[0xd8] = 0x52;
   dev->regs[0xe2] = 0x1f;
 
-  /*dev->regs[0xe5] = 0x28;      28=40 
+  /*dev->regs[0xe5] = 0x28;      28=40
      dev->regs[0xe6] = 0x00; */
   SET_DOUBLE (dev->regs, EXPOSURE_REG, 40);
 
@@ -4748,6 +4910,51 @@ dark_calibration (struct Rts8891_Device
       dev->regs[0xef] = 0x02;	/* 0x03 */
       dev->regs[0xf0] = 0xa8;	/* 0x70 */
     }
+  if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      dev->regs[0x33] = 0x01;
+      dev->regs[0x35] = 0x47;
+      dev->regs[0x40] = 0xa0;
+//      dev->regs[0x7a] = 0x02;// this breaks scanning
+      dev->regs[0x8d] = 0x46;
+      dev->regs[0xc0] = 0x66;
+      dev->regs[0xc1] = 0xc0;
+      dev->regs[0xc2] = 0x7f;
+      dev->regs[0xc3] = 0x99;
+      dev->regs[0xc4] = 0x3f;
+      dev->regs[0xc5] = 0x80;
+      dev->regs[0xc6] = 0x66;
+      dev->regs[0xc7] = 0xc0;
+      dev->regs[0xc8] = 0x7f;
+      dev->regs[0xc9] = 0xff;
+      dev->regs[0xcb] = 0x00;
+      dev->regs[0xcc] = 0x00;
+      dev->regs[0xcd] = 0x80;
+      dev->regs[0xce] = 0xff;
+      dev->regs[0xcf] = 0xe3;
+      dev->regs[0xd0] = 0xe8;
+      dev->regs[0xd1] = 0xee;
+      dev->regs[0xd2] = 0x0f;
+      dev->regs[0xd3] = 0x0b;
+      dev->regs[0xd4] = 0x0d;
+      dev->regs[0xd8] = 0xa6;
+      dev->regs[0xe2] = 0x07;
+
+      /*dev->regs[0xe5] = 0x1b;      28=40
+         dev->regs[0xe6] = 0x01; */
+      SET_DOUBLE (dev->regs, EXPOSURE_REG, 283);
+
+      dev->regs[0xe7] = 0x4b;
+      dev->regs[0xe9] = 0x40;
+      dev->regs[0xea] = 0x7d;
+      dev->regs[0xeb] = 0x04;
+      dev->regs[0xec] = 0x18;
+      dev->regs[0xed] = 0x85;
+      dev->regs[0xee] = 0x02;
+      dev->regs[0xef] = 0x0a;
+      dev->regs[0xf0] = 0x81;
+      dev->regs[0xf1] = 0x01;
+    }
 
   /* we loop scanning a 637 (1911 bytes) pixels wide area in color mode 
    * until each black average reaches the desired value */
@@ -4883,8 +5090,10 @@ gain_calibration (struct Rts8891_Device
   int timing=0;
 
   int xstart = (dev->left_offset * 75) / dev->model->max_xdpi;
+  if (xstart == 0)
+  	xstart = 4;
 
-  DBG (DBG_proc, "gain_calibration: start\n");
+  DBG (DBG_proc, "gain_calibration: start, xstart=%d, xstart+width=%d\n", xstart, xstart + width);
 
   /* set up starting values */
   sanei_rts88xx_set_scan_area (dev->regs, 1, 2, xstart, xstart + width);
@@ -4937,7 +5146,7 @@ gain_calibration (struct Rts8891_Device
   dev->regs[0xf0] = 0x70;
   dev->regs[0xf2] = 0x01;
 
-  dev->regs[0x72] = 0xe1;
+  dev->regs[0x72] = 0xe1;//
   dev->regs[0x73] = 0x14;
   dev->regs[0x74] = 0x18;
 
@@ -5028,6 +5237,54 @@ gain_calibration (struct Rts8891_Device
       dev->regs[0x87] = 0x00;
       dev->regs[0x88] = 0x06;
     }
+  if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      dev->regs[0x33] = 0x01;
+      dev->regs[0x35] = 0x47;
+      dev->regs[0x40] = 0xa0;
+//      dev->regs[0x7a] = 0x02;// this breaks scanning
+      timing = 0x32;
+      dev->regs[0x8d] = 0x4f;
+      dev->regs[0xc0] = 0x66;
+      dev->regs[0xc1] = 0xc0;
+      dev->regs[0xc2] = 0x7f;
+      dev->regs[0xc3] = 0x99;
+      dev->regs[0xc4] = 0x3f;
+      dev->regs[0xc5] = 0x80;
+      dev->regs[0xc6] = 0x66;
+      dev->regs[0xc7] = 0xc0;
+      dev->regs[0xc8] = 0x7f;
+      dev->regs[0xc9] = 0xff;
+      dev->regs[0xcb] = 0x00;
+      dev->regs[0xcc] = 0x00;
+      dev->regs[0xcd] = 0x80;
+      dev->regs[0xce] = 0xff;
+      dev->regs[0xcf] = 0xe3;
+      dev->regs[0xd0] = 0xe8;
+      dev->regs[0xd1] = 0xee;
+      dev->regs[0xd2] = 0x0f;
+      dev->regs[0xd3] = 0x0b;
+      dev->regs[0xd4] = 0x0d;
+      dev->regs[0xd7] = 0x10;
+      dev->regs[0xd8] = 0xa6;
+      dev->regs[0xda] = 0x00;
+      dev->regs[0xe2] = 0x07;
+
+      /*dev->regs[0xe5] = 0x1b;      28=40
+         dev->regs[0xe6] = 0x01; */
+      SET_DOUBLE (dev->regs, EXPOSURE_REG, 283);
+
+      dev->regs[0xe7] = 0x4b;
+      dev->regs[0xe9] = 0x40;
+      dev->regs[0xea] = 0x7d;
+      dev->regs[0xeb] = 0x04;
+      dev->regs[0xec] = 0x18;
+      dev->regs[0xed] = 0x85;
+      dev->regs[0xee] = 0x02;
+      dev->regs[0xef] = 0x0a;
+      dev->regs[0xf0] = 0x81;
+      dev->regs[0xf1] = 0x01;
+    }
   SET_DOUBLE (dev->regs, TIMING_REG, timing);
   SET_DOUBLE (dev->regs, TIMING1_REG, timing+1);
   SET_DOUBLE (dev->regs, TIMING2_REG, timing+2);
@@ -5044,9 +5301,18 @@ gain_calibration (struct Rts8891_Device
   bgg = 0;
   bbg = 0;
   /* top values */
-  trg = 0x1f;
-  tgg = 0x1f;
-  tbg = 0x1f;
+  if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      trg = 0x3f;
+      tgg = 0x3f;
+      tbg = 0x3f;
+    }
+  else
+    {
+      trg = 0x1f;
+      tgg = 0x1f;
+      tbg = 0x1f;
+    }
 
   /* loop on gain calibration until we find until we find stable value
    * or we do more than 20 tries */
@@ -5346,6 +5612,52 @@ offset_calibration (struct Rts8891_Devic
       dev->regs[0xef] = 0x02;	/* 0x03 */
       dev->regs[0xf0] = 0xa8;	/* 0x70 */
     }
+  if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      dev->regs[0x33] = 0x01;
+      dev->regs[0x35] = 0x47;
+      dev->regs[0x40] = 0xa0;
+//      dev->regs[0x7a] = 0x02;// this breaks scanning
+//      timing = 0x32;
+      dev->regs[0x8d] = 0x46;
+      dev->regs[0xc0] = 0x66;
+      dev->regs[0xc1] = 0xc0;
+      dev->regs[0xc2] = 0x7f;
+      dev->regs[0xc3] = 0x99;
+      dev->regs[0xc4] = 0x3f;
+      dev->regs[0xc5] = 0x80;
+      dev->regs[0xc6] = 0x66;
+      dev->regs[0xc7] = 0xc0;
+      dev->regs[0xc8] = 0x7f;
+      dev->regs[0xc9] = 0xff;
+      dev->regs[0xcb] = 0x00;
+      dev->regs[0xcc] = 0x00;
+      dev->regs[0xcd] = 0x80;
+      dev->regs[0xce] = 0xff;
+      dev->regs[0xcf] = 0xe3;
+      dev->regs[0xd0] = 0xe8;
+      dev->regs[0xd1] = 0xee;
+      dev->regs[0xd2] = 0x0f;
+      dev->regs[0xd3] = 0x0b;
+      dev->regs[0xd4] = 0x0d;
+      dev->regs[0xd8] = 0xa6;
+      dev->regs[0xe2] = 0x07;
+
+      /*dev->regs[0xe5] = 0x1b;      28=40
+         dev->regs[0xe6] = 0x01; */
+      SET_DOUBLE (dev->regs, EXPOSURE_REG, 283);
+
+      dev->regs[0xe7] = 0x4b;
+      dev->regs[0xe9] = 0x40;
+      dev->regs[0xea] = 0x7d;
+      dev->regs[0xeb] = 0x04;
+      dev->regs[0xec] = 0x18;
+      dev->regs[0xed] = 0x85;
+      dev->regs[0xee] = 0x02;
+      dev->regs[0xef] = 0x0a;
+      dev->regs[0xf0] = 0x81;
+      dev->regs[0xf1] = 0x01;
+    }
 
   /* we loop scanning a 637 (1911 bytes) pixels wide area in color mode until each black average
    * reaches the desired value */
@@ -5551,6 +5863,18 @@ setup_shading_calibration (struct Rts889
       regs[0xe2] = 0x02;	/* 0x05 */
       exposure=443;
     }
+  if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      regs[0x36] = 0x29;
+      timing = 0x32;
+      regs[0x8d] = 0x4f;
+      regs[0xe2] = 0x00;
+      /* regs[0xe5] = 0xdf;    
+         regs[0xe6] = 0x08;    8df =2271 */
+      exposure=2271;
+      regs[0xee] = 00;
+      regs[0xf1] = 00;
+    }
 
   switch (dev->xdpi)
     {
@@ -5804,6 +6128,36 @@ setup_shading_calibration (struct Rts889
 	       "setup_shading_calibration: setting up SENSOR_TYPE_4400_BARE for 300 dpi\n");
 	  return SANE_STATUS_INVAL;
 	  break;
+	case SENSOR_TYPE_UMAX:
+	  DBG (DBG_io,
+	       "setup_shading_calibration: setting up SENSOR_TYPE_UMAX for 300 dpi\n");
+	  regs[0x36] = 0x2c;
+	  regs[0x40] = 0x20;
+	  regs[0x8d] = 0x12;
+	  regs[0xc0] = 0x87;
+	  regs[0xc1] = 0x07;
+	  regs[0xc2] = 0xf8;
+	  regs[0xc3] = 0x78;
+	  regs[0xc4] = 0xf8;
+	  regs[0xc5] = 0x07;
+	  regs[0xc6] = 0x87;
+	  regs[0xc7] = 0x07;
+	  regs[0xc8] = 0xf8;
+	  regs[0xc9] = 0xfc;
+	  regs[0xca] = 0x0f;
+	  regs[0xcd] = 0x00;
+	  regs[0xce] = 0x80;
+	  regs[0xcf] = 0xe2;
+	  regs[0xd0] = 0xe4;
+	  regs[0xd1] = 0xea;
+	  regs[0xd2] = 0x0b;
+	  regs[0xd3] = 0x17;
+	  regs[0xd4] = 0x01;
+	  regs[0xe2] = 0x07;
+	  /* regs[0xe5] = 0xc9;
+	     regs[0xe6] = 0x01;    0x1c9=457 */
+          exposure=457;
+	  break;
 	}
       break;
 
@@ -5958,6 +6312,46 @@ setup_shading_calibration (struct Rts889
 	       "setup_shading_calibration: setting up SENSOR_TYPE_4400_BARE for 600 dpi\n");
 	  return SANE_STATUS_INVAL;
 	  break;
+	case SENSOR_TYPE_UMAX:
+	  DBG (DBG_io,
+	       "setup_shading_calibration: setting up SENSOR_TYPE_UMAX for 600 dpi\n");
+	  *status1 = 0x20;
+
+	  regs[0x36] = 0x2c;
+	  regs[0x40] = 0x20;
+	  regs[0x8d] = 0x24;
+	  regs[0xc0] = 0xff;
+	  regs[0xc1] = 0x07;
+	  regs[0xc2] = 0x80;
+	  regs[0xc3] = 0x00;
+	  regs[0xc4] = 0xf8;
+	  regs[0xc5] = 0x7f;
+	  regs[0xc6] = 0xff;
+	  regs[0xc7] = 0x07;
+	  regs[0xc8] = 0x80;
+	  regs[0xc9] = 0x00;
+	  regs[0xca] = 0x0f;
+	  regs[0xcc] = 0xfe;
+	  regs[0xcd] = 0x00;
+	  regs[0xce] = 0x00;
+	  regs[0xcf] = 0xd7;
+	  regs[0xd0] = 0x61;
+	  regs[0xd1] = 0xaa;
+	  regs[0xd2] = 0x00;
+	  regs[0xd4] = 0x03;
+	  regs[0xd5] = 0x05;
+	  regs[0xd6] = 0x86;
+	  regs[0xd7] = 0x1b;
+	  regs[0xd8] = 0x10;
+	  regs[0xd9] = 0xa6;
+	  regs[0xda] = 0x2d;
+
+	  regs[0xe3] = 0x07;
+	  /* regs[0xe5] = 0x00;
+	     regs[0xe6] = 0xae;*/
+          exposure=0xae00;
+          regs[0xe7] = 0x02;
+	  break;
 	}
       break;
 
@@ -6108,6 +6502,44 @@ setup_shading_calibration (struct Rts889
 	       "setup_shading_calibration: setting up SENSOR_TYPE_4400_BARE for 1200 dpi\n");
 	  return SANE_STATUS_INVAL;
 	  break;
+
+	case SENSOR_TYPE_UMAX:
+	  DBG (DBG_io,
+	       "setup_shading_calibration: setting up SENSOR_TYPE_UMAX for 1200 dpi\n");
+	  *status1 = 0x20;
+//	  regs[0x10] = 0x20;
+	  regs[0x36] = 0x2c;
+	  regs[0x40] = 0x20;
+	  regs[0x8d] = 0x48;
+
+	  regs[0xc0] = 0x1f;
+	  regs[0xc1] = 0x00;
+	  regs[0xc2] = 0xfe;
+	  regs[0xc3] = 0xe0;
+	  regs[0xc4] = 0xff;
+	  regs[0xc5] = 0x01;
+	  regs[0xc6] = 0x1f;
+	  regs[0xc7] = 0x00;
+	  regs[0xc8] = 0xfe;
+	  regs[0xc9] = 0x00;
+	  regs[0xca] = 0x00;
+	  regs[0xcb] = 0x1c;
+	  regs[0xcc] = 0x00;
+	  regs[0xcd] = 0xc0;
+	  regs[0xce] = 0x01;
+	  regs[0xcf] = 0xeb;
+	  regs[0xd0] = 0xed;
+	  regs[0xd1] = 0xe1;
+	  regs[0xd2] = 0x02;
+	  /* regs[0xd3] = 0x12; */
+	  regs[0xd4] = 0xf4;
+	  regs[0xd5] = 0x86;
+	  regs[0xd6] = 0x1b;
+	  regs[0xe2] = 0x07;
+	  /* regs[0xe5] = 0x5e;
+	     regs[0xe6] = 0x05;         0x55e=1374 */
+          exposure=1374;
+	  break;
 	}
       break;
     }
@@ -6934,6 +7366,68 @@ setup_scan_registers (struct Rts8891_Ses
       regs[0xf0] = 0xa8;	/* 0x00 */
       regs[0xf2] = 0x01;	/* 0x00 */
     }
+  if (dev->sensor == SENSOR_TYPE_UMAX)
+    {
+      regs[0x14] = 0xf0;
+      regs[0x16] = 0x00;
+      regs[0x23] = 0x00;
+      regs[0x32] = 0x80;
+      regs[0x33] = 0x81;
+      regs[0x40] = 0xa4;
+      /*regs[0x7a] = 0x02;*////this breaks scanning, scanner returns only half of the data requested
+      timing=0x0182;
+      regs[0x85] = 0x10;
+      regs[0x86] = 0x14;
+      regs[0x87] = 0x20;
+      regs[0x88] = 0x22;
+      regs[0x8d] = 0x4f;
+      regs[0xc0] = 0x66;
+      regs[0xc1] = 0xc0;
+      regs[0xc2] = 0x7f;
+      regs[0xc3] = 0x99;
+      regs[0xc4] = 0x3f;
+      regs[0xc5] = 0x80;
+      regs[0xc6] = 0x66;
+      regs[0xc7] = 0xc0;
+      regs[0xc8] = 0x7f;
+      regs[0xc9] = 0xff;
+      regs[0xcb] = 0x00;
+      regs[0xcc] = 0x00;
+      regs[0xcd] = 0x80;
+      regs[0xce] = 0xff;
+      regs[0xcf] = 0xe3;
+      regs[0xd0] = 0xe8;
+      regs[0xd1] = 0xee;
+      regs[0xd2] = 0x0f;
+      /*regs[0xd3] = 0x0b;*/
+      regs[0xd4] = 0x0d;
+
+      regs[0xd6] = 0x0f;
+      regs[0xd7] = 0x10;	/* 4111 */
+
+      regs[0xd8] = 0xa6;	/* 0xa610=42512 */
+
+      regs[0xd9] = 0x2d;
+      regs[0xda] = 0x00;
+      regs[0xe2] = 0x07;
+      regs[0xe3] = 0xbd;
+      regs[0xe4] = 0x08;
+
+      /* regs[0xe5] = 0x1b;
+         regs[0xe6] = 0x01;     exposure time 0x011b=283 */
+      exposure=283;
+
+      regs[0xe7] = 0x4b;
+      regs[0xe9] = 0x40;
+      regs[0xea] = 0x7d;
+      regs[0xeb] = 0x04;
+      regs[0xec] = 0x18;
+      regs[0xed] = 0x85;
+      regs[0xee] = 0x02;
+      regs[0xef] = 0x0a;
+      regs[0xf0] = 0x81;
+      regs[0xf1] = 0x01;
+    }
   switch (dev->xdpi)
     {
     case 75:
@@ -7053,6 +7547,48 @@ setup_scan_registers (struct Rts8891_Ses
 	  regs[0xf0] = 0x02;
 	  regs[0xf2] = 0x00;
 	  break;
+	case SENSOR_TYPE_UMAX:
+          DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_UMAX for 150 dpi\n");
+	  regs[0x32] = 0x20;
+	  regs[0x33] = 0x83;
+	  regs[0x40] = 0x2c;
+	  regs[0x8d] = 0x09;
+	  regs[0xc1] = 0x06;
+	  regs[0xc2] = 0x7e;
+	  regs[0xc4] = 0xf9;
+	  regs[0xc5] = 0x81;
+	  regs[0xc7] = 0x06;
+	  regs[0xc8] = 0x7e;
+	  regs[0xca] = 0x0f;
+	  regs[0xcb] = 0xc0;
+	  regs[0xcd] = 0x00;
+	  regs[0xce] = 0x30;
+	  regs[0xcf] = 0xe4;
+	  regs[0xd0] = 0xe6;
+	  regs[0xd1] = 0xea;
+	  regs[0xd2] = 0x0b;
+	  regs[0xd3] = 0x17;
+	  regs[0xd4] = 0x01;
+	  regs[0xe2] = 0x0f;
+	  regs[0xe3] = 0x89;
+	  regs[0xe4] = 0x03;
+//	  regs[0xe5] = 0xaa;
+//	  exposure = 170;
+	  exposure = 169;
+
+	  regs[0xe7] = 0x00;
+	  regs[0xe8] = 0x79;
+	  regs[0xe9] = 0x01;
+	  regs[0xea] = 0x0b;
+	  regs[0xeb] = 0x58;
+	  regs[0xec] = 0x01;
+	  regs[0xed] = 0x04;
+	  regs[0xee] = 0xbc;
+	  regs[0xef] = 0x00;
+	  regs[0xf0] = 0x03;
+	  regs[0xf1] = 0x00;
+	  regs[0xf2] = 0x00;
+          break;
 	}
       break;
 
@@ -7205,6 +7741,58 @@ setup_scan_registers (struct Rts8891_Ses
 	  regs[0xf0] = 0x00;
 	  regs[0xf2] = 0x00;
 	  break;
+	case SENSOR_TYPE_UMAX:
+	  DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_UMAX for 300 dpi\n");
+	  regs[0x32] = 0x20;
+	  regs[0x33] = 0x83;
+	  regs[0x35] = 0x0e;
+	  regs[0x3a] = 0x0e;
+	  regs[0x40] = 0x2c;
+	  timing=0x022b;
+	  regs[0x85] = 0x18;
+	  regs[0x86] = 0x1b;
+	  regs[0x87] = 0x30;
+	  regs[0x88] = 0x30;
+	  regs[0x8d] = 0x12;
+	  regs[0xc0] = 0x87;
+	  regs[0xc1] = 0x07;
+	  regs[0xc2] = 0xf8;
+	  regs[0xc3] = 0x78;
+	  regs[0xc4] = 0xf8;
+	  regs[0xc5] = 0x07;
+	  regs[0xc6] = 0x87;
+	  regs[0xc7] = 0x07;
+	  regs[0xc8] = 0xf8;
+	  regs[0xc9] = 0xfc;
+	  regs[0xca] = 0x0f;
+	  regs[0xcd] = 0x00;
+	  regs[0xce] = 0x80;
+	  regs[0xcf] = 0xe2;
+	  regs[0xd0] = 0xe4;
+	  regs[0xd1] = 0xea;
+	  regs[0xd2] = 0x0b;
+	  regs[0xd3] = 0x17;
+	  regs[0xd4] = 0x01;
+	  regs[0xe3] = 0x00;
+	  regs[0xe4] = 0x00;
+//	  regs[0xe5] = 0xc9;
+//	  regs[0xe6] = 0x01;
+	  exposure = 457;
+
+	  regs[0xe7] = 0x00;
+	  regs[0xe8] = 0x00;
+	  regs[0xe9] = 0x00;
+	  regs[0xea] = 0x00;
+	  regs[0xeb] = 0x00;
+	  regs[0xec] = 0x00;
+	  regs[0xed] = 0x00;
+	  regs[0xee] = 0x00;
+	  regs[0xef] = 0x00;
+	  regs[0xf0] = 0x00;
+	  regs[0xf1] = 0x00;
+	  regs[0xf2] = 0x00;
+
+	  break;
 	}
       break;
     case 600:
@@ -7402,6 +7990,74 @@ setup_scan_registers (struct Rts8891_Ses
           DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_4400_BARE for 600 dpi\n");
 	  return SANE_STATUS_INVAL;
 	  break;
+
+	case SENSOR_TYPE_UMAX:
+          DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_UMAX for 600 dpi\n");
+/*	  *status1 = 0x10;
+	  *status2 = 0x23;*/
+
+	  regs[0x32] = 0x20;
+	  regs[0x33] = 0x83;
+	  regs[0x34] = 0xf0;
+	  regs[0x35] = 0x1b;
+	  regs[0x36] = 0x29;
+	  regs[0x3a] = 0x1b;
+	  regs[0x40] = 0x2c;
+	  regs[0x85] = 0x30;
+	  regs[0x86] = 0x30;
+	  regs[0x87] = 0x60;
+	  regs[0x88] = 0x5a;
+	  regs[0x8d] = 0x24;
+
+	  regs[0xc0] = 0xff;
+	  regs[0xc1] = 0x07;
+	  regs[0xc2] = 0x80;
+	  regs[0xc3] = 0x00;
+	  regs[0xc4] = 0xf8;
+	  regs[0xc5] = 0x7f;
+	  regs[0xc6] = 0xff;
+	  regs[0xc7] = 0x07;
+	  regs[0xc8] = 0x80;
+	  regs[0xc9] = 0x00;
+	  regs[0xca] = 0x0f;
+
+	  regs[0xcc] = 0xfe;
+	  regs[0xcd] = 0x00;
+	  regs[0xce] = 0x00;
+	  regs[0xcf] = 0xd7;
+	  regs[0xd0] = 0x61;
+	  regs[0xd1] = 0xaa;
+	  regs[0xd2] = 0x00;
+/*	  regs[0xd3] = 0x0b;*/
+	  regs[0xd4] = 0x03;
+	  regs[0xd5] = 0x05;
+	  regs[0xd6] = 0x86;
+	  regs[0xd7] = 0x1b;
+	  regs[0xd8] = 0x10;
+	  regs[0xd9] = 0xa6;
+	  regs[0xda] = 0x2d;
+
+	  regs[0xe1] = 0x00;
+	  regs[0xe2] = 0x00;
+	  regs[0xe3] = 0x01;
+	  regs[0xe4] = 0x00;
+/*	  regs[0xe5] = 0x00;
+	  regs[0xe6] = 0xbd;*/
+          exposure=0xbd00;
+	  regs[0xe7] = 0x0a;
+	  regs[0xe8] = 0x00;
+	  regs[0xe9] = 0x00;
+	  regs[0xea] = 0x00;
+	  regs[0xeb] = 0x00;
+	  regs[0xec] = 0x00;
+	  regs[0xed] = 0x00;
+	  regs[0xee] = 0x00;
+	  regs[0xef] = 0x00;
+	  regs[0xf0] = 0x00;
+	  regs[0xf1] = 0x00;
+	  regs[0xf2] = 0x00;
+          timing=0x0425;
+	  break;
 	}
       break;
     case 1200:
@@ -7595,6 +8251,67 @@ setup_scan_registers (struct Rts8891_Ses
           DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_4400_BARE for 1200 dpi\n");
 	  return SANE_STATUS_INVAL;
 	  break;
+
+	case SENSOR_TYPE_UMAX:
+	  DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_UMAX for 1200 dpi\n");
+	  regs[0x32] = 0x20;
+	  regs[0x33] = 0x83;
+	  regs[0x34] = 0xf0;
+	  regs[0x35] = 0x0e;
+	  regs[0x36] = 0x29;
+	  regs[0x3a] = 0x0e;
+	  regs[0x40] = 0x2c;
+	  timing=0x081a;
+	  regs[0x85] = 0x60;
+	  regs[0x86] = 0x5a;
+	  regs[0x87] = 0xc0;
+	  regs[0x88] = 0xae;
+	  regs[0x8d] = 0x48;
+
+	  regs[0xc0] = 0x1f;
+	  regs[0xc1] = 0x00;
+	  regs[0xc2] = 0xfe;
+	  regs[0xc3] = 0xe0;
+	  regs[0xc4] = 0xff;
+	  regs[0xc5] = 0x01;
+	  regs[0xc6] = 0x1f;
+	  regs[0xc7] = 0x00;
+	  regs[0xc8] = 0xfe;
+	  regs[0xc9] = 0x00;
+	  regs[0xca] = 0x00;
+	  regs[0xcb] = 0x1c;
+	  regs[0xcc] = 0x00;
+	  regs[0xcd] = 0xc0;
+	  regs[0xce] = 0x01;
+	  regs[0xcf] = 0xeb;
+	  regs[0xd0] = 0xed;
+	  regs[0xd1] = 0xe1;
+	  regs[0xd2] = 0x02;
+	  /*  regs[0xd3] = 0x12; */
+	  regs[0xd4] = 0xf4;
+	  regs[0xd5] = 0x86;
+	  regs[0xd6] = 0x1b;
+
+	  regs[0xe2] = 0x00;
+	  regs[0xe3] = 0x00;
+	  regs[0xe4] = 0x00;
+	  /* regs[0xe5] = 0xf7;
+	     regs[0xe6] = 0x2a; */
+          exposure=0x2af7;
+	  regs[0xe7] = 0x00;
+	  regs[0xe8] = 0x00;
+	  regs[0xe9] = 0x00;
+	  regs[0xea] = 0x00;
+	  regs[0xeb] = 0x00;
+	  regs[0xec] = 0x00;
+	  regs[0xed] = 0x00;
+	  regs[0xee] = 0x00;
+	  regs[0xef] = 0x00;
+	  regs[0xf0] = 0x00;
+	  regs[0xf1] = 0x00;
+	  regs[0xf2] = 0x00;
+
+	  break;
 	}
       break;
     }
diff -urp ../../sane-backends-1.0.24-orig/backend/rts8891_devices.c ./rts8891_devices.c
--- ../../sane-backends-1.0.24-orig/backend/rts8891_devices.c	2013-08-25 23:22:58.000000000 +0200
+++ ./rts8891_devices.c	2015-05-26 22:07:57.000000000 +0200
@@ -198,7 +198,7 @@ static Rts8891_Model astra4400_model = {
   24, 12, 0,			/* R, G, and B CCD Line-distance correction in lines at
 				   max motor resolution */
   /* default sensor */
-  SENSOR_TYPE_XPA,
+  SENSOR_TYPE_UMAX,
 
   /* default gamma table */
   {0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c,
diff -urp ../../sane-backends-1.0.24-orig/backend/rts8891_low.c ./rts8891_low.c
--- ../../sane-backends-1.0.24-orig/backend/rts8891_low.c	2013-08-25 23:22:58.000000000 +0200
+++ ./rts8891_low.c	2015-05-26 21:12:43.000000000 +0200
@@ -370,6 +370,29 @@ rts8891_data_format (SANE_Int dpi, int s
 	  break;
 	}
     }
+  if (sensor == SENSOR_TYPE_UMAX)
+    {
+      switch (dpi)
+	{
+	case 75:
+	  reg = 0x0b;
+	  break;
+	case 150:
+	  reg = 0x17;//color stripes (sometimes???)
+//	  reg = 0x0e;
+	  break;
+	case 300:
+	  reg = 0x17;
+	  break;
+	case 600:
+	  reg = 0x0b;
+	  break;
+	case 1200:
+	  reg = 0x12;
+//	  reg = 0x17;
+	  break;
+	}
+    }
   return reg;
 }
 
@@ -425,6 +448,11 @@ rts8891_move (struct Rts8891_Device *dev
 
   /* prepare scan */
   rts8891_set_default_regs (regs);
+  if (device->sensor = SENSOR_TYPE_UMAX)
+    {
+      regs10 = 0x20;
+      regs11 = 0x3b;
+    }
   if (device->sensor != SENSOR_TYPE_4400
       && device->sensor != SENSOR_TYPE_4400_BARE)
     {
@@ -511,6 +539,29 @@ rts8891_move (struct Rts8891_Device *dev
       regs[0xe5] = 0xf3;	/* 0xf9 */
       regs[0xe6] = 0x01;	/* 0x00 */
     }
+  if (device->sensor == SENSOR_TYPE_UMAX)
+    {
+      regs[0x14] = 0xf0;
+      regs[0x16] = 0x0f;
+      regs[0x23] = 0x00;
+      regs[0x40] = 0xa0;
+//      regs[0x7a] = 0x02;
+      regs[0x80] = 0x83;
+      regs[0x81] = 0x01;
+      regs[0x82] = 0x84;
+      regs[0x83] = 0x01;
+      regs[0x85] = 0x10;
+      regs[0x86] = 0x14;
+      regs[0x87] = 0x20;
+      regs[0x88] = 0x22;
+      regs[0x89] = 0x85;
+      regs[0x8a] = 0x01;
+      regs[0x8d] = 0x4f;
+      //regs[0xd9] = 0x2d;
+      //regs[0xda] = 0x00;
+      //regs[0xe5] = 0x1b;
+      //regs[0xe6] = 0x01;
+    }
 
   /* disable CCD */
   regs[0] = 0xf5;
diff -urp ../../sane-backends-1.0.24-orig/backend/rts8891_low.h ./rts8891_low.h
--- ../../sane-backends-1.0.24-orig/backend/rts8891_low.h	2013-08-25 23:22:58.000000000 +0200
+++ ./rts8891_low.h	2015-05-26 21:03:16.000000000 +0200
@@ -74,7 +74,8 @@
 #define SENSOR_TYPE_XPA		1	/* sensor for hp4470 sold with XPA */
 #define SENSOR_TYPE_4400	2	/* sensor for hp4400               */
 #define SENSOR_TYPE_4400_BARE	3	/* sensor for hp4400               */
-#define SENSOR_TYPE_MAX         3       /* maximum sensor number value     */
+#define SENSOR_TYPE_UMAX	4	/* sensor for Umax Astra 4400/4450 */
+#define SENSOR_TYPE_MAX         4       /* maximum sensor number value     */
 
 /* Forward typedefs */
 typedef struct Rts8891_Device Rts8891_Device;
