From 3dba8c1d666737c5093e08a82bec59c453dfed78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Voltz?= Date: Sun, 25 Apr 2010 21:32:44 +0200 Subject: [PATCH] WIP setup optical regs ~OK --- backend/genesys.c | 89 +++- backend/genesys.conf.in | 3 + backend/genesys_devices.c | 114 +++++ backend/genesys_gl646.c | 3 +- backend/genesys_gl841.c | 1 + backend/genesys_gl847.c | 912 ++++++++++++-------------------------- backend/genesys_gl847.h | 13 +- backend/genesys_low.h | 20 +- 8 files changed, 522 insertions(+), 633 deletions(-) diff --git a/backend/genesys.c b/backend/genesys.c index 5784b56b0..30fc8b874 100644 --- a/backend/genesys.c +++ b/backend/genesys.c @@ -166,7 +166,7 @@ static const SANE_Range threshold_curve_range = { /* ------------------------------------------------------------------------ */ /* - * returns true if filter bit is on (monochrome scan) + * setup the hardware dependent functions */ static SANE_Status genesys_init_cmd_set (Genesys_Device * dev) @@ -177,6 +177,8 @@ genesys_init_cmd_set (Genesys_Device * dev) return sanei_gl646_init_cmd_set (dev); case GENESYS_GL841: return sanei_gl841_init_cmd_set (dev); + case GENESYS_GL847: + return sanei_gl847_init_cmd_set (dev); default: return SANE_STATUS_INVAL; } @@ -284,13 +286,45 @@ sanei_genesys_set_reg_from_set (Genesys_Register_Set * reg, SANE_Byte address, /* Read and write RAM, registers and AFE */ /* ------------------------------------------------------------------------ */ +/** + * Write to one GL847 ASIC register +URB 10 control 0x40 0x04 0x83 0x00 len 2 wrote 0xa6 0x04 + */ +static SANE_Status +sanei_genesys_write_gl847_register (Genesys_Device * dev, uint8_t reg, uint8_t val) +{ + SANE_Status status; + uint8_t buffer[2]; -/* Write to one register */ + buffer[0]=reg; + buffer[1]=val; + status = + sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER, + VALUE_SET_REGISTER, INDEX, 2, buffer); + if (status != SANE_STATUS_GOOD) + { + DBG (DBG_error, "sanei_genesys_write_gl847_register (0x%02x, 0x%02x): failed : %s\n", reg, val, sane_strstatus (status)); + return status; + } + + DBG (DBG_io, "sanei_genesys_write_gl847_register (0x%02x, 0x%02x) completed\n", + reg, val); + + return status; +} + +/** + * Write to one ASIC register + */ SANE_Status sanei_genesys_write_register (Genesys_Device * dev, uint8_t reg, uint8_t val) { SANE_Status status; + /* route to gl847 function if needed */ + if(dev->model->asic_type==GENESYS_GL847) + return sanei_genesys_write_gl847_register(dev, reg, val); + status = sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX, 1, ®); @@ -319,6 +353,29 @@ sanei_genesys_write_register (Genesys_Device * dev, uint8_t reg, uint8_t val) return status; } +/* read reg 0x41: + * URB 164 control 0xc0 0x04 0x8e 0x4122 len 2 read 0xfc 0x55 + */ +static SANE_Status +sanei_genesys_read_gl847_register (Genesys_Device * dev, uint8_t reg, uint8_t * val) +{ + SANE_Status status; + uint16_t value; + + status = + sanei_usb_control_msg (dev->dn, REQUEST_TYPE_IN, REQUEST_BUFFER, + VALUE_GET_REGISTER, 0x22+(reg<<8), 2, (SANE_Byte *)&value); + if (status != SANE_STATUS_GOOD) + { + DBG (DBG_error, + "sanei_genesys_read_gl847_register (0x%02x): failed while setting register: %s\n", + reg, sane_strstatus (status)); + return status; + } + *val=value & 0xff; + DBG( DBG_io2, "sanei_genesys_read_gl847_register(0x%02x)=0x%02x\n",reg,value & 0xff); + return status; +} /* Read from one register */ SANE_Status @@ -326,6 +383,10 @@ sanei_genesys_read_register (Genesys_Device * dev, uint8_t reg, uint8_t * val) { SANE_Status status; + /* route to gl847 function if needed */ + if(dev->model->asic_type==GENESYS_GL847) + return sanei_genesys_read_gl847_register(dev, reg, val); + status = sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX, 1, ®); @@ -361,6 +422,13 @@ SANE_Status sanei_genesys_set_buffer_address (Genesys_Device * dev, uint32_t addr) { SANE_Status status; + + if(dev->model->asic_type==GENESYS_GL847) + { + DBG (DBG_warn, + "sanei_genesys_set_buffer_address: shouldn't be used for GL847 \n"); + return SANE_STATUS_GOOD; + } DBG (DBG_io, "sanei_genesys_set_buffer_address: setting address to 0x%05x\n", @@ -1377,8 +1445,20 @@ genesys_send_offset_and_shading (Genesys_Device * dev, uint8_t * data, DBG (DBG_proc, "genesys_send_offset_and_shading (size = %d)\n", size); + /* ASIC higher than gl843 doesn't have register 2A/2B, so we route to + * a per ASIC shading data loading function if available */ + if(dev->model->cmd_set->send_shading_data!=NULL) + { + status=dev->model->cmd_set->send_shading_data(dev, data, size); + DBG (DBG_proc, "genesys_send_offset_and_shading: completed\n"); + return status; + } + + /* gl646, gl84[123] case */ dpihw = sanei_genesys_read_reg_from_set (dev->reg, 0x05) >> 6; + /* TODO invert the test so only the 2 models behaving like that are + * tested instead of adding all the others */ /* many scanners send coefficient for lineart/gray like in color mode */ if (dev->settings.scan_mode < 2 && dev->model->ccd_type != CCD_DSMOBILE600 @@ -6055,7 +6135,10 @@ config_attach_genesys (SANEI_Config * config, const char *devname) } /* probes for scanner to attach to the backend */ -static SANE_Status +#ifndef UNIT_TESTING +static +#endif +SANE_Status probe_genesys_devices (void) { SANEI_Config config; diff --git a/backend/genesys.conf.in b/backend/genesys.conf.in index 62b784d62..6addfaf06 100644 --- a/backend/genesys.conf.in +++ b/backend/genesys.conf.in @@ -36,6 +36,9 @@ usb 0x04a9 0x2213 # Canon LiDE 60 usb 0x04a9 0x221c +# Canon LiDE 200 +usb 0x04a9 0x1905 + # Visioneer Strobe XP200 usb 0x04a7 0x0426 diff --git a/backend/genesys_devices.c b/backend/genesys_devices.c index 7d7baddd8..a5ef15832 100644 --- a/backend/genesys_devices.c +++ b/backend/genesys_devices.c @@ -138,6 +138,14 @@ static Genesys_Frontend Wolfson[] = { , {0x07, 0x00, 0x00} } , + {DAC_CANONLIDE200, + {0x9d, 0x9a, 0x00, 0x00} + , {0x00, 0x00, 0x00} + , {0x32, 0x04, 0x00} /* offset */ + , {0x00, 0x3f, 0x00} /* gain */ + , {0x00, 0x00, 0x00} + } + , /* 6: CANONLIDE200 */ }; @@ -393,6 +401,31 @@ static Genesys_Sensor Sensor[] = { 1.0, 1.0, 1.0, NULL, NULL, NULL} , + /* CANONLIDE200 */ + {CIS_CANONLIDE200, + 1200, /* optical resolution */ + 87, /* black pixels */ + 16, /* dummy pixels */ + 0, + 10400, + 210, + 200, + {0x00, 0x00, 0x00, 0x00}, + /* reg 0x10 - 0x1d */ + {0x02, 0x7d, 0x02, 0x7d, 0x02, 0x7d, /* EXPR/EXPG/EXPB */ + 0x10, 0x0c, 0x00, 0xff, 0x34, 0x00, 0x02, 0x04 }, + /* reg 0x52 - 0x5e */ + {0x03, 0x07, + 0x00, 0x00, 0x00, 0x00, + 0x2a, 0xe1, + 0x55, + 0x00, 0x00, 0x00, + 0x41 + } + , + 1.0, 1.0, 1.0, + NULL, NULL, NULL} + , }; @@ -492,6 +525,14 @@ static Genesys_Gpo Gpo[] = { {0xfb, 0x00}, /* 6e, 6f */ } , + /* CANONLIDE200 */ + {GPO_CANONLIDE200, + {0xfb, 0x20} + , + {0xff, 0x00} + , + } + , }; static Genesys_Motor Motor[] = { @@ -712,6 +753,24 @@ static Genesys_Motor Motor[] = { 0.8, },},}, }, + {MOTOR_CANONLIDE200, /* Canon LiDE 200 */ + 1200, + 2400, + 1, + 1, + {{{ + 3500, + 1300, + 60, + 0.8, + }, + { + 3500, + 1400, + 60, + 0.8, + },},}, + }, }; /* here we have the various device settings... @@ -821,6 +880,60 @@ static Genesys_Model canon_lide_50_model = { 400 }; +static Genesys_Model canon_lide_200_model = { + "canon-lide-200", /* Name */ + "Canon", /* Device vendor string */ + "LiDE 200", /* Device model name */ + GENESYS_GL847, + NULL, + + {1200, 600, 300, 150, 75, 50, 0}, /* possible x-resolutions */ + {2400, 1200, 600, 300, 150, 75, 50, 0}, /* possible y-resolutions */ + {16, 8, 0}, /* possible depths in gray mode */ + {16, 8, 0}, /* possible depths in color mode */ + + SANE_FIX (0.42), /* Start of scan area in mm (x) */ + SANE_FIX (7.9), /* Start of scan area in mm (y) */ + SANE_FIX (218.0), /* Size of scan area in mm (x) */ + SANE_FIX (299.0), /* Size of scan area in mm (y) */ + + SANE_FIX (3.0), /* Start of white strip in mm (y) */ + SANE_FIX (0.0), /* Start of black mark in mm (x) */ + + SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ + SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ + SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ + SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ + + SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ + + SANE_FIX (0.0), /* Size of scan area after paper sensor stops + sensing document in mm */ + SANE_FIX (0.0), /* Amount of feeding needed to eject document + after finishing scanning in mm */ + + 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ + + COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ + + SANE_TRUE, /* Is this a CIS scanner? */ + SANE_FALSE, /* Is this a sheetfed scanner? */ + CIS_CANONLIDE200, + DAC_CANONLIDE200, + GPO_CANONLIDE200, + MOTOR_CANONLIDE200, + GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ + | GENESYS_FLAG_SKIP_WARMUP + | GENESYS_FLAG_OFFSET_CALIBRATION + | GENESYS_FLAG_DARK_WHITE_CALIBRATION + | GENESYS_FLAG_CUSTOM_GAMMA + | GENESYS_FLAG_HALF_CCD_MODE, + GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, + 300, + 400 +}; /* this is completely untested -- hmg */ + + static Genesys_Model canon_lide_60_model = { "canon-lide-60", /* Name */ "Canon", /* Device vendor string */ @@ -1896,6 +2009,7 @@ static Genesys_USB_Device_Entry genesys_usb_device_list[] = { {0x04a7, 0x04ac, &xerox_travelscanner_model}, {0x04a9, 0x2213, &canon_lide_50_model}, {0x04a9, 0x221c, &canon_lide_60_model}, + {0x04a9, 0x1905, &canon_lide_200_model}, {0x0638, 0x0a10, &umax_astra_4500_model}, {0x07b3, 0x0600, &plustek_st12_model}, {0x07b3, 0x0601, &plustek_st24_model}, diff --git a/backend/genesys_gl646.c b/backend/genesys_gl646.c index 04d791bff..5ca022664 100644 --- a/backend/genesys_gl646.c +++ b/backend/genesys_gl646.c @@ -5752,7 +5752,8 @@ static Genesys_Command_Set gl646_cmd_set = { gl646_search_strip, gl646_is_compatible_calibration, - gl646_move_to_ta + gl646_move_to_ta, + NULL }; SANE_Status diff --git a/backend/genesys_gl841.c b/backend/genesys_gl841.c index 1e46e8d96..de5c4bd52 100644 --- a/backend/genesys_gl841.c +++ b/backend/genesys_gl841.c @@ -6296,6 +6296,7 @@ static Genesys_Command_Set gl841_cmd_set = { gl841_search_strip, gl841_is_compatible_calibration, + NULL, NULL }; diff --git a/backend/genesys_gl847.c b/backend/genesys_gl847.c index c10285ee8..dd8995185 100644 --- a/backend/genesys_gl847.c +++ b/backend/genesys_gl847.c @@ -53,6 +53,75 @@ /* Read and write RAM, registers and AFE */ /* ------------------------------------------------------------------------ */ +/** + * + */ +static SANE_Status +write_end_access (Genesys_Device * dev, uint8_t index, uint8_t val) +{ + SANE_Status status; + + DBG (DBG_io, "write_end_access: 0x%02x,0x%02x\n", index, val); + + status = + sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER, + VALUE_BUF_ENDACCESS, index, 1, &val); + if (status != SANE_STATUS_GOOD) + { + DBG (DBG_error, + "write_end_access: failed %s\n", sane_strstatus (status)); + } + return status; +} + + +/** + * writes a block of data to AHB + * @param dn USB device index + * @param addr AHB address to write to + * @param size size of the chunk of data + * @param data pointer to the data to write + */ +static SANE_Status +write_ahb (SANE_Int dn, uint32_t addr, uint32_t size, uint8_t * data) +{ + uint8_t outdata[8]; + size_t written; + SANE_Status status = SANE_STATUS_GOOD; + + outdata[0] = addr & 0xff; + outdata[1] = ((addr >> 8) & 0xff); + outdata[2] = ((addr >> 16) & 0xff); + outdata[3] = ((addr >> 24) & 0xff); + outdata[4] = (size & 0xff); + outdata[5] = ((size >> 8) & 0xff); + outdata[6] = ((size >> 16) & 0xff); + outdata[7] = ((size >> 24) & 0xff); + + /* write addr and size for AHB */ + status = + sanei_usb_control_msg (dn, REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, + 0x01, sizeof (outdata), outdata); + if (status != SANE_STATUS_GOOD) + { + DBG (DBG_error, "write_ahb: failed while setting addr and size: %s\n", + sane_strstatus (status)); + return status; + } + + /* write actual data */ + written = size; + status = sanei_usb_write_bulk (dn, data, &written); + if (status != SANE_STATUS_GOOD) + { + DBG (DBG_error, "write_ahb: failed while writing bulk data: %s\n", + sane_strstatus (status)); + return status; + } + + return status; +} + /** * Write to many GL847 registers at once * Note: There is no known bulk register write, @@ -62,7 +131,7 @@ gl847_bulk_write_register (Genesys_Device * dev, Genesys_Register_Set * reg, size_t elems) { SANE_Status status = SANE_STATUS_GOOD; - int i; + size_t i; for (i = 0; i < elems && status == SANE_STATUS_GOOD; i++) { @@ -329,326 +398,10 @@ print_status (uint8_t val) DBG (DBG_info, "status=%s\n", msg); } -/* - * dumps register set in a human readable format - * todo : finish all register decoding - * - * adapted to sanei_gl847 but not tested at all - */ -static void -sanei_gl847_print_registers (Genesys_Register_Set * reg) -{ - SANE_Int i; - SANE_Byte v; - SANE_Int fastmode = 0; - SANE_Int lperiod; - SANE_Int cpp = 0; - - lperiod = - sanei_genesys_read_reg_from_set (reg, - 0x38) * 256 + - sanei_genesys_read_reg_from_set (reg, 0x39); -#if 0 - fastmode = - (sanei_genesys_read_reg_from_set (reg, 0x01) & REG01_FASTMOD) ? 1 : 0; -#endif - - for (i = 0; i < GENESYS_GL847_MAX_REGS; i++) - { - v = reg[i].value; - DBG (DBG_info, "reg 0x%02x: 0x%02x ", reg[i].address, v); - switch (reg[i].address) - { - case 0x01: - DBG (DBG_info, "%s, %s, %s, %s, %s, %s, %s, ", /*%s", */ - (v & REG01_CISSET) ? "CIS" : "CCD", - (v & REG01_DOGENB) ? "watchdog on" : "watchdog off", - (v & REG01_DVDSET) ? "shading on" : "shading off", - /*(v & REG01_FASTMOD) ? "fastmode on" : "fastmode off", */ - (v & REG01_M16DRAM) ? "data comp on" : "data comp off", - (v & REG01_DRAMSEL) ? "1 MB RAM" : "512 KB RAM", - (v & REG01_SHDAREA) ? "shading=scan area" : - "shading=total line", - (v & REG01_SCAN) ? "enable scan" : "disable scan"); - break; - case 0x02: - DBG (DBG_info, "%s, %s, %s, %s, %s, %s, %s, %s", - (v & REG02_NOTHOME) ? "autohome doesn't work" : - "autohome works", - (v & REG02_ACDCDIS) ? "backtrack off" : "backtrack on", - (v & REG02_AGOHOME) ? "autohome on" : "autohome off", - (v & REG02_MTRPWR) ? "motor on" : "motor off", - (v & REG02_FASTFED) ? "2 tables" : "1 table", - (v & REG02_MTRREV) ? "reverse" : "forward", - (v & REG02_HOMENEG) ? "indicate home sensor falling edge" : - "indicate home sensor rising edge", - (v & REG02_LONGCURV) ? - "deceleration curve fast mode is table 5" : - "deceleration curve fast mode is table 4"); - break; - case 0x03: - DBG (DBG_info, "%s, %s, %s, %s, %s, lamptime: %d pixels", - (v & REG03_LAMPDOG) ? "lamp sleeping mode on" : - "lamp sleefping mode off", - (v & REG03_AVEENB) ? "dpi average" : "dpi deletion", - (v & REG03_XPASEL) ? "TA lamp" : "flatbed lamp", - (v & REG03_LAMPPWR) ? "lamp on" : "lamp off", - "lamp timer on", - v & REG03_LAMPTIM * (fastmode + 1) * 65536 * lperiod); - break; - case 0x04: - DBG (DBG_info, "%s, %s, AFEMOD: %d, %s, %s", - /*(v & REG04_LINEART) ? "lineart on" : "lineart off", */ - "sanei_gl847 manual rev 1.7 is strange here ", - (v & REG04_BITSET) ? "image data 16 bits" : - "image data 8 bits", - ((v & REG04_AFEMOD) >> 4), - ((v & REG04_FILTER) >> 2 == - 0) ? "color filter" : ((v & REG04_FILTER) >> 2 == - 1) ? "red filter" : ((v & - REG04_FILTER) - >> 2 == - 2) ? - "green filter" : "blue filter", - ((v & REG04_FESET) < - 2) ? (((v & REG04_FESET) == 0) ? "ESIC type 1" : - "ESIC type 2") : (((v & REG04_FESET) == - 2) ? "ADI type" : "reserved")); - break; - case 0x05: - DBG (DBG_info, "%s, %s, %s, %s, %s, %s", - ((v & REG05_DPIHW) >> 6) == 0 ? "opt. sensor dpi: 600" : - ((v & REG05_DPIHW) >> 6) == - 1 ? "opt. sensor dpi: 1200 dpi" : ((v & REG05_DPIHW) >> - 6) == - 2 ? "opt. sensor dpi: 2400 dpi" : - "opt. sensor dpi: reserved", - "lamp time out", - ((v & REG05_MTLLAMP) >> 4) < 2 - ? (((v & REG05_MTLLAMP) >> 4) == 0 - ? "1*LAMPTIM" : "2*LAMPTIM") - : ((v & REG05_MTLLAMP) >> 4) == 2 - ? "4*LAMPTIM" : "reserved", - (v & REG05_GMMENB) ? "gamma correction on" : - "gamma correction off", - "pixes number under each system pixel time: ", - (v & REG05_MTLBASE) < 2 - ? ((v & REG05_MTLBASE) == 0 - ? "1" : "2") : (v & REG05_MTLBASE) == 2 ? "3" : "4"); - /* I don't now if this works cause in gl646 the unit of - measurement is clocks/pixel and in sanei_gl847 it is - pixel/system pixel time */ - { - switch (v & REG05_MTLBASE) - { - case 0: - cpp = 1; - break; - case 1: - cpp = 2; - break; - case 2: - cpp = 3; - break; - case 3: - cpp = 4; - break; - } - } - break; - case 0x06: - DBG (DBG_info, "12 clk/pixel normal for scanning, %s, %s, %s, %s", - ((v & REG06_SCANMOD >> 5) > 5) ? - ((v & REG06_SCANMOD >> 5) == 4) ? - " 6 clk/pixel fast mode " - : ((v & REG06_SCANMOD >> 5) == 5) ? - " 15 clk/pixel 16 color" - : " 18 clk/pixel 16 color" - : - ((v & REG06_SCANMOD >> 5) < 2) ? - ((v & REG06_SCANMOD >> 5) == 0) ? - "12 clk/pixel normal for scanning" - : "12 clk/pixel bypass for scanning" - : - " reserved", - (v & REG06_PWRBIT) ? "turn power on" : - "don't turn power on", - (v & REG06_GAIN4) ? "digital shading gain=4 times system" : - "digital shading gain=8 times system", - (v & REG06_OPTEST) == - 0 ? "ASIC test mode: off" : (v & REG06_OPTEST) == 1 ? - "ASIC test mode: simulation, motorgo" : - (v & REG06_OPTEST) == 2 ? - "ASIC test mode: image, pixel count" : - (v & REG06_OPTEST) == 3 ? - "ASIC test mode: image, line count" : - (v & REG06_OPTEST) == 4 ? - "ASIC test mode: simulation, counter + adder" : - (v & REG06_OPTEST) == 5 ? - "ASIC test mode: CCD TG" : "ASIC test mode: reserved"); - break; - case 0x07: - DBG (DBG_info, "%s, %s, %s, %s", - (v & REG07_SRAMSEL) ? "DMA access for SRAM" : - "DMA access for DRAM", - (v & REG07_FASTDMA) ? "2 clocks/access" : - "4 clocks/access", - (v & REG07_DMASEL) ? "DMA access for DRAM" : - "MPU access for DRAM", - (v & REG07_DMARDWR) ? "DMA read DRAM" : "DMA write DRAM"); - break; - case 0x08: - DBG (DBG_info, "%s, %s, %s, %s, %s, %s, %s", - (v & REG08_DECFLAG) ? "gamma table is decrement type" : - "gamma table is increment type", - (v & REG08_GMMFFR) ? - "red channel Gamma table address FFH is special type" - : " ", - (v & REG08_GMMFFG) ? - "green channel Gamma table address FFH is special type" - : " ", - (v & REG08_GMMFFB) ? - "blue channel Gamma table address FFH is special type" - : " ", - (v & REG08_GMMZR) ? - "red channel Gamma table address 00H is special type" - : " ", - (v & REG08_GMMZG) ? - "green channel Gamma table address 0H is special type" - : " ", - (v & REG08_GMMZB) ? - "blue channel Gamma table address 00H is special type" : " "); - break; - case 0x09: - DBG (DBG_info, "%s, %s, %s, %s, %s, %s", - ((v & REG09_MCNTSET) == 0) ? "pixel count" : - ((v & REG09_MCNTSET) == 1) ? "system clock*2" : - ((v & REG09_MCNTSET) == 2) ? "system clock*3" : - "system clock*4", - ((v & REG09_CLKSET) == 0) ? "24MHz" : - ((v & REG09_CLKSET) == 1) ? "30MHz" : - ((v & REG09_CLKSET) == 2) ? "40MHz" : - "48MHz", - (v & REG09_BACKSCAN) ? - "backward scan function" - : "forward scan function ", - (v & REG09_ENHANCE) ? - "enhance EPP interfgace speed for USB2.0 " - : "select normal EPP interface speed for USB2.0 ", - (v & REG09_SHORTTG) ? - "enable short CCD SH(TG) period for film scanning" - : " ", - (v & REG09_NWAIT) ? "delay nWait (H_BUSY) one clock" : " "); - break; - case 0x0a: - DBG (DBG_info, "%s", - (v & REG0A_SRAMBUF) ? - "select external SRAM as the image buffer" : - "select external DRAM as the image buffer"); - break; - case 0x0d: - DBG (DBG_info, "scanner command: %s", - (v & REG0D_CLRLNCNT) ? "clear SCANCNT(Reg4b,Reg4c,Reg4d)" : - "don't clear SCANCNT"); - break; - case 0x0e: - DBG (DBG_info, "scanner software reset"); - break; - case 0x0f: - DBG (DBG_info, "start motor move"); - break; - case 0x10: - DBG (DBG_info, "red exposure time hi"); - break; - case 0x11: - DBG (DBG_info, "red exposure time lo (total: 0x%x)", - v + 256 * sanei_genesys_read_reg_from_set (reg, 0x10)); - break; - case 0x12: - DBG (DBG_info, "green exposure time hi"); - break; - case 0x13: - DBG (DBG_info, "green exposure time lo (total: 0x%x)", - v + 256 * sanei_genesys_read_reg_from_set (reg, 0x12)); - break; - case 0x14: - DBG (DBG_info, "blue exposure time hi"); - break; - case 0x15: - DBG (DBG_info, "blue exposure time lo (total: 0x%x)", - v + 256 * sanei_genesys_read_reg_from_set (reg, 0x14)); - break; - case 0x16: - DBG (DBG_info, "%s, %s, %s, %s, %s, %s, %s, %s", - (v & REG16_CTRLHI) ? "CCD CP & RS hi when TG high" : - "CCD CP & RS lo when TG high", - (v & REG16_TOSHIBA) ? "image sensor is TOSHIBA CIS" : - " ", - (v & REG16_TGINV) ? "inverse CCD TG" : "normal CCD TG", - (v & REG16_CK1INV) ? "inverse CCD clock 1" : - "normal CCD clock 1", - (v & REG16_CK2INV) ? "inverse CCD clock 2" : - "normal CCD clock 2", - (v & REG16_CTRLINV) ? "inverse CCD CP & RS" : - "normal CCD CP & RS", - (v & REG16_CKDIS) ? "CCD TG position clock 1/2 signal off" - : "CCD TG position clock 1/2 signal on", - (v & REG16_CTRLDIS) ? "CCD TG position CP & RS signals off" - : "CCD TG position CP & RS signals off"); - break; - case 0x17: - DBG (DBG_info, "%s, CCD TG width: %0x", - ((v & REG17_TGMODE) >> 6) == - 0x00 ? "CCD TG without dummy line" : ((v & REG17_TGMODE) >> - 6) == - 0x01 ? "CCD TG with dummy line" : "CCD TG reserved", - (v & REG17_TGW)); - break; - case 0x18: - DBG (DBG_info, "%s, %d time CCD clock speed for dummy line, %s, " - "delay %d system clocks for CCD clock 1/2, %d time CCD clock speed for capture image", - (v & REG18_CNSET) ? "TG and clock canon CIS style" : - "TG and clock non-canon CIS style", - ((v & REG18_DCKSEL) >> 5) + 1, - (v & REG18_CKTOGGLE) ? - "half cycle per pixel for CCD clock 1/2" : - "one cycle per pixel for CCD clock 1/2", - ((v & REG18_CKDELAY) >> 2), ((v & REG18_CKSEL) + 1)); - - break; - case 0x19: - DBG (DBG_info, "dummy line exposure time (0x%x pixel times)", - v * 256); - break; - case 0x1a: - DBG (DBG_info, "%s, %s, %s, %s, %s", - (v & REG1A_MANUAL3) ? - "CCD clock3,clock4 manual output" - : "CCD clock3,clock4 automatic output", - (v & REG1A_MANUAL1) ? - "CCD clock1,clock2 manual output" - : "CCD clock1,clock2 automatic output", - (v & REG1A_CK4INV) ? - "reverse CCD Clock4" - : " ", - (v & REG1A_CK3INV) ? - "reverse CCD Clock3" - : " ", - (v & REG1A_LINECLP) ? - "CCD line clamping" : "CCD pixel clamping"); - break; - case 0x1b: - DBG (DBG_info, "reserved"); - break; - } - DBG (DBG_info, "\n"); - } -} /** copy sensor specific settings */ /* *dev : device infos *regs : registers to be set - extended : do extended set up half_ccd: set up for half ccd resolution all registers 08-0B, 10-1D, 52-59 are set up. They shouldn't appear anywhere else but in register_ini @@ -679,102 +432,28 @@ other register settings depending on this: */ static void -sanei_gl847_setup_sensor (Genesys_Device * dev, - Genesys_Register_Set * regs, - SANE_Bool extended, SANE_Bool half_ccd) +gl847_setup_sensor (Genesys_Device * dev, Genesys_Register_Set * regs) { Genesys_Register_Set *r; int i; DBG (DBG_proc, "gl847_setup_sensor\n"); - r = sanei_genesys_get_address (regs, 0x70); - for (i = 0; i < 4; i++, r++) - r->value = dev->sensor.regs_0x08_0x0b[i]; - - r = sanei_genesys_get_address (regs, 0x16); - for (i = 0x06; i < 0x0a; i++, r++) - r->value = dev->sensor.regs_0x10_0x1d[i]; - - r = sanei_genesys_get_address (regs, 0x1a); - for (i = 0x0a; i < 0x0e; i++, r++) - r->value = dev->sensor.regs_0x10_0x1d[i]; - - r = sanei_genesys_get_address (regs, 0x52); - for (i = 0; i < 9; i++, r++) - r->value = dev->sensor.regs_0x52_0x5e[i]; - - /* don't go any further if no extended setup */ - if (!extended) - return; - - /* todo : add more CCD types if needed */ - /* we might want to expand the Sensor struct to have these - 2 kind of settings */ - if (dev->model->ccd_type == CCD_5345) + for (i = 0x06; i < 0x0e; i++) { - if (half_ccd) - { - /* settings for CCD used at half is max resolution */ - r = sanei_genesys_get_address (regs, 0x70); - r->value = 0x00; - r = sanei_genesys_get_address (regs, 0x71); - r->value = 0x05; - r = sanei_genesys_get_address (regs, 0x72); - r->value = 0x06; - r = sanei_genesys_get_address (regs, 0x73); - r->value = 0x08; - r = sanei_genesys_get_address (regs, 0x18); - r->value = 0x28; - r = sanei_genesys_get_address (regs, 0x58); - r->value = 0x80 | (r->value & 0x03); /* VSMP=16 */ - } - else - { - /* swap latch times */ - r = sanei_genesys_get_address (regs, 0x18); - r->value = 0x30; - r = sanei_genesys_get_address (regs, 0x52); - for (i = 0; i < 6; i++, r++) - r->value = dev->sensor.regs_0x52_0x5e[(i + 3) % 6]; - r = sanei_genesys_get_address (regs, 0x58); - r->value = 0x20 | (r->value & 0x03); /* VSMP=4 */ - } - return; + r = sanei_genesys_get_address (regs, 0x10 + i); + if(r) + r->value = dev->sensor.regs_0x10_0x1d[i]; } - if (dev->model->ccd_type == CCD_HP2300) + for (i = 0; i < 9; i++) { - /* settings for CCD used at half is max resolution */ - if (half_ccd) - { - r = sanei_genesys_get_address (regs, 0x70); - r->value = 0x16; - r = sanei_genesys_get_address (regs, 0x71); - r->value = 0x00; - r = sanei_genesys_get_address (regs, 0x72); - r->value = 0x01; - r = sanei_genesys_get_address (regs, 0x73); - r->value = 0x03; - /* manual clock programming */ - r = sanei_genesys_get_address (regs, 0x1d); - r->value |= 0x80; - } - else - { - r = sanei_genesys_get_address (regs, 0x70); - r->value = 1; - r = sanei_genesys_get_address (regs, 0x71); - r->value = 3; - r = sanei_genesys_get_address (regs, 0x72); - r->value = 4; - r = sanei_genesys_get_address (regs, 0x73); - r->value = 6; - } - r = sanei_genesys_get_address (regs, 0x58); - r->value = 0x80 | (r->value & 0x03); /* VSMP=16 */ - return; + r = sanei_genesys_get_address (regs, 0x52 + i); + if(r) + r->value = dev->sensor.regs_0x52_0x5e[i]; } + + DBG (DBG_proc, "gl847_setup_sensor: completed \n"); } @@ -890,12 +569,6 @@ gl847_init_registers (Genesys_Device * dev) SETREG (0xa9, 0x00); SETREG (0xfe, 0x08); - /* setup base address for shading data. TODO private struct for description */ - /* values must be multiplied by 8192=0x4000 to give address on AHB */ - SETREG (0xd0, 0x0a); - SETREG (0xd1, 0x1f); - SETREG (0xd2, 0x34); - /* gamma[0] and gamma[256] values */ SETREG (0xbe, 0x00); SETREG (0xc5, 0x00); @@ -915,7 +588,6 @@ gl847_send_slope_table (Genesys_Device * dev, int table_nr, uint16_t * slope_table, int steps) { int dpihw; - int start_address; SANE_Status status; uint8_t *table; int i; @@ -923,17 +595,6 @@ gl847_send_slope_table (Genesys_Device * dev, int table_nr, DBG (DBG_proc, "gl847_send_slope_table (table_nr = %d, steps = %d)\n", table_nr, steps); - dpihw = dev->reg[reg_0x05].value >> 6; - - if (dpihw == 0) /* 600 dpi */ - start_address = 0x08000; - else if (dpihw == 1) /* 1200 dpi */ - start_address = 0x10000; - else if (dpihw == 2) /* 2400 dpi */ - start_address = 0x20000; - else /* reserved */ - return SANE_STATUS_INVAL; - table = (uint8_t *) malloc (steps * 2); for (i = 0; i < steps; i++) { @@ -941,25 +602,14 @@ gl847_send_slope_table (Genesys_Device * dev, int table_nr, table[i * 2 + 1] = slope_table[i] >> 8; } + /* slope table addresses ae fixed */ status = - sanei_genesys_set_buffer_address (dev, start_address + table_nr * 0x200); + write_ahb (dev->dn, 0x10000000 + 0x4000 * table_nr, steps * 2, table); if (status != SANE_STATUS_GOOD) { - free (table); DBG (DBG_error, - "gl847_send_slope_table: failed to set buffer address: %s\n", - sane_strstatus (status)); - return status; - } - - status = gl847_bulk_write_data (dev, 0x3c, (uint8_t *) table, steps * 2); - if (status != SANE_STATUS_GOOD) - { - free (table); - DBG (DBG_error, - "gl847_send_slope_table: failed to send slope table: %s\n", - sane_strstatus (status)); - return status; + "gl847_send_slope_table: write to AHB failed writing slope table %d (%s)\n", + table_nr, sane_strstatus (status)); } free (table); @@ -983,6 +633,15 @@ gl847_set_ad_fe (Genesys_Device * dev, uint8_t set) DBG (DBG_proc, "gl847_set_ad_fe(): setting DAC %u\n", dev->model->dac_type); + /* reset DAC */ + status = sanei_genesys_fe_write_data (dev, 0x00, 0x80); + if (status != SANE_STATUS_GOOD) + { + DBG (DBG_error, "gl847_set_ad_fe: failed to write reg0: %s\n", + sane_strstatus (status)); + return status; + } + /* sets to default values */ sanei_genesys_init_fe (dev); @@ -1031,18 +690,6 @@ gl847_set_ad_fe (Genesys_Device * dev, uint8_t set) } } } - /* - if (set == AFE_POWER_SAVE) - { - status = - sanei_genesys_fe_write_data (dev, 0x00, dev->frontend.reg[0] | 0x04); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "gl847_set_ad_fe: failed to write reg0: %s\n", - sane_strstatus (status)); - return status; - } - } */ DBG (DBG_proc, "gl847_set_ad_fe(): end\n"); return status; @@ -1760,18 +1407,7 @@ gl847_init_optical_regs_scan (Genesys_Device * dev, else dpiset = used_res; - if (dev->model->gpo_type == GPO_CANONLIDE200) - { -/* gpio part.*/ - r = sanei_genesys_get_address (reg, 0x6c); - if (half_ccd) - r->value &= ~0x80; - else - r->value |= 0x80; - } - /* enable shading */ -/* dev->reg[reg_0x01].value |= REG01_DVDSET | REG01_SCAN;*/ r = sanei_genesys_get_address (reg, 0x01); r->value |= REG01_SCAN; if ((flags & OPTICAL_FLAG_DISABLE_SHADING) || @@ -1781,8 +1417,7 @@ gl847_init_optical_regs_scan (Genesys_Device * dev, r->value |= REG01_DVDSET; /* average looks better than deletion, and we are already set up to - use one of the average enabled resolutions - */ + use one of the average enabled resolutions */ r = sanei_genesys_get_address (reg, 0x03); r->value |= REG03_AVEENB; if (flags & OPTICAL_FLAG_DISABLE_LAMP) @@ -1791,22 +1426,17 @@ gl847_init_optical_regs_scan (Genesys_Device * dev, r->value |= REG03_LAMPPWR; /* exposure times */ - r = sanei_genesys_get_address (reg, 0x10); for (i = 0; i < 6; i++, r++) { + r = sanei_genesys_get_address (reg, 0x10 + i); if (flags & OPTICAL_FLAG_DISABLE_LAMP) r->value = 0x01; /* 0x0101 is as off as possible */ - else if (dev->sensor.regs_0x10_0x1d[i] == 0x00) - r->value = 0x01; /*0x00 will not be accepted */ else r->value = dev->sensor.regs_0x10_0x1d[i]; } r = sanei_genesys_get_address (reg, 0x19); - if (flags & OPTICAL_FLAG_DISABLE_LAMP) - r->value = 0xff; - else - r->value = 0x50; + r->value = 0xff; /* BW threshold */ r = sanei_genesys_get_address (reg, 0x2e); @@ -1814,7 +1444,6 @@ gl847_init_optical_regs_scan (Genesys_Device * dev, r = sanei_genesys_get_address (reg, 0x2f); r->value = dev->settings.threshold; - /* monochrome / color scan */ r = sanei_genesys_get_address (reg, 0x04); switch (depth) @@ -1849,7 +1478,7 @@ gl847_init_optical_regs_scan (Genesys_Device * dev, } } else - r->value |= 0x10; /* color pixel by pixel */ + r->value |= 0x10; /* mono */ /* CIS scanners can do true gray by setting LEDADD */ if (dev->model->is_cis == SANE_TRUE) @@ -1871,10 +1500,7 @@ gl847_init_optical_regs_scan (Genesys_Device * dev, r->value |= REG05_GMMENB; /* sensor parameters */ - sanei_gl847_setup_sensor (dev, dev->reg, 1, half_ccd); - - r = sanei_genesys_get_address (reg, 0x29); - r->value = 255; /*<<<"magic" number, only suitable for cis */ + gl847_setup_sensor (dev, dev->reg); r = sanei_genesys_get_address (reg, 0x2c); r->value = HIBYTE (dpiset); @@ -1902,12 +1528,13 @@ gl847_init_optical_regs_scan (Genesys_Device * dev, dev->wpl = words_per_line; + /* MAXWD is expressed in 4 words unit */ r = sanei_genesys_get_address (reg, 0x35); - r->value = LOBYTE (HIWORD (words_per_line)); + r->value = LOBYTE (HIWORD (words_per_line >> 2)); r = sanei_genesys_get_address (reg, 0x36); - r->value = HIBYTE (LOWORD (words_per_line)); + r->value = HIBYTE (LOWORD (words_per_line >> 2)); r = sanei_genesys_get_address (reg, 0x37); - r->value = LOBYTE (LOWORD (words_per_line)); + r->value = LOBYTE (LOWORD (words_per_line >> 2)); r = sanei_genesys_get_address (reg, 0x38); r->value = HIBYTE (exposure_time); @@ -2055,7 +1682,7 @@ independent of our calculated values: /* used_res */ i = optical_res / xres; -/* gl847 supports 1/1 1/2 1/3 1/4 1/5 1/6 1/8 1/10 1/12 1/15 averaging */ +/* gl847 supports 1/2,1/3,1/4,1/5,1/6,1/8,1/10,1/12,1/15 */ if (i < 2 || (flags & SCAN_FLAG_USE_OPTICAL_RES)) /* optical_res >= xres > optical_res/2 */ used_res = optical_res; @@ -2682,85 +2309,7 @@ gl847_save_power (Genesys_Device * dev, SANE_Bool enable) uint8_t val; DBG (DBG_proc, "gl847_save_power: enable = %d\n", enable); - - if (enable) - { - if (dev->model->gpo_type == GPO_CANONLIDE200) - { -/* expect GPIO17 to be enabled, and GPIO9 to be disabled, - while GPIO8 is disabled*/ -/* final state: GPIO8 disabled, GPIO9 enabled, GPIO17 disabled, - GPIO18 disabled*/ - - sanei_genesys_read_register (dev, 0x6D, &val); - sanei_genesys_write_register (dev, 0x6D, val | 0x80); - - usleep (1000); - - /*enable GPIO9 */ - sanei_genesys_read_register (dev, 0x6C, &val); - sanei_genesys_write_register (dev, 0x6C, val | 0x01); - - /*disable GPO17 */ - sanei_genesys_read_register (dev, 0x6B, &val); - sanei_genesys_write_register (dev, 0x6B, val & ~REG6B_GPO17); - - /*disable GPO18 */ - sanei_genesys_read_register (dev, 0x6B, &val); - sanei_genesys_write_register (dev, 0x6B, val & ~REG6B_GPO18); - - usleep (1000); - - sanei_genesys_read_register (dev, 0x6D, &val); - sanei_genesys_write_register (dev, 0x6D, val & ~0x80); - - } - - gl847_set_fe (dev, AFE_POWER_SAVE); - - } - else - { - if (dev->model->gpo_type == GPO_CANONLIDE200) - { -/* expect GPIO17 to be enabled, and GPIO9 to be disabled, - while GPIO8 is disabled*/ -/* final state: GPIO8 enabled, GPIO9 disabled, GPIO17 enabled, - GPIO18 enabled*/ - - sanei_genesys_read_register (dev, 0x6D, &val); - sanei_genesys_write_register (dev, 0x6D, val | 0x80); - dev->reg[reg_0x6d].value |= 0x80; - dev->calib_reg[reg_0x6d].value |= 0x80; - - usleep (10000); - - /*disable GPIO9 */ - sanei_genesys_read_register (dev, 0x6C, &val); - sanei_genesys_write_register (dev, 0x6C, val & ~0x01); - dev->reg[reg_0x6c].value &= ~0x01; - dev->calib_reg[reg_0x6c].value &= ~0x01; - - /*enable GPIO10 */ - sanei_genesys_read_register (dev, 0x6C, &val); - sanei_genesys_write_register (dev, 0x6C, val | 0x02); - dev->reg[reg_0x6c].value |= 0x02; - dev->calib_reg[reg_0x6c].value |= 0x02; - - /*enable GPO17 */ - sanei_genesys_read_register (dev, 0x6B, &val); - sanei_genesys_write_register (dev, 0x6B, val | REG6B_GPO17); - dev->reg[reg_0x6b].value |= REG6B_GPO17; - dev->calib_reg[reg_0x6b].value |= REG6B_GPO17; - - /*enable GPO18 */ - sanei_genesys_read_register (dev, 0x6B, &val); - sanei_genesys_write_register (dev, 0x6B, val | REG6B_GPO18); - dev->reg[reg_0x6b].value |= REG6B_GPO18; - dev->calib_reg[reg_0x6b].value |= REG6B_GPO18; - - } - } + DBG (DBG_proc, "gl847_save_power: completed \n"); return SANE_STATUS_GOOD; } @@ -2768,7 +2317,7 @@ gl847_save_power (Genesys_Device * dev, SANE_Bool enable) static SANE_Status gl847_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ ) { - SANE_Status status=SANE_STATUS_GOOD; + SANE_Status status = SANE_STATUS_GOOD; DBG (DBG_proc, "gl847_set_powersaving (delay = %d)\n", delay); DBG (DBG_proc, "gl847_set_powersaving: completed\n"); @@ -3835,52 +3384,6 @@ gl847_init_regs_for_scan (Genesys_Device * dev) return SANE_STATUS_GOOD; } -/** - * writes a block of data to AHB - * @param dn USB device index - * @param addr AHB address to write to - * @param size size of the chunk of data - * @param data pointer to the data to write - */ -static SANE_Status -write_ahb (SANE_Int dn, uint32_t addr, uint32_t size, uint8_t * data) -{ - uint8_t outdata[8]; - size_t written; - SANE_Status status = SANE_STATUS_GOOD; - - outdata[0] = addr & 0xff; - outdata[1] = ((addr >> 8) & 0xff); - outdata[2] = ((addr >> 16) & 0xff); - outdata[3] = ((addr >> 24) & 0xff); - outdata[4] = (size & 0xff); - outdata[5] = ((size >> 8) & 0xff); - outdata[6] = ((size >> 16) & 0xff); - outdata[7] = ((size >> 24) & 0xff); - - /* write addr and size for AHB */ - status = - sanei_usb_control_msg (dn, REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, - 0x01, sizeof (outdata), outdata); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "write_ahb: failed while setting aadr and size: %s\n", - sane_strstatus (status)); - return status; - } - - /* write actual data */ - written = size; - status = sanei_usb_write_bulk (dn, data, &written); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "write_ahb: failed while writing bulk data: %s\n", - sane_strstatus (status)); - return status; - } - - return status; -} /** * This function sends generic gamma table (ie linear ones) @@ -3947,23 +3450,23 @@ gl847_send_gamma_table (Genesys_Device * dev, SANE_Bool generic) } } - /* loop sending gamma tables */ + /* loop sending gamma tables NOTE: 0x01000000 not 0x10000000 */ for (i = 0; i < 3; i++) { - status = write_ahb (dev->dn, 0x10000000+0x200 * i, size * 2, gamma + i * size * 2); + status = + write_ahb (dev->dn, 0x01000000 + 0x200 * i, size * 2, + gamma + i * size * 2); if (status != SANE_STATUS_GOOD) { - free (gamma); DBG (DBG_error, - "gl847_send_gamma_table: write to AHB failed writing table %d (%s)\n",i, - sane_strstatus (status)); - return status; + "gl847_send_gamma_table: write to AHB failed writing table %d (%s)\n", + i, sane_strstatus (status)); } } free (gamma); DBG (DBG_proc, "gl847_send_gamma_table: completed\n"); - return SANE_STATUS_GOOD; + return status; } /** @@ -4953,7 +4456,148 @@ gl847_is_compatible_calibration (Genesys_Device * dev, return SANE_STATUS_GOOD; } -/* +/** + * set up GPIO/GPOE + * TODO the hardcode values will be moved in a per device private + * description struct. + */ +static SANE_Status +gl847_init_gpio (Genesys_Device * dev) +{ + SANE_Status status = SANE_STATUS_GOOD; + uint8_t val, effective; + + DBG (DBG_proc, "gl847_init_gpio: start\n"); + SETREG (0x6e, dev->gpo.enable[0]); + SETREG (0x6f, dev->gpo.enable[1]); + SETREG (0xa7, 0x04); + SETREG (0xa8, 0x00); + RIE (sanei_genesys_write_register (dev, 0x6e, dev->reg[reg_0x6e].value)); + RIE (sanei_genesys_write_register (dev, 0x6f, dev->reg[reg_0x6f].value)); + RIE (sanei_genesys_write_register (dev, 0xa7, dev->reg[reg_0xa7].value)); + RIE (sanei_genesys_write_register (dev, 0xa8, dev->reg[reg_0xa8].value)); + + /* toggle needed bits one after all */ + /* TODO define a function for bit toggling */ + RIE (sanei_genesys_read_register (dev, 0x6c, &effective)); + val = effective | 0x80; + RIE (sanei_genesys_write_register (dev, 0x6c, val)); + RIE (sanei_genesys_read_register (dev, 0x6c, &effective)); + if (effective != val) + { + DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n", + effective, val); + } + val = effective | 0x40; + RIE (sanei_genesys_write_register (dev, 0x6c, val)); + RIE (sanei_genesys_read_register (dev, 0x6c, &effective)); + if (effective != val) + { + DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n", + effective, val); + } + val = effective | 0x20; + RIE (sanei_genesys_write_register (dev, 0x6c, val)); + /* seems useless : memory or clock related ? + genesys_read_register(0x0b)=0x29 + genesys_write_register(0x0b,0x29) + */ + RIE (sanei_genesys_read_register (dev, 0x6c, &effective)); + if (effective != val) + { + DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n", + effective, val); + } + val = effective | 0x02; + RIE (sanei_genesys_write_register (dev, 0x6c, val)); + RIE (sanei_genesys_read_register (dev, 0x6c, &effective)); + if (effective != val) + { + DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n", + effective, val); + } + val = effective | 0x01; + RIE (sanei_genesys_write_register (dev, 0x6c, val)); + RIE (sanei_genesys_read_register (dev, 0x6c, &effective)); + if (effective != val) + { + DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n", + effective, val); + } + SETREG (0x6c, val); + + DBG (DBG_proc, "gl847_init_gpio: completed\n"); + return status; +} + +/** + * set memory layout by filling values in dedicated registers + * TODO the hardcode values will be moved in a per device private + * description struct. + */ +static SANE_Status +gl847_init_memory_layout (Genesys_Device * dev) +{ + SANE_Status status = SANE_STATUS_GOOD; + + DBG (DBG_proc, "gl847_init_memory_layout\n"); + + /* setup base address for shading data. */ + /* values must be multiplied by 8192=0x4000 to give address on AHB */ + /* R-Channel shading bank0 address setting for CIS */ + SETREG (0xd0, 0x0a); + /* G-Channel shading bank0 address setting for CIS */ + SETREG (0xd1, 0x1f); + /* B-Channel shading bank0 address setting for CIS */ + SETREG (0xd2, 0x34); + + /* setup base address for scanned data. */ + /* values must be multiplied by 1024*2=0x0800 to give address on AHB */ + /* R-Channel ODD image buffer 0x0124->0x92000 */ + /* size for each buffer is 0x16d*1k word */ + SETREG (0xe0, 0x01); + SETREG (0xe1, 0x24); +/* R-Channel ODD image buffer end-address 0x0291->0x148800 => size=0xB6800*/ + SETREG (0xe2, 0x02); + SETREG (0xe3, 0x91); + + /* R-Channel EVEN image buffer 0x0292 */ + SETREG (0xe4, 0x02); + SETREG (0xe5, 0x92); +/* R-Channel EVEN image buffer end-address 0x03ff*/ + SETREG (0xe6, 0x03); + SETREG (0xe7, 0xff); + +/* same for green, since CIS, same addresses */ + SETREG (0xe8, 0x01); + SETREG (0xe9, 0x24); + SETREG (0xea, 0x02); + SETREG (0xeb, 0x91); + SETREG (0xec, 0x02); + SETREG (0xed, 0x92); + SETREG (0xee, 0x03); + SETREG (0xef, 0xff); + +/* same for blue, since CIS, same addresses */ + SETREG (0xf0, 0x01); + SETREG (0xf1, 0x24); + SETREG (0xf2, 0x02); + SETREG (0xf3, 0x91); + SETREG (0xf4, 0x02); + SETREG (0xf5, 0x92); + SETREG (0xf6, 0x03); + SETREG (0xf7, 0xff); + + /* only write modified registers */ + RIE (sanei_genesys_write_register (dev, 0xd0, dev->reg[reg_0xd0].value)); + RIE (sanei_genesys_write_register (dev, 0xd1, dev->reg[reg_0xd1].value)); + RIE (sanei_genesys_write_register (dev, 0xd2, dev->reg[reg_0xd2].value)); + + DBG (DBG_proc, "gl847_init_memory_layout completed\n"); + return status; +} + +/* * * initialize ASIC : registers, motor tables, and gamma tables * then ensure scanner's head is at home */ @@ -4982,6 +4626,14 @@ gl847_init (Genesys_Device * dev) return SANE_STATUS_GOOD; } + /* try to use CHKVER */ + RIE (sanei_genesys_read_register (dev, 0x40, &val)); + if (val & 0x10) + { + RIE (sanei_genesys_read_register (dev, 0x00, &val)); + DBG (DBG_info, "gl847_init: reported version is 0x%02x\n", val); + } + /* here either the backend or the scanner need to be initialized */ /* XXX STEF XXX FREEIFNOTNULL */ dev->dark_average_data = NULL; @@ -4989,7 +4641,7 @@ gl847_init (Genesys_Device * dev) dev->settings.color_filter = 0; /* ASIC reset */ - /* XXX STEF XXX pour 841 on fait juste write 0 */ + /* XXX STEF XXX just writes 0 for GL841 */ RIE (sanei_genesys_write_register (dev, 0x0e, 0x01)); sleep (1); RIE (sanei_genesys_write_register (dev, 0x0e, 0x00)); @@ -5006,29 +4658,49 @@ gl847_init (Genesys_Device * dev) RIE (gl847_bulk_write_register (dev, dev->reg, GENESYS_GL847_MAX_REGS)); /* Enable DRAM by setting a rising edge on bit 3 of reg 0x09 */ - val=dev->reg[reg_0x0b].value & REG0B_DRAMSEL; - val=(val | REG0B_ENBDRAM); + val = dev->reg[reg_0x0b].value & REG0B_DRAMSEL; + val = (val | REG0B_ENBDRAM); RIE (sanei_genesys_write_register (dev, 0x0b, val)); - dev->reg[reg_0x0b].value=val; + dev->reg[reg_0x0b].value = val; - /* read back GPIO TODO usefull ?*/ + /* read back GPIO TODO usefull ? */ sanei_genesys_read_register (dev, REG_GPIO17_21, &val); - if(val!=0x04) + if (val != 0x04) { - DBG (DBG_warn, "gl847_init: GPIO is 0x%02d instead of 0x04\n",val); + DBG (DBG_warn, "gl847_init: GPIO is 0x%02d instead of 0x04\n", val); } /* set up clock */ SETREG (0x77, 0x00); SETREG (0x78, 0x00); SETREG (0x79, 0x9f); - val=(dev->reg[reg_0x0b].value & ~REG0B_CLKSET) | REG0B_30MHZ; + RIE (sanei_genesys_write_register (dev, 0x77, dev->reg[reg_0x77].value)); + RIE (sanei_genesys_write_register (dev, 0x78, dev->reg[reg_0x78].value)); + RIE (sanei_genesys_write_register (dev, 0x79, dev->reg[reg_0x79].value)); + + /* CLKSET */ + val = (dev->reg[reg_0x0b].value & ~REG0B_CLKSET) | REG0B_30MHZ; RIE (sanei_genesys_write_register (dev, 0x0b, val)); - dev->reg[reg_0x0b].value=val; + dev->reg[reg_0x0b].value = val; + + /* CIS_LINE */ + SETREG (0x08, REG08_CIS_LINE); + RIE (sanei_genesys_write_register (dev, 0x08, dev->reg[reg_0x08].value)); /* end access ?? */ /* URB 109 control 0x40 0x0c 0x8c 0x10 len 1 wrote 0x0b URB 110 control 0x40 0x0c 0x8c 0x13 len 1 wrote 0x0e */ + RIE (write_end_access (dev, 0x10, 0x0b)); + RIE (write_end_access (dev, 0x13, 0x0e)); + + /* setup internal memory layout */ + RIE (gl847_init_gpio (dev)); + + /* setup internal memory layout */ + RIE (gl847_init_memory_layout (dev)); + + SETREG (0xf8, 0x01); + RIE (sanei_genesys_write_register (dev, 0xf8, dev->reg[reg_0xf8].value)); /* Set analog frontend */ RIE (gl847_set_fe (dev, AFE_INIT)); diff --git a/backend/genesys_gl847.h b/backend/genesys_gl847.h index 55ab8248a..f322352fb 100644 --- a/backend/genesys_gl847.h +++ b/backend/genesys_gl847.h @@ -112,13 +112,12 @@ #define REG07_DMASEL 0x02 #define REG07_DMARDWR 0x01 -#define REG08_DECFLAG 0x40 -#define REG08_GMMFFR 0x20 -#define REG08_GMMFFG 0x10 -#define REG08_GMMFFB 0x08 -#define REG08_GMMZR 0x04 -#define REG08_GMMZG 0x02 -#define REG08_GMMZB 0x01 +#define REG08_DRAM2X 0x80 +#define REG08_MPENB 0x20 +#define REG08_CIS_LINE 0x10 +#define REG08_IR1ENB 0x08 +#define REG08_IR2ENB 0x04 +#define REG08_ENB24M 0x01 #define REG09_MCNTSET 0xc0 #define REG09_CLKSET 0x30 diff --git a/backend/genesys_low.h b/backend/genesys_low.h index bf38ac391..a2ba01b56 100644 --- a/backend/genesys_low.h +++ b/backend/genesys_low.h @@ -123,6 +123,8 @@ #define GPIO_OUTPUT_ENABLE 0x89 #define GPIO_READ 0x8a #define GPIO_WRITE 0x8b +#define VALUE_BUF_ENDACCESS 0x8c +#define VALUE_GET_REGISTER 0x8e #define INDEX 0x00 /* todo: used? @@ -146,8 +148,8 @@ #define AFE_SET 2 #define AFE_POWER_SAVE 4 -#define LOWORD(x) ((uint16_t)(x & 0xffff)) -#define HIWORD(x) ((uint16_t)(x >> 16)) +#define LOWORD(x) ((uint16_t)((x) & 0xffff)) +#define HIWORD(x) ((uint16_t)((x) >> 16)) #define LOBYTE(x) ((uint8_t)((x) & 0xFF)) #define HIBYTE(x) ((uint8_t)((x) >> 8)) @@ -240,6 +242,9 @@ Genesys_Color_Order; #define GENESYS_GL646 646 #define GENESYS_GL841 841 +#define GENESYS_GL846 846 +#define GENESYS_GL847 847 +#define GENESYS_GL848 848 /*135 registers for gl841 + 1 null-reg*/ #define GENESYS_MAX_REGS 136 @@ -255,6 +260,7 @@ Genesys_Color_Order; #define DAC_WOLFSON_XP300 8 #define DAC_WOLFSON_HP3670 9 #define DAC_WOLFSON_DSM600 10 +#define DAC_CANONLIDE200 11 #define CCD_UMAX 0 #define CCD_ST12 1 /* SONY ILX548: 5340 Pixel ??? */ @@ -271,6 +277,7 @@ Genesys_Color_Order; #define CCD_DSMOBILE600 12 #define CCD_XP300 13 #define CCD_DP685 14 +#define CIS_CANONLIDE200 15 #define GPO_UMAX 0 #define GPO_ST12 1 @@ -284,6 +291,7 @@ Genesys_Color_Order; #define GPO_HP3670 9 #define GPO_DP665 10 #define GPO_DP685 11 +#define GPO_CANONLIDE200 12 #define MOTOR_UMAX 0 #define MOTOR_5345 1 @@ -297,6 +305,7 @@ Genesys_Color_Order; #define MOTOR_DP665 10 #define MOTOR_ROADWARRIOR 11 #define MOTOR_DSMOBILE_600 12 +#define MOTOR_CANONLIDE200 13 /* Forward typedefs */ @@ -416,6 +425,12 @@ typedef struct Genesys_Command_Set * move scanning head to transparency adapter */ SANE_Status (*move_to_ta) (Genesys_Device * dev); + + /** + * write shading data calibration to ASIC + */ + SANE_Status (*send_shading_data) (Genesys_Device * dev, uint8_t * data, int size); + } Genesys_Command_Set; typedef struct Genesys_Model @@ -769,5 +784,6 @@ sanei_genesys_buffer_consume(Genesys_Buffer * buf, size_t size); /*---------------------------------------------------------------------------*/ extern SANE_Status sanei_gl646_init_cmd_set (Genesys_Device * dev); extern SANE_Status sanei_gl841_init_cmd_set (Genesys_Device * dev); +extern SANE_Status sanei_gl847_init_cmd_set (Genesys_Device * dev); #endif /* not GENESYS_LOW_H */