1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci Copyright (C) 2000-2003 Jochen Eisinger <jochen.eisinger@gmx.net> 3141cc406Sopenharmony_ci This file is part of the SANE package. 4141cc406Sopenharmony_ci 5141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 6141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 7141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 8141cc406Sopenharmony_ci License, or (at your option) any later version. 9141cc406Sopenharmony_ci 10141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 11141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 12141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13141cc406Sopenharmony_ci General Public License for more details. 14141cc406Sopenharmony_ci 15141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 16141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 17141cc406Sopenharmony_ci 18141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 19141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 20141cc406Sopenharmony_ci 21141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 22141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 23141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 24141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 25141cc406Sopenharmony_ci account of linking the SANE library code into it. 26141cc406Sopenharmony_ci 27141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 28141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 29141cc406Sopenharmony_ci License. 30141cc406Sopenharmony_ci 31141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 32141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 33141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 34141cc406Sopenharmony_ci 35141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 36141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 37141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 38141cc406Sopenharmony_ci 39141cc406Sopenharmony_ci This file implements the hardware driver scanners using a 300dpi CCD */ 40141cc406Sopenharmony_ci 41141cc406Sopenharmony_ci#include "mustek_pp_ccd300.h" 42141cc406Sopenharmony_ci 43141cc406Sopenharmony_ci#define MUSTEK_PP_CCD300 4 44141cc406Sopenharmony_ci 45141cc406Sopenharmony_cistatic void config_ccd_101x (Mustek_pp_Handle * dev); 46141cc406Sopenharmony_cistatic void config_ccd (Mustek_pp_Handle * dev); 47141cc406Sopenharmony_cistatic void lamp (Mustek_pp_Handle * dev, int lamp_on); 48141cc406Sopenharmony_ci 49141cc406Sopenharmony_ci#define CCD300_ASIC1013 0xa8 50141cc406Sopenharmony_ci#define CCD300_ASIC1015 0xa5 51141cc406Sopenharmony_ci 52141cc406Sopenharmony_ci#define CCD300_CHANNEL_RED 0 53141cc406Sopenharmony_ci#define CCD300_CHANNEL_GREEN 1 54141cc406Sopenharmony_ci#define CCD300_CHANNEL_BLUE 2 55141cc406Sopenharmony_ci#define CCD300_CHANNEL_GRAY 1 56141cc406Sopenharmony_ci 57141cc406Sopenharmony_ci#define CCD300_MAXHSIZE 2600 58141cc406Sopenharmony_ci#define CCD300_MAXVSIZE 3500 59141cc406Sopenharmony_ci 60141cc406Sopenharmony_ci/* 61141cc406Sopenharmony_ci * Here starts the driver code for the different chipsets 62141cc406Sopenharmony_ci * 63141cc406Sopenharmony_ci * The 1013 & 1015 chipsets share large portions of the code. This 64141cc406Sopenharmony_ci * shared functions end with _101x. 65141cc406Sopenharmony_ci */ 66141cc406Sopenharmony_ci 67141cc406Sopenharmony_cistatic const u_char chan_codes_1013[] = { 0x82, 0x42, 0xC2 }; 68141cc406Sopenharmony_cistatic const u_char chan_codes_1015[] = { 0x80, 0x40, 0xC0 }; 69141cc406Sopenharmony_cistatic const u_char fullstep[] = { 0x09, 0x0C, 0x06, 0x03 }; 70141cc406Sopenharmony_cistatic const u_char halfstep[] = { 0x02, 0x03, 0x01, 0x09, 71141cc406Sopenharmony_ci 0x08, 0x0C, 0x04, 0x06 72141cc406Sopenharmony_ci}; 73141cc406Sopenharmony_cistatic const u_char voltages[4][3] = { {0x5C, 0x5A, 0x63}, 74141cc406Sopenharmony_ci{0xE6, 0xB4, 0xBE}, 75141cc406Sopenharmony_ci{0xB4, 0xB4, 0xB4}, 76141cc406Sopenharmony_ci{0x64, 0x50, 0x64} 77141cc406Sopenharmony_ci}; 78141cc406Sopenharmony_ci 79141cc406Sopenharmony_ci/* Forward declarations of 1013/1015 functions */ 80141cc406Sopenharmony_cistatic void set_ccd_channel_1013 (Mustek_pp_Handle * dev, int channel); 81141cc406Sopenharmony_cistatic void motor_backward_1013 (Mustek_pp_Handle * dev); 82141cc406Sopenharmony_cistatic void return_home_1013 (Mustek_pp_Handle * dev); 83141cc406Sopenharmony_cistatic void motor_forward_1013 (Mustek_pp_Handle * dev); 84141cc406Sopenharmony_cistatic void config_ccd_1013 (Mustek_pp_Handle * dev); 85141cc406Sopenharmony_ci 86141cc406Sopenharmony_cistatic void set_ccd_channel_1015 (Mustek_pp_Handle * dev, int channel); 87141cc406Sopenharmony_ci/* static void motor_backward_1015 (Mustek_pp_Handle * dev); */ 88141cc406Sopenharmony_cistatic void return_home_1015 (Mustek_pp_Handle * dev, SANE_Bool nowait); 89141cc406Sopenharmony_cistatic void motor_forward_1015 (Mustek_pp_Handle * dev); 90141cc406Sopenharmony_cistatic void config_ccd_1015 (Mustek_pp_Handle * dev); 91141cc406Sopenharmony_ci 92141cc406Sopenharmony_ci 93141cc406Sopenharmony_ci/* These functions are common to all 1013/1015 chipsets */ 94141cc406Sopenharmony_ci 95141cc406Sopenharmony_cistatic void 96141cc406Sopenharmony_ciset_led (Mustek_pp_Handle * dev) 97141cc406Sopenharmony_ci{ 98141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 99141cc406Sopenharmony_ci 100141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 101141cc406Sopenharmony_ci (priv->motor_step % 5 == 0 ? 0x03 : 0x13)); 102141cc406Sopenharmony_ci 103141cc406Sopenharmony_ci} 104141cc406Sopenharmony_ci 105141cc406Sopenharmony_cistatic void 106141cc406Sopenharmony_ciset_sti (Mustek_pp_Handle * dev) 107141cc406Sopenharmony_ci{ 108141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 109141cc406Sopenharmony_ci 110141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 3, 0); 111141cc406Sopenharmony_ci priv->bank_count++; 112141cc406Sopenharmony_ci priv->bank_count &= 7; 113141cc406Sopenharmony_ci 114141cc406Sopenharmony_ci} 115141cc406Sopenharmony_ci 116141cc406Sopenharmony_cistatic void 117141cc406Sopenharmony_ciget_bank_count (Mustek_pp_Handle * dev) 118141cc406Sopenharmony_ci{ 119141cc406Sopenharmony_ci u_char val; 120141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 121141cc406Sopenharmony_ci 122141cc406Sopenharmony_ci sanei_pa4s2_readbegin (dev->fd, 3); 123141cc406Sopenharmony_ci sanei_pa4s2_readbyte (dev->fd, &val); 124141cc406Sopenharmony_ci sanei_pa4s2_readend (dev->fd); 125141cc406Sopenharmony_ci 126141cc406Sopenharmony_ci priv->bank_count = (val & 0x07); 127141cc406Sopenharmony_ci 128141cc406Sopenharmony_ci} 129141cc406Sopenharmony_ci 130141cc406Sopenharmony_cistatic void 131141cc406Sopenharmony_cireset_bank_count (Mustek_pp_Handle * dev) 132141cc406Sopenharmony_ci{ 133141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 7); 134141cc406Sopenharmony_ci} 135141cc406Sopenharmony_ci 136141cc406Sopenharmony_cistatic void 137141cc406Sopenharmony_ciwait_bank_change (Mustek_pp_Handle * dev, int bankcount, int niceload) 138141cc406Sopenharmony_ci{ 139141cc406Sopenharmony_ci struct timeval start, end; 140141cc406Sopenharmony_ci unsigned long diff; 141141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 142141cc406Sopenharmony_ci int first_time = 1; 143141cc406Sopenharmony_ci 144141cc406Sopenharmony_ci gettimeofday (&start, NULL); 145141cc406Sopenharmony_ci 146141cc406Sopenharmony_ci do 147141cc406Sopenharmony_ci { 148141cc406Sopenharmony_ci if ((niceload == 0) && (first_time == 0)) 149141cc406Sopenharmony_ci { 150141cc406Sopenharmony_ci usleep (1); /* could be as well sched_yield */ 151141cc406Sopenharmony_ci first_time = 0; 152141cc406Sopenharmony_ci } 153141cc406Sopenharmony_ci get_bank_count (dev); 154141cc406Sopenharmony_ci 155141cc406Sopenharmony_ci gettimeofday (&end, NULL); 156141cc406Sopenharmony_ci diff = (end.tv_sec * 1000 + end.tv_usec / 1000) - 157141cc406Sopenharmony_ci (start.tv_sec * 1000 + start.tv_usec / 1000); 158141cc406Sopenharmony_ci 159141cc406Sopenharmony_ci } 160141cc406Sopenharmony_ci while ((priv->bank_count != bankcount) && (diff < priv->wait_bank)); 161141cc406Sopenharmony_ci 162141cc406Sopenharmony_ci} 163141cc406Sopenharmony_ci 164141cc406Sopenharmony_cistatic void 165141cc406Sopenharmony_ciset_dpi_value (Mustek_pp_Handle * dev) 166141cc406Sopenharmony_ci{ 167141cc406Sopenharmony_ci u_char val = 0; 168141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 169141cc406Sopenharmony_ci 170141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x80); 171141cc406Sopenharmony_ci 172141cc406Sopenharmony_ci switch (priv->hwres) 173141cc406Sopenharmony_ci { 174141cc406Sopenharmony_ci case 100: 175141cc406Sopenharmony_ci val = 0x00; 176141cc406Sopenharmony_ci break; 177141cc406Sopenharmony_ci case 200: 178141cc406Sopenharmony_ci val = 0x10; 179141cc406Sopenharmony_ci break; 180141cc406Sopenharmony_ci case 300: 181141cc406Sopenharmony_ci val = 0x20; 182141cc406Sopenharmony_ci break; 183141cc406Sopenharmony_ci } 184141cc406Sopenharmony_ci 185141cc406Sopenharmony_ci 186141cc406Sopenharmony_ci if (priv->ccd_type == 1) 187141cc406Sopenharmony_ci val |= 0x01; 188141cc406Sopenharmony_ci 189141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, val); 190141cc406Sopenharmony_ci 191141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x00); 192141cc406Sopenharmony_ci 193141cc406Sopenharmony_ci DBG (5, "set_dpi_value: value 0x%02x\n", val); 194141cc406Sopenharmony_ci 195141cc406Sopenharmony_ci} 196141cc406Sopenharmony_ci 197141cc406Sopenharmony_cistatic void 198141cc406Sopenharmony_ciset_line_adjust (Mustek_pp_Handle * dev) 199141cc406Sopenharmony_ci{ 200141cc406Sopenharmony_ci int adjustline; 201141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 202141cc406Sopenharmony_ci 203141cc406Sopenharmony_ci adjustline = (dev->bottomX - dev->topX) * priv->hwres / 300; 204141cc406Sopenharmony_ci priv->adjustskip = priv->adjustskip * priv->hwres / 300; 205141cc406Sopenharmony_ci 206141cc406Sopenharmony_ci DBG (5, "set_line_adjust: ppl %u (%u), adjust %u, skip %u\n", 207141cc406Sopenharmony_ci dev->params.pixels_per_line, (dev->bottomX - dev->topX), adjustline, 208141cc406Sopenharmony_ci priv->adjustskip); 209141cc406Sopenharmony_ci 210141cc406Sopenharmony_ci 211141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x11); 212141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, (adjustline + priv->adjustskip) >> 8); 213141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x21); 214141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, (adjustline + priv->adjustskip) & 0xFF); 215141cc406Sopenharmony_ci 216141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x01); 217141cc406Sopenharmony_ci 218141cc406Sopenharmony_ci} 219141cc406Sopenharmony_ci 220141cc406Sopenharmony_cistatic void 221141cc406Sopenharmony_ciset_lamp (Mustek_pp_Handle * dev, int lamp_on) 222141cc406Sopenharmony_ci{ 223141cc406Sopenharmony_ci 224141cc406Sopenharmony_ci int ctr; 225141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 226141cc406Sopenharmony_ci 227141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0xC3); 228141cc406Sopenharmony_ci 229141cc406Sopenharmony_ci for (ctr = 0; ctr < 3; ctr++) 230141cc406Sopenharmony_ci { 231141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, (lamp_on ? 0x47 : 0x57)); 232141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x77); 233141cc406Sopenharmony_ci } 234141cc406Sopenharmony_ci 235141cc406Sopenharmony_ci priv->motor_step = lamp_on; 236141cc406Sopenharmony_ci 237141cc406Sopenharmony_ci set_led (dev); 238141cc406Sopenharmony_ci 239141cc406Sopenharmony_ci} 240141cc406Sopenharmony_ci 241141cc406Sopenharmony_cistatic void 242141cc406Sopenharmony_cisend_voltages (Mustek_pp_Handle * dev) 243141cc406Sopenharmony_ci{ 244141cc406Sopenharmony_ci 245141cc406Sopenharmony_ci int voltage, sel = 8, ctr; 246141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 247141cc406Sopenharmony_ci 248141cc406Sopenharmony_ci switch (priv->ccd_type) 249141cc406Sopenharmony_ci { 250141cc406Sopenharmony_ci case 0: 251141cc406Sopenharmony_ci voltage = 0; 252141cc406Sopenharmony_ci break; 253141cc406Sopenharmony_ci case 1: 254141cc406Sopenharmony_ci voltage = 1; 255141cc406Sopenharmony_ci break; 256141cc406Sopenharmony_ci default: 257141cc406Sopenharmony_ci voltage = 2; 258141cc406Sopenharmony_ci break; 259141cc406Sopenharmony_ci } 260141cc406Sopenharmony_ci 261141cc406Sopenharmony_ci for (ctr = 0; ctr < 3; ctr++) 262141cc406Sopenharmony_ci { 263141cc406Sopenharmony_ci 264141cc406Sopenharmony_ci sel <<= 1; 265141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, sel); 266141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, voltages[voltage][ctr]); 267141cc406Sopenharmony_ci 268141cc406Sopenharmony_ci } 269141cc406Sopenharmony_ci 270141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x00); 271141cc406Sopenharmony_ci 272141cc406Sopenharmony_ci} 273141cc406Sopenharmony_ci 274141cc406Sopenharmony_cistatic int 275141cc406Sopenharmony_cicompar (const void *a, const void *b) 276141cc406Sopenharmony_ci{ 277141cc406Sopenharmony_ci return (signed int) (*(const SANE_Byte *) a) - 278141cc406Sopenharmony_ci (signed int) (*(const SANE_Byte *) b); 279141cc406Sopenharmony_ci} 280141cc406Sopenharmony_ci 281141cc406Sopenharmony_cistatic void 282141cc406Sopenharmony_ciset_ccd_channel_101x (Mustek_pp_Handle * dev, int channel) 283141cc406Sopenharmony_ci{ 284141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 285141cc406Sopenharmony_ci switch (priv->asic) 286141cc406Sopenharmony_ci { 287141cc406Sopenharmony_ci case CCD300_ASIC1013: 288141cc406Sopenharmony_ci set_ccd_channel_1013 (dev, channel); 289141cc406Sopenharmony_ci break; 290141cc406Sopenharmony_ci 291141cc406Sopenharmony_ci case CCD300_ASIC1015: 292141cc406Sopenharmony_ci set_ccd_channel_1015 (dev, channel); 293141cc406Sopenharmony_ci break; 294141cc406Sopenharmony_ci } 295141cc406Sopenharmony_ci} 296141cc406Sopenharmony_ci 297141cc406Sopenharmony_cistatic void 298141cc406Sopenharmony_cimotor_forward_101x (Mustek_pp_Handle * dev) 299141cc406Sopenharmony_ci{ 300141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 301141cc406Sopenharmony_ci switch (priv->asic) 302141cc406Sopenharmony_ci { 303141cc406Sopenharmony_ci case CCD300_ASIC1013: 304141cc406Sopenharmony_ci motor_forward_1013 (dev); 305141cc406Sopenharmony_ci break; 306141cc406Sopenharmony_ci 307141cc406Sopenharmony_ci case CCD300_ASIC1015: 308141cc406Sopenharmony_ci motor_forward_1015 (dev); 309141cc406Sopenharmony_ci break; 310141cc406Sopenharmony_ci } 311141cc406Sopenharmony_ci} 312141cc406Sopenharmony_ci 313141cc406Sopenharmony_cistatic void 314141cc406Sopenharmony_cimotor_backward_101x (Mustek_pp_Handle * dev) 315141cc406Sopenharmony_ci{ 316141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 317141cc406Sopenharmony_ci switch (priv->asic) 318141cc406Sopenharmony_ci { 319141cc406Sopenharmony_ci case CCD300_ASIC1013: 320141cc406Sopenharmony_ci motor_backward_1013 (dev); 321141cc406Sopenharmony_ci break; 322141cc406Sopenharmony_ci 323141cc406Sopenharmony_ci case CCD300_ASIC1015: 324141cc406Sopenharmony_ci/* motor_backward_1015 (dev); */ 325141cc406Sopenharmony_ci break; 326141cc406Sopenharmony_ci } 327141cc406Sopenharmony_ci} 328141cc406Sopenharmony_ci 329141cc406Sopenharmony_cistatic void 330141cc406Sopenharmony_cimove_motor_101x (Mustek_pp_Handle * dev, int forward) 331141cc406Sopenharmony_ci{ 332141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 333141cc406Sopenharmony_ci if (forward == SANE_TRUE) 334141cc406Sopenharmony_ci motor_forward_101x (dev); 335141cc406Sopenharmony_ci else 336141cc406Sopenharmony_ci motor_backward_101x (dev); 337141cc406Sopenharmony_ci 338141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 339141cc406Sopenharmony_ci reset_bank_count (dev); 340141cc406Sopenharmony_ci} 341141cc406Sopenharmony_ci 342141cc406Sopenharmony_ci 343141cc406Sopenharmony_cistatic void 344141cc406Sopenharmony_ciconfig_ccd_101x (Mustek_pp_Handle * dev) 345141cc406Sopenharmony_ci{ 346141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 347141cc406Sopenharmony_ci switch (priv->asic) 348141cc406Sopenharmony_ci { 349141cc406Sopenharmony_ci case CCD300_ASIC1013: 350141cc406Sopenharmony_ci config_ccd_1013 (dev); 351141cc406Sopenharmony_ci break; 352141cc406Sopenharmony_ci 353141cc406Sopenharmony_ci case CCD300_ASIC1015: 354141cc406Sopenharmony_ci config_ccd_1015 (dev); 355141cc406Sopenharmony_ci break; 356141cc406Sopenharmony_ci } 357141cc406Sopenharmony_ci} 358141cc406Sopenharmony_ci 359141cc406Sopenharmony_ci 360141cc406Sopenharmony_ci 361141cc406Sopenharmony_cistatic void 362141cc406Sopenharmony_ciread_line_101x (Mustek_pp_Handle * dev, SANE_Byte * buf, SANE_Int pixel, 363141cc406Sopenharmony_ci SANE_Int RefBlack, SANE_Byte * calib, SANE_Int * gamma) 364141cc406Sopenharmony_ci{ 365141cc406Sopenharmony_ci 366141cc406Sopenharmony_ci SANE_Byte *cal = calib; 367141cc406Sopenharmony_ci u_char color; 368141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 369141cc406Sopenharmony_ci int ctr, skips = priv->adjustskip + 1, cval; 370141cc406Sopenharmony_ci 371141cc406Sopenharmony_ci if (pixel <= 0) 372141cc406Sopenharmony_ci return; 373141cc406Sopenharmony_ci 374141cc406Sopenharmony_ci sanei_pa4s2_readbegin (dev->fd, 1); 375141cc406Sopenharmony_ci 376141cc406Sopenharmony_ci 377141cc406Sopenharmony_ci if (priv->hwres == dev->res) 378141cc406Sopenharmony_ci { 379141cc406Sopenharmony_ci 380141cc406Sopenharmony_ci while (skips--) 381141cc406Sopenharmony_ci sanei_pa4s2_readbyte (dev->fd, &color); 382141cc406Sopenharmony_ci 383141cc406Sopenharmony_ci for (ctr = 0; ctr < pixel; ctr++) 384141cc406Sopenharmony_ci { 385141cc406Sopenharmony_ci 386141cc406Sopenharmony_ci sanei_pa4s2_readbyte (dev->fd, &color); 387141cc406Sopenharmony_ci 388141cc406Sopenharmony_ci cval = color; 389141cc406Sopenharmony_ci 390141cc406Sopenharmony_ci if (cval < RefBlack) 391141cc406Sopenharmony_ci cval = 0; 392141cc406Sopenharmony_ci else 393141cc406Sopenharmony_ci cval -= RefBlack; 394141cc406Sopenharmony_ci 395141cc406Sopenharmony_ci if (cal) 396141cc406Sopenharmony_ci { 397141cc406Sopenharmony_ci if (cval >= cal[ctr]) 398141cc406Sopenharmony_ci cval = 0xFF; 399141cc406Sopenharmony_ci else 400141cc406Sopenharmony_ci { 401141cc406Sopenharmony_ci cval <<= 8; 402141cc406Sopenharmony_ci cval /= (int) cal[ctr]; 403141cc406Sopenharmony_ci } 404141cc406Sopenharmony_ci } 405141cc406Sopenharmony_ci 406141cc406Sopenharmony_ci if (gamma) 407141cc406Sopenharmony_ci cval = gamma[cval]; 408141cc406Sopenharmony_ci 409141cc406Sopenharmony_ci buf[ctr] = cval; 410141cc406Sopenharmony_ci 411141cc406Sopenharmony_ci } 412141cc406Sopenharmony_ci 413141cc406Sopenharmony_ci } 414141cc406Sopenharmony_ci else 415141cc406Sopenharmony_ci { 416141cc406Sopenharmony_ci 417141cc406Sopenharmony_ci int pos = 0, bpos = 0; 418141cc406Sopenharmony_ci 419141cc406Sopenharmony_ci while (skips--) 420141cc406Sopenharmony_ci sanei_pa4s2_readbyte (dev->fd, &color); 421141cc406Sopenharmony_ci 422141cc406Sopenharmony_ci ctr = 0; 423141cc406Sopenharmony_ci 424141cc406Sopenharmony_ci do 425141cc406Sopenharmony_ci { 426141cc406Sopenharmony_ci 427141cc406Sopenharmony_ci sanei_pa4s2_readbyte (dev->fd, &color); 428141cc406Sopenharmony_ci 429141cc406Sopenharmony_ci cval = color; 430141cc406Sopenharmony_ci 431141cc406Sopenharmony_ci if (ctr < (pos >> SANE_FIXED_SCALE_SHIFT)) 432141cc406Sopenharmony_ci { 433141cc406Sopenharmony_ci ctr++; 434141cc406Sopenharmony_ci continue; 435141cc406Sopenharmony_ci } 436141cc406Sopenharmony_ci 437141cc406Sopenharmony_ci ctr++; 438141cc406Sopenharmony_ci pos += priv->res_step; 439141cc406Sopenharmony_ci 440141cc406Sopenharmony_ci 441141cc406Sopenharmony_ci if (cval < RefBlack) 442141cc406Sopenharmony_ci cval = 0; 443141cc406Sopenharmony_ci else 444141cc406Sopenharmony_ci cval -= RefBlack; 445141cc406Sopenharmony_ci 446141cc406Sopenharmony_ci if (cal) 447141cc406Sopenharmony_ci { 448141cc406Sopenharmony_ci if (cval >= cal[bpos]) 449141cc406Sopenharmony_ci cval = 0xFF; 450141cc406Sopenharmony_ci else 451141cc406Sopenharmony_ci { 452141cc406Sopenharmony_ci cval <<= 8; 453141cc406Sopenharmony_ci cval /= (int) cal[bpos]; 454141cc406Sopenharmony_ci } 455141cc406Sopenharmony_ci } 456141cc406Sopenharmony_ci 457141cc406Sopenharmony_ci if (gamma) 458141cc406Sopenharmony_ci cval = gamma[cval]; 459141cc406Sopenharmony_ci 460141cc406Sopenharmony_ci buf[bpos++] = cval; 461141cc406Sopenharmony_ci 462141cc406Sopenharmony_ci } 463141cc406Sopenharmony_ci while (bpos < pixel); 464141cc406Sopenharmony_ci 465141cc406Sopenharmony_ci } 466141cc406Sopenharmony_ci 467141cc406Sopenharmony_ci sanei_pa4s2_readend (dev->fd); 468141cc406Sopenharmony_ci 469141cc406Sopenharmony_ci} 470141cc406Sopenharmony_ci 471141cc406Sopenharmony_cistatic void 472141cc406Sopenharmony_ciread_average_line_101x (Mustek_pp_Handle * dev, SANE_Byte * buf, int pixel, 473141cc406Sopenharmony_ci int RefBlack) 474141cc406Sopenharmony_ci{ 475141cc406Sopenharmony_ci 476141cc406Sopenharmony_ci SANE_Byte lbuf[4][CCD300_MAXHSIZE * 2]; 477141cc406Sopenharmony_ci int ctr, sum; 478141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 479141cc406Sopenharmony_ci 480141cc406Sopenharmony_ci for (ctr = 0; ctr < 4; ctr++) 481141cc406Sopenharmony_ci { 482141cc406Sopenharmony_ci 483141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 484141cc406Sopenharmony_ci read_line_101x (dev, lbuf[ctr], pixel, RefBlack, NULL, NULL); 485141cc406Sopenharmony_ci reset_bank_count (dev); 486141cc406Sopenharmony_ci if (ctr < 3) 487141cc406Sopenharmony_ci set_sti (dev); 488141cc406Sopenharmony_ci 489141cc406Sopenharmony_ci } 490141cc406Sopenharmony_ci 491141cc406Sopenharmony_ci for (ctr = 0; ctr < pixel; ctr++) 492141cc406Sopenharmony_ci { 493141cc406Sopenharmony_ci 494141cc406Sopenharmony_ci sum = lbuf[0][ctr] + lbuf[1][ctr] + lbuf[2][ctr] + lbuf[3][ctr]; 495141cc406Sopenharmony_ci 496141cc406Sopenharmony_ci buf[ctr] = (sum / 4); 497141cc406Sopenharmony_ci 498141cc406Sopenharmony_ci } 499141cc406Sopenharmony_ci 500141cc406Sopenharmony_ci} 501141cc406Sopenharmony_ci 502141cc406Sopenharmony_cistatic void 503141cc406Sopenharmony_cifind_black_side_edge_101x (Mustek_pp_Handle * dev) 504141cc406Sopenharmony_ci{ 505141cc406Sopenharmony_ci SANE_Byte buf[CCD300_MAXHSIZE * 2]; 506141cc406Sopenharmony_ci SANE_Byte blackposition[5]; 507141cc406Sopenharmony_ci int pos = 0, ctr, blackpos; 508141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 509141cc406Sopenharmony_ci 510141cc406Sopenharmony_ci 511141cc406Sopenharmony_ci for (ctr = 0; ctr < 20; ctr++) 512141cc406Sopenharmony_ci { 513141cc406Sopenharmony_ci 514141cc406Sopenharmony_ci motor_forward_101x (dev); 515141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 516141cc406Sopenharmony_ci read_line_101x (dev, buf, CCD300_MAXHSIZE, 0, NULL, NULL); 517141cc406Sopenharmony_ci reset_bank_count (dev); 518141cc406Sopenharmony_ci 519141cc406Sopenharmony_ci priv->ref_black = priv->ref_red = priv->ref_green = priv->ref_blue = 520141cc406Sopenharmony_ci buf[0]; 521141cc406Sopenharmony_ci 522141cc406Sopenharmony_ci blackpos = CCD300_MAXHSIZE / 4; 523141cc406Sopenharmony_ci 524141cc406Sopenharmony_ci while ((abs (buf[blackpos] - buf[0]) >= 15) && (blackpos > 0)) 525141cc406Sopenharmony_ci blackpos--; 526141cc406Sopenharmony_ci 527141cc406Sopenharmony_ci if (blackpos > 1) 528141cc406Sopenharmony_ci blackposition[pos++] = blackpos; 529141cc406Sopenharmony_ci 530141cc406Sopenharmony_ci if (pos == 5) 531141cc406Sopenharmony_ci break; 532141cc406Sopenharmony_ci 533141cc406Sopenharmony_ci } 534141cc406Sopenharmony_ci 535141cc406Sopenharmony_ci blackpos = 0; 536141cc406Sopenharmony_ci 537141cc406Sopenharmony_ci for (ctr = 0; ctr < pos; ctr++) 538141cc406Sopenharmony_ci if (blackposition[ctr] > blackpos) 539141cc406Sopenharmony_ci blackpos = blackposition[ctr]; 540141cc406Sopenharmony_ci 541141cc406Sopenharmony_ci if (blackpos < 0x66) 542141cc406Sopenharmony_ci blackpos = 0x6A; 543141cc406Sopenharmony_ci 544141cc406Sopenharmony_ci priv->blackpos = blackpos; 545141cc406Sopenharmony_ci priv->saved_skipcount = (blackpos + 12) & 0xFF; 546141cc406Sopenharmony_ci 547141cc406Sopenharmony_ci} 548141cc406Sopenharmony_ci 549141cc406Sopenharmony_cistatic void 550141cc406Sopenharmony_cimin_color_levels_101x (Mustek_pp_Handle * dev) 551141cc406Sopenharmony_ci{ 552141cc406Sopenharmony_ci 553141cc406Sopenharmony_ci SANE_Byte buf[CCD300_MAXHSIZE * 2]; 554141cc406Sopenharmony_ci int ctr, sum = 0; 555141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 556141cc406Sopenharmony_ci 557141cc406Sopenharmony_ci for (ctr = 0; ctr < 8; ctr++) 558141cc406Sopenharmony_ci { 559141cc406Sopenharmony_ci 560141cc406Sopenharmony_ci set_ccd_channel_101x (dev, CCD300_CHANNEL_RED); 561141cc406Sopenharmony_ci set_sti (dev); 562141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 563141cc406Sopenharmony_ci 564141cc406Sopenharmony_ci read_line_101x (dev, buf, CCD300_MAXHSIZE, 0, NULL, NULL); 565141cc406Sopenharmony_ci 566141cc406Sopenharmony_ci reset_bank_count (dev); 567141cc406Sopenharmony_ci 568141cc406Sopenharmony_ci sum += buf[3]; 569141cc406Sopenharmony_ci 570141cc406Sopenharmony_ci } 571141cc406Sopenharmony_ci 572141cc406Sopenharmony_ci priv->ref_red = sum / 8; 573141cc406Sopenharmony_ci 574141cc406Sopenharmony_ci sum = 0; 575141cc406Sopenharmony_ci 576141cc406Sopenharmony_ci for (ctr = 0; ctr < 8; ctr++) 577141cc406Sopenharmony_ci { 578141cc406Sopenharmony_ci 579141cc406Sopenharmony_ci set_ccd_channel_101x (dev, CCD300_CHANNEL_GREEN); 580141cc406Sopenharmony_ci set_sti (dev); 581141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 582141cc406Sopenharmony_ci 583141cc406Sopenharmony_ci read_line_101x (dev, buf, CCD300_MAXHSIZE, 0, NULL, NULL); 584141cc406Sopenharmony_ci 585141cc406Sopenharmony_ci reset_bank_count (dev); 586141cc406Sopenharmony_ci 587141cc406Sopenharmony_ci sum += buf[3]; 588141cc406Sopenharmony_ci 589141cc406Sopenharmony_ci } 590141cc406Sopenharmony_ci 591141cc406Sopenharmony_ci priv->ref_green = sum / 8; 592141cc406Sopenharmony_ci 593141cc406Sopenharmony_ci sum = 0; 594141cc406Sopenharmony_ci 595141cc406Sopenharmony_ci for (ctr = 0; ctr < 8; ctr++) 596141cc406Sopenharmony_ci { 597141cc406Sopenharmony_ci 598141cc406Sopenharmony_ci set_ccd_channel_101x (dev, CCD300_CHANNEL_BLUE); 599141cc406Sopenharmony_ci set_sti (dev); 600141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 601141cc406Sopenharmony_ci 602141cc406Sopenharmony_ci read_line_101x (dev, buf, CCD300_MAXHSIZE, 0, NULL, NULL); 603141cc406Sopenharmony_ci 604141cc406Sopenharmony_ci reset_bank_count (dev); 605141cc406Sopenharmony_ci 606141cc406Sopenharmony_ci sum += buf[3]; 607141cc406Sopenharmony_ci 608141cc406Sopenharmony_ci } 609141cc406Sopenharmony_ci 610141cc406Sopenharmony_ci priv->ref_blue = sum / 8; 611141cc406Sopenharmony_ci 612141cc406Sopenharmony_ci} 613141cc406Sopenharmony_ci 614141cc406Sopenharmony_ci 615141cc406Sopenharmony_cistatic void 616141cc406Sopenharmony_cimax_color_levels_101x (Mustek_pp_Handle * dev) 617141cc406Sopenharmony_ci{ 618141cc406Sopenharmony_ci 619141cc406Sopenharmony_ci int ctr, line, sum; 620141cc406Sopenharmony_ci SANE_Byte rbuf[32][CCD300_MAXHSIZE * 2]; 621141cc406Sopenharmony_ci SANE_Byte gbuf[32][CCD300_MAXHSIZE * 2]; 622141cc406Sopenharmony_ci SANE_Byte bbuf[32][CCD300_MAXHSIZE * 2]; 623141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 624141cc406Sopenharmony_ci 625141cc406Sopenharmony_ci SANE_Byte maxbuf[32]; 626141cc406Sopenharmony_ci 627141cc406Sopenharmony_ci for (ctr = 0; ctr < 32; ctr++) 628141cc406Sopenharmony_ci { 629141cc406Sopenharmony_ci 630141cc406Sopenharmony_ci if (dev->mode == MODE_COLOR) 631141cc406Sopenharmony_ci { 632141cc406Sopenharmony_ci 633141cc406Sopenharmony_ci set_ccd_channel_101x (dev, CCD300_CHANNEL_RED); 634141cc406Sopenharmony_ci motor_forward_101x (dev); 635141cc406Sopenharmony_ci 636141cc406Sopenharmony_ci read_average_line_101x (dev, rbuf[ctr], dev->params.pixels_per_line, 637141cc406Sopenharmony_ci priv->ref_red); 638141cc406Sopenharmony_ci 639141cc406Sopenharmony_ci set_ccd_channel_101x (dev, CCD300_CHANNEL_GREEN); 640141cc406Sopenharmony_ci set_sti (dev); 641141cc406Sopenharmony_ci 642141cc406Sopenharmony_ci read_average_line_101x (dev, gbuf[ctr], dev->params.pixels_per_line, 643141cc406Sopenharmony_ci priv->ref_green); 644141cc406Sopenharmony_ci 645141cc406Sopenharmony_ci set_ccd_channel_101x (dev, CCD300_CHANNEL_BLUE); 646141cc406Sopenharmony_ci set_sti (dev); 647141cc406Sopenharmony_ci 648141cc406Sopenharmony_ci read_average_line_101x (dev, bbuf[ctr], dev->params.pixels_per_line, 649141cc406Sopenharmony_ci priv->ref_blue); 650141cc406Sopenharmony_ci 651141cc406Sopenharmony_ci } 652141cc406Sopenharmony_ci else 653141cc406Sopenharmony_ci { 654141cc406Sopenharmony_ci 655141cc406Sopenharmony_ci priv->channel = CCD300_CHANNEL_GRAY; 656141cc406Sopenharmony_ci 657141cc406Sopenharmony_ci motor_forward_101x (dev); 658141cc406Sopenharmony_ci 659141cc406Sopenharmony_ci read_average_line_101x (dev, gbuf[ctr], dev->params.pixels_per_line, 660141cc406Sopenharmony_ci priv->ref_black); 661141cc406Sopenharmony_ci 662141cc406Sopenharmony_ci } 663141cc406Sopenharmony_ci 664141cc406Sopenharmony_ci } 665141cc406Sopenharmony_ci 666141cc406Sopenharmony_ci 667141cc406Sopenharmony_ci for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++) 668141cc406Sopenharmony_ci { 669141cc406Sopenharmony_ci for (line = 0; line < 32; line++) 670141cc406Sopenharmony_ci maxbuf[line] = gbuf[line][ctr]; 671141cc406Sopenharmony_ci 672141cc406Sopenharmony_ci qsort (maxbuf, 32, sizeof (maxbuf[0]), compar); 673141cc406Sopenharmony_ci 674141cc406Sopenharmony_ci sum = maxbuf[4] + maxbuf[5] + maxbuf[6] + maxbuf[7]; 675141cc406Sopenharmony_ci 676141cc406Sopenharmony_ci priv->calib_g[ctr] = sum / 4; 677141cc406Sopenharmony_ci 678141cc406Sopenharmony_ci } 679141cc406Sopenharmony_ci 680141cc406Sopenharmony_ci if (dev->mode == MODE_COLOR) 681141cc406Sopenharmony_ci { 682141cc406Sopenharmony_ci 683141cc406Sopenharmony_ci for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++) 684141cc406Sopenharmony_ci { 685141cc406Sopenharmony_ci for (line = 0; line < 32; line++) 686141cc406Sopenharmony_ci maxbuf[line] = rbuf[line][ctr]; 687141cc406Sopenharmony_ci 688141cc406Sopenharmony_ci qsort (maxbuf, 32, sizeof (maxbuf[0]), compar); 689141cc406Sopenharmony_ci 690141cc406Sopenharmony_ci sum = maxbuf[4] + maxbuf[5] + maxbuf[6] + maxbuf[7]; 691141cc406Sopenharmony_ci 692141cc406Sopenharmony_ci priv->calib_r[ctr] = sum / 4; 693141cc406Sopenharmony_ci 694141cc406Sopenharmony_ci } 695141cc406Sopenharmony_ci 696141cc406Sopenharmony_ci for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++) 697141cc406Sopenharmony_ci { 698141cc406Sopenharmony_ci for (line = 0; line < 32; line++) 699141cc406Sopenharmony_ci maxbuf[line] = bbuf[line][ctr]; 700141cc406Sopenharmony_ci 701141cc406Sopenharmony_ci qsort (maxbuf, 32, sizeof (maxbuf[0]), compar); 702141cc406Sopenharmony_ci 703141cc406Sopenharmony_ci sum = maxbuf[4] + maxbuf[5] + maxbuf[6] + maxbuf[7]; 704141cc406Sopenharmony_ci 705141cc406Sopenharmony_ci priv->calib_b[ctr] = sum / 4; 706141cc406Sopenharmony_ci 707141cc406Sopenharmony_ci } 708141cc406Sopenharmony_ci 709141cc406Sopenharmony_ci } 710141cc406Sopenharmony_ci 711141cc406Sopenharmony_ci} 712141cc406Sopenharmony_ci 713141cc406Sopenharmony_cistatic void 714141cc406Sopenharmony_cifind_black_top_edge_101x (Mustek_pp_Handle * dev) 715141cc406Sopenharmony_ci{ 716141cc406Sopenharmony_ci 717141cc406Sopenharmony_ci int lines = 0, ctr, pos; 718141cc406Sopenharmony_ci SANE_Byte buf[CCD300_MAXHSIZE * 2]; 719141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 720141cc406Sopenharmony_ci 721141cc406Sopenharmony_ci priv->channel = CCD300_CHANNEL_GRAY; 722141cc406Sopenharmony_ci 723141cc406Sopenharmony_ci do 724141cc406Sopenharmony_ci { 725141cc406Sopenharmony_ci 726141cc406Sopenharmony_ci motor_forward_101x (dev); 727141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 728141cc406Sopenharmony_ci 729141cc406Sopenharmony_ci read_line_101x (dev, buf, CCD300_MAXHSIZE, priv->ref_black, NULL, NULL); 730141cc406Sopenharmony_ci 731141cc406Sopenharmony_ci reset_bank_count (dev); 732141cc406Sopenharmony_ci 733141cc406Sopenharmony_ci pos = 0; 734141cc406Sopenharmony_ci 735141cc406Sopenharmony_ci for (ctr = priv->blackpos; ctr > priv->blackpos - 10; ctr--) 736141cc406Sopenharmony_ci if (buf[ctr] <= 15) 737141cc406Sopenharmony_ci pos++; 738141cc406Sopenharmony_ci 739141cc406Sopenharmony_ci } 740141cc406Sopenharmony_ci while ((pos >= 8) && (lines++ < 67)); 741141cc406Sopenharmony_ci 742141cc406Sopenharmony_ci} 743141cc406Sopenharmony_ci 744141cc406Sopenharmony_cistatic void 745141cc406Sopenharmony_cicalibrate_device_101x (Mustek_pp_Handle * dev) 746141cc406Sopenharmony_ci{ 747141cc406Sopenharmony_ci 748141cc406Sopenharmony_ci int saved_ppl = dev->params.pixels_per_line, ctr; 749141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 750141cc406Sopenharmony_ci 751141cc406Sopenharmony_ci priv->saved_mode = dev->mode; 752141cc406Sopenharmony_ci priv->saved_invert = dev->invert; 753141cc406Sopenharmony_ci priv->saved_skipcount = priv->skipcount; 754141cc406Sopenharmony_ci priv->saved_skipimagebyte = priv->skipimagebytes; 755141cc406Sopenharmony_ci priv->saved_adjustskip = priv->adjustskip; 756141cc406Sopenharmony_ci priv->saved_res = dev->res; 757141cc406Sopenharmony_ci priv->saved_hwres = priv->hwres; 758141cc406Sopenharmony_ci priv->saved_res_step = priv->res_step; 759141cc406Sopenharmony_ci priv->saved_line_step = priv->line_step; 760141cc406Sopenharmony_ci priv->saved_channel = priv->channel; 761141cc406Sopenharmony_ci 762141cc406Sopenharmony_ci dev->params.pixels_per_line = CCD300_MAXHSIZE; 763141cc406Sopenharmony_ci priv->hwres = dev->res = 300; 764141cc406Sopenharmony_ci dev->mode = MODE_GRAYSCALE; 765141cc406Sopenharmony_ci priv->skipcount = priv->skipimagebytes = 0; 766141cc406Sopenharmony_ci dev->invert = SANE_FALSE; 767141cc406Sopenharmony_ci priv->channel = CCD300_CHANNEL_GRAY; 768141cc406Sopenharmony_ci 769141cc406Sopenharmony_ci config_ccd_101x (dev); 770141cc406Sopenharmony_ci get_bank_count (dev); 771141cc406Sopenharmony_ci 772141cc406Sopenharmony_ci find_black_side_edge_101x (dev); 773141cc406Sopenharmony_ci 774141cc406Sopenharmony_ci for (ctr = 0; ctr < 4; ctr++) 775141cc406Sopenharmony_ci move_motor_101x (dev, SANE_TRUE); 776141cc406Sopenharmony_ci 777141cc406Sopenharmony_ci dev->mode = priv->saved_mode; 778141cc406Sopenharmony_ci dev->invert = priv->saved_invert; 779141cc406Sopenharmony_ci priv->skipcount = priv->saved_skipcount; 780141cc406Sopenharmony_ci priv->skipimagebytes = priv->saved_skipimagebyte; 781141cc406Sopenharmony_ci priv->adjustskip = priv->saved_adjustskip; 782141cc406Sopenharmony_ci dev->res = priv->saved_res; 783141cc406Sopenharmony_ci priv->hwres = priv->saved_hwres; 784141cc406Sopenharmony_ci priv->res_step = priv->saved_res_step; 785141cc406Sopenharmony_ci priv->line_step = priv->saved_line_step; 786141cc406Sopenharmony_ci priv->channel = priv->saved_channel; 787141cc406Sopenharmony_ci 788141cc406Sopenharmony_ci priv->hwres = dev->res = 300; 789141cc406Sopenharmony_ci priv->skipcount = priv->skipimagebytes = 0; 790141cc406Sopenharmony_ci dev->invert = SANE_FALSE; 791141cc406Sopenharmony_ci 792141cc406Sopenharmony_ci config_ccd_101x (dev); 793141cc406Sopenharmony_ci get_bank_count (dev); 794141cc406Sopenharmony_ci 795141cc406Sopenharmony_ci if ((dev->mode == MODE_COLOR) && (priv->ccd_type != 0)) 796141cc406Sopenharmony_ci min_color_levels_101x (dev); 797141cc406Sopenharmony_ci 798141cc406Sopenharmony_ci dev->mode = priv->saved_mode; 799141cc406Sopenharmony_ci dev->invert = priv->saved_invert; 800141cc406Sopenharmony_ci priv->skipcount = priv->saved_skipcount; 801141cc406Sopenharmony_ci priv->skipimagebytes = priv->saved_skipimagebyte; 802141cc406Sopenharmony_ci priv->adjustskip = priv->saved_adjustskip; 803141cc406Sopenharmony_ci dev->res = priv->saved_res; 804141cc406Sopenharmony_ci priv->hwres = priv->saved_hwres; 805141cc406Sopenharmony_ci priv->res_step = priv->saved_res_step; 806141cc406Sopenharmony_ci priv->line_step = priv->saved_line_step; 807141cc406Sopenharmony_ci priv->channel = priv->saved_channel; 808141cc406Sopenharmony_ci 809141cc406Sopenharmony_ci dev->params.pixels_per_line = saved_ppl; 810141cc406Sopenharmony_ci dev->invert = SANE_FALSE; 811141cc406Sopenharmony_ci 812141cc406Sopenharmony_ci config_ccd_101x (dev); 813141cc406Sopenharmony_ci get_bank_count (dev); 814141cc406Sopenharmony_ci 815141cc406Sopenharmony_ci max_color_levels_101x (dev); 816141cc406Sopenharmony_ci 817141cc406Sopenharmony_ci dev->params.pixels_per_line = CCD300_MAXHSIZE; 818141cc406Sopenharmony_ci dev->mode = MODE_GRAYSCALE; 819141cc406Sopenharmony_ci priv->hwres = dev->res = 300; 820141cc406Sopenharmony_ci priv->skipcount = priv->skipimagebytes = 0; 821141cc406Sopenharmony_ci dev->invert = SANE_FALSE; 822141cc406Sopenharmony_ci 823141cc406Sopenharmony_ci config_ccd_101x (dev); 824141cc406Sopenharmony_ci get_bank_count (dev); 825141cc406Sopenharmony_ci 826141cc406Sopenharmony_ci find_black_top_edge_101x (dev); 827141cc406Sopenharmony_ci 828141cc406Sopenharmony_ci dev->mode = priv->saved_mode; 829141cc406Sopenharmony_ci dev->invert = priv->saved_invert; 830141cc406Sopenharmony_ci priv->skipcount = priv->saved_skipcount; 831141cc406Sopenharmony_ci priv->skipimagebytes = priv->saved_skipimagebyte; 832141cc406Sopenharmony_ci priv->adjustskip = priv->saved_adjustskip; 833141cc406Sopenharmony_ci dev->res = priv->saved_res; 834141cc406Sopenharmony_ci priv->hwres = priv->saved_hwres; 835141cc406Sopenharmony_ci priv->res_step = priv->saved_res_step; 836141cc406Sopenharmony_ci priv->line_step = priv->saved_line_step; 837141cc406Sopenharmony_ci priv->channel = priv->saved_channel; 838141cc406Sopenharmony_ci 839141cc406Sopenharmony_ci dev->params.pixels_per_line = saved_ppl; 840141cc406Sopenharmony_ci 841141cc406Sopenharmony_ci config_ccd_101x (dev); 842141cc406Sopenharmony_ci get_bank_count (dev); 843141cc406Sopenharmony_ci 844141cc406Sopenharmony_ci} 845141cc406Sopenharmony_ci 846141cc406Sopenharmony_cistatic void 847141cc406Sopenharmony_ciget_grayscale_line_101x (Mustek_pp_Handle * dev, SANE_Byte * buf) 848141cc406Sopenharmony_ci{ 849141cc406Sopenharmony_ci 850141cc406Sopenharmony_ci int skips; 851141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 852141cc406Sopenharmony_ci 853141cc406Sopenharmony_ci priv->line_diff += SANE_FIX (300.0 / (float) dev->res); 854141cc406Sopenharmony_ci 855141cc406Sopenharmony_ci skips = (priv->line_diff >> SANE_FIXED_SCALE_SHIFT); 856141cc406Sopenharmony_ci 857141cc406Sopenharmony_ci while (--skips) 858141cc406Sopenharmony_ci { 859141cc406Sopenharmony_ci motor_forward_101x (dev); 860141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 861141cc406Sopenharmony_ci reset_bank_count (dev); 862141cc406Sopenharmony_ci } 863141cc406Sopenharmony_ci 864141cc406Sopenharmony_ci priv->line_diff &= 0xFFFF; 865141cc406Sopenharmony_ci 866141cc406Sopenharmony_ci motor_forward_101x (dev); 867141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 868141cc406Sopenharmony_ci 869141cc406Sopenharmony_ci read_line_101x (dev, buf, dev->params.pixels_per_line, priv->ref_black, 870141cc406Sopenharmony_ci priv->calib_g, NULL); 871141cc406Sopenharmony_ci 872141cc406Sopenharmony_ci reset_bank_count (dev); 873141cc406Sopenharmony_ci 874141cc406Sopenharmony_ci} 875141cc406Sopenharmony_ci 876141cc406Sopenharmony_cistatic void 877141cc406Sopenharmony_ciget_lineart_line_101x (Mustek_pp_Handle * dev, SANE_Byte * buf) 878141cc406Sopenharmony_ci{ 879141cc406Sopenharmony_ci 880141cc406Sopenharmony_ci int ctr; 881141cc406Sopenharmony_ci SANE_Byte gbuf[CCD300_MAXHSIZE * 2]; 882141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 883141cc406Sopenharmony_ci 884141cc406Sopenharmony_ci get_grayscale_line_101x (dev, gbuf); 885141cc406Sopenharmony_ci 886141cc406Sopenharmony_ci memset (buf, 0xFF, dev->params.bytes_per_line); 887141cc406Sopenharmony_ci 888141cc406Sopenharmony_ci for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++) 889141cc406Sopenharmony_ci buf[ctr >> 3] ^= ((gbuf[ctr] > priv->bw) ? (1 << (7 - ctr % 8)) : 0); 890141cc406Sopenharmony_ci 891141cc406Sopenharmony_ci} 892141cc406Sopenharmony_ci 893141cc406Sopenharmony_cistatic void 894141cc406Sopenharmony_ciget_color_line_101x (Mustek_pp_Handle * dev, SANE_Byte * buf) 895141cc406Sopenharmony_ci{ 896141cc406Sopenharmony_ci 897141cc406Sopenharmony_ci SANE_Byte *red, *blue, *src, *dest; 898141cc406Sopenharmony_ci int gotline = 0, ctr; 899141cc406Sopenharmony_ci int gored, goblue, gogreen; 900141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 901141cc406Sopenharmony_ci int step = priv->line_step; 902141cc406Sopenharmony_ci 903141cc406Sopenharmony_ci do 904141cc406Sopenharmony_ci { 905141cc406Sopenharmony_ci 906141cc406Sopenharmony_ci red = priv->red[priv->redline]; 907141cc406Sopenharmony_ci blue = priv->blue[priv->blueline]; 908141cc406Sopenharmony_ci 909141cc406Sopenharmony_ci priv->ccd_line++; 910141cc406Sopenharmony_ci 911141cc406Sopenharmony_ci if ((priv->rdiff >> SANE_FIXED_SCALE_SHIFT) == priv->ccd_line) 912141cc406Sopenharmony_ci { 913141cc406Sopenharmony_ci gored = 1; 914141cc406Sopenharmony_ci priv->rdiff += step; 915141cc406Sopenharmony_ci } 916141cc406Sopenharmony_ci else 917141cc406Sopenharmony_ci gored = 0; 918141cc406Sopenharmony_ci 919141cc406Sopenharmony_ci if ((priv->bdiff >> SANE_FIXED_SCALE_SHIFT) == priv->ccd_line) 920141cc406Sopenharmony_ci { 921141cc406Sopenharmony_ci goblue = 1; 922141cc406Sopenharmony_ci priv->bdiff += step; 923141cc406Sopenharmony_ci } 924141cc406Sopenharmony_ci else 925141cc406Sopenharmony_ci goblue = 0; 926141cc406Sopenharmony_ci 927141cc406Sopenharmony_ci if ((priv->gdiff >> SANE_FIXED_SCALE_SHIFT) == priv->ccd_line) 928141cc406Sopenharmony_ci { 929141cc406Sopenharmony_ci gogreen = 1; 930141cc406Sopenharmony_ci priv->gdiff += step; 931141cc406Sopenharmony_ci } 932141cc406Sopenharmony_ci else 933141cc406Sopenharmony_ci gogreen = 0; 934141cc406Sopenharmony_ci 935141cc406Sopenharmony_ci if (!gored && !goblue && !gogreen) 936141cc406Sopenharmony_ci { 937141cc406Sopenharmony_ci motor_forward_101x (dev); 938141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 939141cc406Sopenharmony_ci reset_bank_count (dev); 940141cc406Sopenharmony_ci if (priv->ccd_line >= (priv->line_step >> SANE_FIXED_SCALE_SHIFT)) 941141cc406Sopenharmony_ci priv->redline = (priv->redline + 1) % priv->green_offs; 942141cc406Sopenharmony_ci if (priv->ccd_line >= 943141cc406Sopenharmony_ci priv->blue_offs + (priv->line_step >> SANE_FIXED_SCALE_SHIFT)) 944141cc406Sopenharmony_ci priv->blueline = (priv->blueline + 1) % priv->blue_offs; 945141cc406Sopenharmony_ci continue; 946141cc406Sopenharmony_ci } 947141cc406Sopenharmony_ci 948141cc406Sopenharmony_ci if (gored) 949141cc406Sopenharmony_ci priv->channel = CCD300_CHANNEL_RED; 950141cc406Sopenharmony_ci else if (goblue) 951141cc406Sopenharmony_ci priv->channel = CCD300_CHANNEL_BLUE; 952141cc406Sopenharmony_ci else 953141cc406Sopenharmony_ci priv->channel = CCD300_CHANNEL_GREEN; 954141cc406Sopenharmony_ci 955141cc406Sopenharmony_ci motor_forward_101x (dev); 956141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 957141cc406Sopenharmony_ci 958141cc406Sopenharmony_ci if (priv->ccd_line >= priv->green_offs && gogreen) 959141cc406Sopenharmony_ci { 960141cc406Sopenharmony_ci src = red; 961141cc406Sopenharmony_ci dest = buf; 962141cc406Sopenharmony_ci 963141cc406Sopenharmony_ci for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++) 964141cc406Sopenharmony_ci { 965141cc406Sopenharmony_ci *dest = *src++; 966141cc406Sopenharmony_ci dest += 3; 967141cc406Sopenharmony_ci } 968141cc406Sopenharmony_ci } 969141cc406Sopenharmony_ci 970141cc406Sopenharmony_ci if (gored) 971141cc406Sopenharmony_ci { 972141cc406Sopenharmony_ci 973141cc406Sopenharmony_ci read_line_101x (dev, red, dev->params.pixels_per_line, 974141cc406Sopenharmony_ci priv->ref_red, priv->calib_r, NULL); 975141cc406Sopenharmony_ci 976141cc406Sopenharmony_ci reset_bank_count (dev); 977141cc406Sopenharmony_ci 978141cc406Sopenharmony_ci } 979141cc406Sopenharmony_ci 980141cc406Sopenharmony_ci priv->redline = (priv->redline + 1) % priv->green_offs; 981141cc406Sopenharmony_ci 982141cc406Sopenharmony_ci if (priv->ccd_line >= priv->green_offs && gogreen) 983141cc406Sopenharmony_ci { 984141cc406Sopenharmony_ci src = blue; 985141cc406Sopenharmony_ci dest = buf + 2; 986141cc406Sopenharmony_ci 987141cc406Sopenharmony_ci 988141cc406Sopenharmony_ci for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++) 989141cc406Sopenharmony_ci { 990141cc406Sopenharmony_ci *dest = *src++; 991141cc406Sopenharmony_ci dest += 3; 992141cc406Sopenharmony_ci } 993141cc406Sopenharmony_ci 994141cc406Sopenharmony_ci } 995141cc406Sopenharmony_ci 996141cc406Sopenharmony_ci if (goblue) 997141cc406Sopenharmony_ci { 998141cc406Sopenharmony_ci if (gored) 999141cc406Sopenharmony_ci { 1000141cc406Sopenharmony_ci set_ccd_channel_101x (dev, CCD300_CHANNEL_BLUE); 1001141cc406Sopenharmony_ci set_sti (dev); 1002141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 1003141cc406Sopenharmony_ci } 1004141cc406Sopenharmony_ci 1005141cc406Sopenharmony_ci read_line_101x (dev, blue, dev->params.pixels_per_line, 1006141cc406Sopenharmony_ci priv->ref_blue, priv->calib_b, NULL); 1007141cc406Sopenharmony_ci 1008141cc406Sopenharmony_ci reset_bank_count (dev); 1009141cc406Sopenharmony_ci 1010141cc406Sopenharmony_ci } 1011141cc406Sopenharmony_ci 1012141cc406Sopenharmony_ci if (priv->ccd_line >= 1013141cc406Sopenharmony_ci priv->blue_offs + (priv->line_step >> SANE_FIXED_SCALE_SHIFT)) 1014141cc406Sopenharmony_ci priv->blueline = (priv->blueline + 1) % priv->blue_offs; 1015141cc406Sopenharmony_ci 1016141cc406Sopenharmony_ci if (gogreen) 1017141cc406Sopenharmony_ci { 1018141cc406Sopenharmony_ci 1019141cc406Sopenharmony_ci if (gored || goblue) 1020141cc406Sopenharmony_ci { 1021141cc406Sopenharmony_ci set_ccd_channel_101x (dev, CCD300_CHANNEL_GREEN); 1022141cc406Sopenharmony_ci set_sti (dev); 1023141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 1); 1024141cc406Sopenharmony_ci } 1025141cc406Sopenharmony_ci 1026141cc406Sopenharmony_ci read_line_101x (dev, priv->green, dev->params.pixels_per_line, 1027141cc406Sopenharmony_ci priv->ref_green, priv->calib_g, NULL); 1028141cc406Sopenharmony_ci 1029141cc406Sopenharmony_ci reset_bank_count (dev); 1030141cc406Sopenharmony_ci 1031141cc406Sopenharmony_ci src = priv->green; 1032141cc406Sopenharmony_ci dest = buf + 1; 1033141cc406Sopenharmony_ci 1034141cc406Sopenharmony_ci for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++) 1035141cc406Sopenharmony_ci { 1036141cc406Sopenharmony_ci *dest = *src++; 1037141cc406Sopenharmony_ci dest += 3; 1038141cc406Sopenharmony_ci } 1039141cc406Sopenharmony_ci 1040141cc406Sopenharmony_ci gotline = 1; 1041141cc406Sopenharmony_ci } 1042141cc406Sopenharmony_ci 1043141cc406Sopenharmony_ci } 1044141cc406Sopenharmony_ci while (!gotline); 1045141cc406Sopenharmony_ci 1046141cc406Sopenharmony_ci} 1047141cc406Sopenharmony_ci 1048141cc406Sopenharmony_ci 1049141cc406Sopenharmony_ci 1050141cc406Sopenharmony_ci/* these functions are for the 1013 chipset */ 1051141cc406Sopenharmony_ci 1052141cc406Sopenharmony_cistatic void 1053141cc406Sopenharmony_ciset_ccd_channel_1013 (Mustek_pp_Handle * dev, int channel) 1054141cc406Sopenharmony_ci{ 1055141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1056141cc406Sopenharmony_ci priv->channel = channel; 1057141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, chan_codes_1013[channel]); 1058141cc406Sopenharmony_ci} 1059141cc406Sopenharmony_ci 1060141cc406Sopenharmony_cistatic void 1061141cc406Sopenharmony_cimotor_backward_1013 (Mustek_pp_Handle * dev) 1062141cc406Sopenharmony_ci{ 1063141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1064141cc406Sopenharmony_ci 1065141cc406Sopenharmony_ci priv->motor_step++; 1066141cc406Sopenharmony_ci set_led (dev); 1067141cc406Sopenharmony_ci 1068141cc406Sopenharmony_ci if (priv->motor_phase > 3) 1069141cc406Sopenharmony_ci priv->motor_phase = 3; 1070141cc406Sopenharmony_ci 1071141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x62); 1072141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, fullstep[priv->motor_phase]); 1073141cc406Sopenharmony_ci 1074141cc406Sopenharmony_ci priv->motor_phase = (priv->motor_phase == 0 ? 3 : priv->motor_phase - 1); 1075141cc406Sopenharmony_ci 1076141cc406Sopenharmony_ci set_ccd_channel_1013 (dev, priv->channel); 1077141cc406Sopenharmony_ci set_sti (dev); 1078141cc406Sopenharmony_ci 1079141cc406Sopenharmony_ci} 1080141cc406Sopenharmony_ci 1081141cc406Sopenharmony_cistatic void 1082141cc406Sopenharmony_cireturn_home_1013 (Mustek_pp_Handle * dev) 1083141cc406Sopenharmony_ci{ 1084141cc406Sopenharmony_ci u_char ishome; 1085141cc406Sopenharmony_ci int ctr; 1086141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1087141cc406Sopenharmony_ci 1088141cc406Sopenharmony_ci /* 1013 can't return home all alone, nowait ignored */ 1089141cc406Sopenharmony_ci 1090141cc406Sopenharmony_ci for (ctr = 0; ctr < 4500; ctr++) 1091141cc406Sopenharmony_ci { 1092141cc406Sopenharmony_ci 1093141cc406Sopenharmony_ci /* check_is_home_1013 */ 1094141cc406Sopenharmony_ci sanei_pa4s2_readbegin (dev->fd, 2); 1095141cc406Sopenharmony_ci sanei_pa4s2_readbyte (dev->fd, &ishome); 1096141cc406Sopenharmony_ci sanei_pa4s2_readend (dev->fd); 1097141cc406Sopenharmony_ci 1098141cc406Sopenharmony_ci /* yes, it should be is_not_home */ 1099141cc406Sopenharmony_ci if ((ishome & 1) == 0) 1100141cc406Sopenharmony_ci break; 1101141cc406Sopenharmony_ci 1102141cc406Sopenharmony_ci motor_backward_1013 (dev); 1103141cc406Sopenharmony_ci wait_bank_change (dev, priv->bank_count, 0); 1104141cc406Sopenharmony_ci reset_bank_count (dev); 1105141cc406Sopenharmony_ci 1106141cc406Sopenharmony_ci } 1107141cc406Sopenharmony_ci 1108141cc406Sopenharmony_ci} 1109141cc406Sopenharmony_ci 1110141cc406Sopenharmony_cistatic void 1111141cc406Sopenharmony_cimotor_forward_1013 (Mustek_pp_Handle * dev) 1112141cc406Sopenharmony_ci{ 1113141cc406Sopenharmony_ci 1114141cc406Sopenharmony_ci int ctr; 1115141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1116141cc406Sopenharmony_ci 1117141cc406Sopenharmony_ci priv->motor_step++; 1118141cc406Sopenharmony_ci set_led (dev); 1119141cc406Sopenharmony_ci 1120141cc406Sopenharmony_ci for (ctr = 0; ctr < 2; ctr++) 1121141cc406Sopenharmony_ci { 1122141cc406Sopenharmony_ci 1123141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x62); 1124141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, halfstep[priv->motor_phase]); 1125141cc406Sopenharmony_ci 1126141cc406Sopenharmony_ci priv->motor_phase = 1127141cc406Sopenharmony_ci (priv->motor_phase == 7 ? 0 : priv->motor_phase + 1); 1128141cc406Sopenharmony_ci 1129141cc406Sopenharmony_ci } 1130141cc406Sopenharmony_ci 1131141cc406Sopenharmony_ci set_ccd_channel_1013 (dev, priv->channel); 1132141cc406Sopenharmony_ci set_sti (dev); 1133141cc406Sopenharmony_ci} 1134141cc406Sopenharmony_ci 1135141cc406Sopenharmony_ci 1136141cc406Sopenharmony_ci 1137141cc406Sopenharmony_cistatic void 1138141cc406Sopenharmony_ciconfig_ccd_1013 (Mustek_pp_Handle * dev) 1139141cc406Sopenharmony_ci{ 1140141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1141141cc406Sopenharmony_ci 1142141cc406Sopenharmony_ci if (dev->res != 0) 1143141cc406Sopenharmony_ci priv->res_step = SANE_FIX ((float) priv->hwres / (float) dev->res); 1144141cc406Sopenharmony_ci 1145141cc406Sopenharmony_ci set_dpi_value (dev); 1146141cc406Sopenharmony_ci 1147141cc406Sopenharmony_ci /* set_start_channel_1013 (dev); */ 1148141cc406Sopenharmony_ci 1149141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x05); 1150141cc406Sopenharmony_ci 1151141cc406Sopenharmony_ci switch (dev->mode) 1152141cc406Sopenharmony_ci { 1153141cc406Sopenharmony_ci case MODE_BW: 1154141cc406Sopenharmony_ci case MODE_GRAYSCALE: 1155141cc406Sopenharmony_ci priv->channel = CCD300_CHANNEL_GRAY; 1156141cc406Sopenharmony_ci break; 1157141cc406Sopenharmony_ci 1158141cc406Sopenharmony_ci case MODE_COLOR: 1159141cc406Sopenharmony_ci priv->channel = CCD300_CHANNEL_RED; 1160141cc406Sopenharmony_ci break; 1161141cc406Sopenharmony_ci 1162141cc406Sopenharmony_ci } 1163141cc406Sopenharmony_ci 1164141cc406Sopenharmony_ci set_ccd_channel_1013 (dev, priv->channel); 1165141cc406Sopenharmony_ci 1166141cc406Sopenharmony_ci /* set_invert_1013 (dev); */ 1167141cc406Sopenharmony_ci 1168141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 1169141cc406Sopenharmony_ci (dev->invert == SANE_TRUE ? 0x04 : 0x14)); 1170141cc406Sopenharmony_ci 1171141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x37); 1172141cc406Sopenharmony_ci reset_bank_count (dev); 1173141cc406Sopenharmony_ci 1174141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x27); 1175141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x67); 1176141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x17); 1177141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x77); 1178141cc406Sopenharmony_ci 1179141cc406Sopenharmony_ci /* set_initial_skip_1013 (dev); */ 1180141cc406Sopenharmony_ci 1181141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x41); 1182141cc406Sopenharmony_ci 1183141cc406Sopenharmony_ci priv->adjustskip = priv->skipcount + priv->skipimagebytes; 1184141cc406Sopenharmony_ci 1185141cc406Sopenharmony_ci DBG (5, "config_ccd_1013: adjustskip %u\n", priv->adjustskip); 1186141cc406Sopenharmony_ci 1187141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, priv->adjustskip / 16 + 2); 1188141cc406Sopenharmony_ci 1189141cc406Sopenharmony_ci priv->adjustskip %= 16; 1190141cc406Sopenharmony_ci 1191141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x81); 1192141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, 0x70); 1193141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x01); 1194141cc406Sopenharmony_ci 1195141cc406Sopenharmony_ci 1196141cc406Sopenharmony_ci set_line_adjust (dev); 1197141cc406Sopenharmony_ci 1198141cc406Sopenharmony_ci get_bank_count (dev); 1199141cc406Sopenharmony_ci 1200141cc406Sopenharmony_ci} 1201141cc406Sopenharmony_ci 1202141cc406Sopenharmony_ci/* these functions are for the 1015 chipset */ 1203141cc406Sopenharmony_ci 1204141cc406Sopenharmony_ci 1205141cc406Sopenharmony_cistatic void 1206141cc406Sopenharmony_cimotor_control_1015 (Mustek_pp_Handle * dev, u_char control) 1207141cc406Sopenharmony_ci{ 1208141cc406Sopenharmony_ci u_char val; 1209141cc406Sopenharmony_ci 1210141cc406Sopenharmony_ci DBG (5, "motor_controll_1015: control code 0x%02x\n", 1211141cc406Sopenharmony_ci (unsigned int) control); 1212141cc406Sopenharmony_ci 1213141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0xF6); 1214141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x22); 1215141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, control); 1216141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x02); 1217141cc406Sopenharmony_ci 1218141cc406Sopenharmony_ci do 1219141cc406Sopenharmony_ci { 1220141cc406Sopenharmony_ci 1221141cc406Sopenharmony_ci sanei_pa4s2_readbegin (dev->fd, 2); 1222141cc406Sopenharmony_ci sanei_pa4s2_readbyte (dev->fd, &val); 1223141cc406Sopenharmony_ci sanei_pa4s2_readend (dev->fd); 1224141cc406Sopenharmony_ci 1225141cc406Sopenharmony_ci } 1226141cc406Sopenharmony_ci while ((val & 0x08) != 0); 1227141cc406Sopenharmony_ci 1228141cc406Sopenharmony_ci} 1229141cc406Sopenharmony_ci 1230141cc406Sopenharmony_cistatic void 1231141cc406Sopenharmony_cireturn_home_1015 (Mustek_pp_Handle * dev, SANE_Bool nowait) 1232141cc406Sopenharmony_ci{ 1233141cc406Sopenharmony_ci 1234141cc406Sopenharmony_ci u_char ishome, control = 0xC3; 1235141cc406Sopenharmony_ci 1236141cc406Sopenharmony_ci motor_control_1015 (dev, control); 1237141cc406Sopenharmony_ci 1238141cc406Sopenharmony_ci do 1239141cc406Sopenharmony_ci { 1240141cc406Sopenharmony_ci 1241141cc406Sopenharmony_ci /* check_is_home_1015 */ 1242141cc406Sopenharmony_ci sanei_pa4s2_readbegin (dev->fd, 2); 1243141cc406Sopenharmony_ci sanei_pa4s2_readbyte (dev->fd, &ishome); 1244141cc406Sopenharmony_ci sanei_pa4s2_readend (dev->fd); 1245141cc406Sopenharmony_ci 1246141cc406Sopenharmony_ci if (nowait) 1247141cc406Sopenharmony_ci break; 1248141cc406Sopenharmony_ci 1249141cc406Sopenharmony_ci usleep (1000); /* much nicer load */ 1250141cc406Sopenharmony_ci 1251141cc406Sopenharmony_ci } 1252141cc406Sopenharmony_ci while ((ishome & 2) == 0); 1253141cc406Sopenharmony_ci 1254141cc406Sopenharmony_ci} 1255141cc406Sopenharmony_ci 1256141cc406Sopenharmony_cistatic void 1257141cc406Sopenharmony_cimotor_forward_1015 (Mustek_pp_Handle * dev) 1258141cc406Sopenharmony_ci{ 1259141cc406Sopenharmony_ci u_char control = 0x1B; 1260141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1261141cc406Sopenharmony_ci 1262141cc406Sopenharmony_ci priv->motor_step++; 1263141cc406Sopenharmony_ci set_led (dev); 1264141cc406Sopenharmony_ci 1265141cc406Sopenharmony_ci 1266141cc406Sopenharmony_ci motor_control_1015 (dev, control); 1267141cc406Sopenharmony_ci 1268141cc406Sopenharmony_ci set_ccd_channel_1015 (dev, priv->channel); 1269141cc406Sopenharmony_ci set_sti (dev); 1270141cc406Sopenharmony_ci 1271141cc406Sopenharmony_ci} 1272141cc406Sopenharmony_ci 1273141cc406Sopenharmony_ci/* 1274141cc406Sopenharmony_cistatic void 1275141cc406Sopenharmony_cimotor_backward_1015 (Mustek_pp_Handle * dev) 1276141cc406Sopenharmony_ci{ 1277141cc406Sopenharmony_ci u_char control = 0x43; 1278141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1279141cc406Sopenharmony_ci 1280141cc406Sopenharmony_ci priv->motor_step++; 1281141cc406Sopenharmony_ci 1282141cc406Sopenharmony_ci set_led (dev); 1283141cc406Sopenharmony_ci 1284141cc406Sopenharmony_ci switch (priv->ccd_type) 1285141cc406Sopenharmony_ci { 1286141cc406Sopenharmony_ci case 1: 1287141cc406Sopenharmony_ci control = 0x1B; 1288141cc406Sopenharmony_ci break; 1289141cc406Sopenharmony_ci 1290141cc406Sopenharmony_ci default: 1291141cc406Sopenharmony_ci control = 0x43; 1292141cc406Sopenharmony_ci break; 1293141cc406Sopenharmony_ci } 1294141cc406Sopenharmony_ci 1295141cc406Sopenharmony_ci motor_control_1015 (dev, control); 1296141cc406Sopenharmony_ci 1297141cc406Sopenharmony_ci set_ccd_channel_1015 (dev, priv->channel); 1298141cc406Sopenharmony_ci set_sti (dev); 1299141cc406Sopenharmony_ci 1300141cc406Sopenharmony_ci} 1301141cc406Sopenharmony_ci*/ 1302141cc406Sopenharmony_ci 1303141cc406Sopenharmony_ci 1304141cc406Sopenharmony_cistatic void 1305141cc406Sopenharmony_ciset_ccd_channel_1015 (Mustek_pp_Handle * dev, int channel) 1306141cc406Sopenharmony_ci{ 1307141cc406Sopenharmony_ci 1308141cc406Sopenharmony_ci u_char chancode = chan_codes_1015[channel]; 1309141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1310141cc406Sopenharmony_ci 1311141cc406Sopenharmony_ci priv->channel = channel; 1312141cc406Sopenharmony_ci 1313141cc406Sopenharmony_ci priv->image_control &= 0x34; 1314141cc406Sopenharmony_ci chancode |= priv->image_control; 1315141cc406Sopenharmony_ci 1316141cc406Sopenharmony_ci 1317141cc406Sopenharmony_ci priv->image_control = chancode; 1318141cc406Sopenharmony_ci 1319141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, chancode); 1320141cc406Sopenharmony_ci 1321141cc406Sopenharmony_ci} 1322141cc406Sopenharmony_ci 1323141cc406Sopenharmony_ci 1324141cc406Sopenharmony_cistatic void 1325141cc406Sopenharmony_ciconfig_ccd_1015 (Mustek_pp_Handle * dev) 1326141cc406Sopenharmony_ci{ 1327141cc406Sopenharmony_ci 1328141cc406Sopenharmony_ci u_char val; 1329141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1330141cc406Sopenharmony_ci 1331141cc406Sopenharmony_ci if (dev->res != 0) 1332141cc406Sopenharmony_ci priv->res_step = SANE_FIX ((float) priv->hwres / (float) dev->res); 1333141cc406Sopenharmony_ci 1334141cc406Sopenharmony_ci 1335141cc406Sopenharmony_ci set_dpi_value (dev); 1336141cc406Sopenharmony_ci 1337141cc406Sopenharmony_ci priv->image_control = 4; 1338141cc406Sopenharmony_ci 1339141cc406Sopenharmony_ci /* set_start_channel_1015 (dev); */ 1340141cc406Sopenharmony_ci 1341141cc406Sopenharmony_ci switch (dev->mode) 1342141cc406Sopenharmony_ci { 1343141cc406Sopenharmony_ci case MODE_BW: 1344141cc406Sopenharmony_ci case MODE_GRAYSCALE: 1345141cc406Sopenharmony_ci priv->channel = CCD300_CHANNEL_GRAY; 1346141cc406Sopenharmony_ci break; 1347141cc406Sopenharmony_ci 1348141cc406Sopenharmony_ci case MODE_COLOR: 1349141cc406Sopenharmony_ci priv->channel = CCD300_CHANNEL_RED; 1350141cc406Sopenharmony_ci break; 1351141cc406Sopenharmony_ci 1352141cc406Sopenharmony_ci } 1353141cc406Sopenharmony_ci 1354141cc406Sopenharmony_ci set_ccd_channel_1015 (dev, priv->channel); 1355141cc406Sopenharmony_ci 1356141cc406Sopenharmony_ci 1357141cc406Sopenharmony_ci /* set_invert_1015 (dev); */ 1358141cc406Sopenharmony_ci 1359141cc406Sopenharmony_ci priv->image_control &= 0xE4; 1360141cc406Sopenharmony_ci 1361141cc406Sopenharmony_ci if (dev->invert == SANE_FALSE) 1362141cc406Sopenharmony_ci priv->image_control |= 0x10; 1363141cc406Sopenharmony_ci 1364141cc406Sopenharmony_ci 1365141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, priv->image_control); 1366141cc406Sopenharmony_ci 1367141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x23); 1368141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, 0x00); 1369141cc406Sopenharmony_ci 1370141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x43); 1371141cc406Sopenharmony_ci 1372141cc406Sopenharmony_ci switch (priv->ccd_type) 1373141cc406Sopenharmony_ci { 1374141cc406Sopenharmony_ci case 1: 1375141cc406Sopenharmony_ci val = 0x6B; 1376141cc406Sopenharmony_ci break; 1377141cc406Sopenharmony_ci case 4: 1378141cc406Sopenharmony_ci val = 0x9F; 1379141cc406Sopenharmony_ci break; 1380141cc406Sopenharmony_ci default: 1381141cc406Sopenharmony_ci val = 0x92; 1382141cc406Sopenharmony_ci break; 1383141cc406Sopenharmony_ci } 1384141cc406Sopenharmony_ci 1385141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, val); 1386141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x03); 1387141cc406Sopenharmony_ci 1388141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x37); 1389141cc406Sopenharmony_ci reset_bank_count (dev); 1390141cc406Sopenharmony_ci 1391141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x27); 1392141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x67); 1393141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x17); 1394141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x77); 1395141cc406Sopenharmony_ci 1396141cc406Sopenharmony_ci /* set_initial_skip_1015 (dev); */ 1397141cc406Sopenharmony_ci 1398141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x41); 1399141cc406Sopenharmony_ci 1400141cc406Sopenharmony_ci priv->adjustskip = priv->skipcount + priv->skipimagebytes; 1401141cc406Sopenharmony_ci 1402141cc406Sopenharmony_ci /* if (dev->CCD.mode == MODE_COLOR) 1403141cc406Sopenharmony_ci dev->CCD.adjustskip <<= 3; */ 1404141cc406Sopenharmony_ci 1405141cc406Sopenharmony_ci 1406141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, priv->adjustskip / 32 + 1); 1407141cc406Sopenharmony_ci 1408141cc406Sopenharmony_ci priv->adjustskip %= 32; 1409141cc406Sopenharmony_ci 1410141cc406Sopenharmony_ci 1411141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x81); 1412141cc406Sopenharmony_ci 1413141cc406Sopenharmony_ci /* expose time */ 1414141cc406Sopenharmony_ci switch (priv->ccd_type) 1415141cc406Sopenharmony_ci { 1416141cc406Sopenharmony_ci case 1: 1417141cc406Sopenharmony_ci 1418141cc406Sopenharmony_ci val = 0xA8; 1419141cc406Sopenharmony_ci break; 1420141cc406Sopenharmony_ci case 0: 1421141cc406Sopenharmony_ci val = 0x8A; 1422141cc406Sopenharmony_ci break; 1423141cc406Sopenharmony_ci default: 1424141cc406Sopenharmony_ci val = 0xA8; 1425141cc406Sopenharmony_ci break; 1426141cc406Sopenharmony_ci } 1427141cc406Sopenharmony_ci 1428141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 5, val); 1429141cc406Sopenharmony_ci 1430141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x01); 1431141cc406Sopenharmony_ci 1432141cc406Sopenharmony_ci 1433141cc406Sopenharmony_ci set_line_adjust (dev); 1434141cc406Sopenharmony_ci 1435141cc406Sopenharmony_ci get_bank_count (dev); 1436141cc406Sopenharmony_ci 1437141cc406Sopenharmony_ci} 1438141cc406Sopenharmony_ci 1439141cc406Sopenharmony_ci 1440141cc406Sopenharmony_ci/* these functions are interfaces only */ 1441141cc406Sopenharmony_cistatic void 1442141cc406Sopenharmony_ciconfig_ccd (Mustek_pp_Handle * dev) 1443141cc406Sopenharmony_ci{ 1444141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1445141cc406Sopenharmony_ci 1446141cc406Sopenharmony_ci DBG (5, "config_ccd: %d dpi, mode %d, invert %d, size %d\n", 1447141cc406Sopenharmony_ci priv->hwres, dev->mode, dev->invert, dev->params.pixels_per_line); 1448141cc406Sopenharmony_ci 1449141cc406Sopenharmony_ci switch (priv->asic) 1450141cc406Sopenharmony_ci { 1451141cc406Sopenharmony_ci case CCD300_ASIC1013: 1452141cc406Sopenharmony_ci config_ccd_1013 (dev); 1453141cc406Sopenharmony_ci break; 1454141cc406Sopenharmony_ci 1455141cc406Sopenharmony_ci case CCD300_ASIC1015: 1456141cc406Sopenharmony_ci config_ccd_1015 (dev); 1457141cc406Sopenharmony_ci break; 1458141cc406Sopenharmony_ci } 1459141cc406Sopenharmony_ci 1460141cc406Sopenharmony_ci} 1461141cc406Sopenharmony_ci 1462141cc406Sopenharmony_cistatic void 1463141cc406Sopenharmony_cireturn_home (Mustek_pp_Handle * dev, SANE_Bool nowait) 1464141cc406Sopenharmony_ci{ 1465141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1466141cc406Sopenharmony_ci 1467141cc406Sopenharmony_ci priv->saved_mode = dev->mode; 1468141cc406Sopenharmony_ci priv->saved_invert = dev->invert; 1469141cc406Sopenharmony_ci priv->saved_skipcount = priv->skipcount; 1470141cc406Sopenharmony_ci priv->saved_skipimagebyte = priv->skipimagebytes; 1471141cc406Sopenharmony_ci priv->saved_adjustskip = priv->adjustskip; 1472141cc406Sopenharmony_ci priv->saved_res = dev->res; 1473141cc406Sopenharmony_ci priv->saved_hwres = priv->hwres; 1474141cc406Sopenharmony_ci priv->saved_res_step = priv->res_step; 1475141cc406Sopenharmony_ci priv->saved_line_step = priv->line_step; 1476141cc406Sopenharmony_ci priv->saved_channel = priv->channel; 1477141cc406Sopenharmony_ci 1478141cc406Sopenharmony_ci 1479141cc406Sopenharmony_ci priv->hwres = dev->res = 100; 1480141cc406Sopenharmony_ci dev->mode = MODE_GRAYSCALE; 1481141cc406Sopenharmony_ci 1482141cc406Sopenharmony_ci priv->skipcount = priv->skipimagebytes = 0; 1483141cc406Sopenharmony_ci 1484141cc406Sopenharmony_ci config_ccd (dev); 1485141cc406Sopenharmony_ci 1486141cc406Sopenharmony_ci switch (priv->asic) 1487141cc406Sopenharmony_ci { 1488141cc406Sopenharmony_ci case CCD300_ASIC1013: 1489141cc406Sopenharmony_ci return_home_1013 (dev); 1490141cc406Sopenharmony_ci break; 1491141cc406Sopenharmony_ci 1492141cc406Sopenharmony_ci case CCD300_ASIC1015: 1493141cc406Sopenharmony_ci return_home_1015 (dev, nowait); 1494141cc406Sopenharmony_ci break; 1495141cc406Sopenharmony_ci } 1496141cc406Sopenharmony_ci 1497141cc406Sopenharmony_ci 1498141cc406Sopenharmony_ci dev->mode = priv->saved_mode; 1499141cc406Sopenharmony_ci dev->invert = priv->saved_invert; 1500141cc406Sopenharmony_ci priv->skipcount = priv->saved_skipcount; 1501141cc406Sopenharmony_ci priv->skipimagebytes = priv->saved_skipimagebyte; 1502141cc406Sopenharmony_ci priv->adjustskip = priv->saved_adjustskip; 1503141cc406Sopenharmony_ci dev->res = priv->saved_res; 1504141cc406Sopenharmony_ci priv->hwres = priv->saved_hwres; 1505141cc406Sopenharmony_ci priv->res_step = priv->saved_res_step; 1506141cc406Sopenharmony_ci priv->line_step = priv->saved_line_step; 1507141cc406Sopenharmony_ci priv->channel = priv->saved_channel; 1508141cc406Sopenharmony_ci priv->motor_step = 0; 1509141cc406Sopenharmony_ci 1510141cc406Sopenharmony_ci config_ccd (dev); 1511141cc406Sopenharmony_ci} 1512141cc406Sopenharmony_ci 1513141cc406Sopenharmony_cistatic void 1514141cc406Sopenharmony_cilamp (Mustek_pp_Handle * dev, int lamp_on) 1515141cc406Sopenharmony_ci{ 1516141cc406Sopenharmony_ci 1517141cc406Sopenharmony_ci set_lamp (dev, lamp_on); 1518141cc406Sopenharmony_ci 1519141cc406Sopenharmony_ci} 1520141cc406Sopenharmony_ci 1521141cc406Sopenharmony_cistatic void 1522141cc406Sopenharmony_ciset_voltages (Mustek_pp_Handle * dev) 1523141cc406Sopenharmony_ci{ 1524141cc406Sopenharmony_ci send_voltages (dev); 1525141cc406Sopenharmony_ci} 1526141cc406Sopenharmony_ci 1527141cc406Sopenharmony_cistatic void 1528141cc406Sopenharmony_cimove_motor (Mustek_pp_Handle * dev, int count, int forward) 1529141cc406Sopenharmony_ci{ 1530141cc406Sopenharmony_ci 1531141cc406Sopenharmony_ci int ctr; 1532141cc406Sopenharmony_ci 1533141cc406Sopenharmony_ci DBG (5, "move_motor: %u steps (%s)\n", count, 1534141cc406Sopenharmony_ci (forward == SANE_TRUE ? "forward" : "backward")); 1535141cc406Sopenharmony_ci 1536141cc406Sopenharmony_ci 1537141cc406Sopenharmony_ci for (ctr = 0; ctr < count; ctr++) 1538141cc406Sopenharmony_ci { 1539141cc406Sopenharmony_ci 1540141cc406Sopenharmony_ci move_motor_101x (dev, forward); 1541141cc406Sopenharmony_ci 1542141cc406Sopenharmony_ci } 1543141cc406Sopenharmony_ci 1544141cc406Sopenharmony_ci 1545141cc406Sopenharmony_ci} 1546141cc406Sopenharmony_ci 1547141cc406Sopenharmony_cistatic void 1548141cc406Sopenharmony_cicalibrate (Mustek_pp_Handle * dev) 1549141cc406Sopenharmony_ci{ 1550141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1551141cc406Sopenharmony_ci 1552141cc406Sopenharmony_ci DBG (5, "calibrate entered (asic = 0x%02x)\n", priv->asic); 1553141cc406Sopenharmony_ci 1554141cc406Sopenharmony_ci calibrate_device_101x (dev); 1555141cc406Sopenharmony_ci 1556141cc406Sopenharmony_ci DBG (5, "calibrate: ref_black %d, blackpos %d\n", 1557141cc406Sopenharmony_ci priv->ref_black, priv->blackpos); 1558141cc406Sopenharmony_ci 1559141cc406Sopenharmony_ci} 1560141cc406Sopenharmony_ci 1561141cc406Sopenharmony_ci 1562141cc406Sopenharmony_cistatic void 1563141cc406Sopenharmony_ciget_lineart_line (Mustek_pp_Handle * dev, SANE_Byte * buf) 1564141cc406Sopenharmony_ci{ 1565141cc406Sopenharmony_ci get_lineart_line_101x (dev, buf); 1566141cc406Sopenharmony_ci} 1567141cc406Sopenharmony_ci 1568141cc406Sopenharmony_cistatic void 1569141cc406Sopenharmony_ciget_grayscale_line (Mustek_pp_Handle * dev, SANE_Byte * buf) 1570141cc406Sopenharmony_ci{ 1571141cc406Sopenharmony_ci 1572141cc406Sopenharmony_ci get_grayscale_line_101x (dev, buf); 1573141cc406Sopenharmony_ci} 1574141cc406Sopenharmony_ci 1575141cc406Sopenharmony_cistatic void 1576141cc406Sopenharmony_ciget_color_line (Mustek_pp_Handle * dev, SANE_Byte * buf) 1577141cc406Sopenharmony_ci{ 1578141cc406Sopenharmony_ci 1579141cc406Sopenharmony_ci get_color_line_101x (dev, buf); 1580141cc406Sopenharmony_ci 1581141cc406Sopenharmony_ci} 1582141cc406Sopenharmony_ci 1583141cc406Sopenharmony_ci 1584141cc406Sopenharmony_cistatic SANE_Status 1585141cc406Sopenharmony_ciccd300_init (SANE_Int options, SANE_String_Const port, 1586141cc406Sopenharmony_ci SANE_String_Const name, SANE_Attach_Callback attach) 1587141cc406Sopenharmony_ci{ 1588141cc406Sopenharmony_ci SANE_Status status; 1589141cc406Sopenharmony_ci unsigned char asic, ccd; 1590141cc406Sopenharmony_ci int fd; 1591141cc406Sopenharmony_ci 1592141cc406Sopenharmony_ci if (options != CAP_NOTHING) 1593141cc406Sopenharmony_ci { 1594141cc406Sopenharmony_ci DBG (1, "ccd300_init: called with unknown options (%#02x)\n", options); 1595141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1596141cc406Sopenharmony_ci } 1597141cc406Sopenharmony_ci 1598141cc406Sopenharmony_ci /* try to attach to he supplied port */ 1599141cc406Sopenharmony_ci status = sanei_pa4s2_open (port, &fd); 1600141cc406Sopenharmony_ci 1601141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1602141cc406Sopenharmony_ci { 1603141cc406Sopenharmony_ci DBG (2, "ccd300_init: couldn't attach to port ``%s'' (%s)\n", 1604141cc406Sopenharmony_ci port, sane_strstatus (status)); 1605141cc406Sopenharmony_ci return status; 1606141cc406Sopenharmony_ci } 1607141cc406Sopenharmony_ci 1608141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_TRUE); 1609141cc406Sopenharmony_ci sanei_pa4s2_readbegin (fd, 0); 1610141cc406Sopenharmony_ci sanei_pa4s2_readbyte (fd, &asic); 1611141cc406Sopenharmony_ci sanei_pa4s2_readend (fd); 1612141cc406Sopenharmony_ci sanei_pa4s2_readbegin (fd, 2); 1613141cc406Sopenharmony_ci sanei_pa4s2_readbyte (fd, &ccd); 1614141cc406Sopenharmony_ci sanei_pa4s2_readend (fd); 1615141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 1616141cc406Sopenharmony_ci sanei_pa4s2_close (fd); 1617141cc406Sopenharmony_ci 1618141cc406Sopenharmony_ci if (asic != CCD300_ASIC1013 && asic != CCD300_ASIC1015) 1619141cc406Sopenharmony_ci { 1620141cc406Sopenharmony_ci DBG (2, "ccd300_init: scanner not recognized (unknown ASIC id %#02x)\n", 1621141cc406Sopenharmony_ci asic); 1622141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1623141cc406Sopenharmony_ci } 1624141cc406Sopenharmony_ci 1625141cc406Sopenharmony_ci ccd &= (asic == CCD300_ASIC1013 ? 0x04 : 0x05); 1626141cc406Sopenharmony_ci 1627141cc406Sopenharmony_ci DBG (3, "ccd_init: found scanner on port ``%s'' (ASIC id %#02x, CCD %d)\n", 1628141cc406Sopenharmony_ci port, asic, ccd); 1629141cc406Sopenharmony_ci 1630141cc406Sopenharmony_ci return attach (port, name, MUSTEK_PP_CCD300, options); 1631141cc406Sopenharmony_ci 1632141cc406Sopenharmony_ci} 1633141cc406Sopenharmony_ci 1634141cc406Sopenharmony_cistatic void 1635141cc406Sopenharmony_ciccd300_capabilities (SANE_Int info, SANE_String * model, 1636141cc406Sopenharmony_ci SANE_String * vendor, SANE_String * type, 1637141cc406Sopenharmony_ci SANE_Int * maxres, SANE_Int * minres, 1638141cc406Sopenharmony_ci SANE_Int * maxhsize, SANE_Int * maxvsize, 1639141cc406Sopenharmony_ci SANE_Int * caps) 1640141cc406Sopenharmony_ci{ 1641141cc406Sopenharmony_ci *model = strdup ("600 III EP Plus"); 1642141cc406Sopenharmony_ci *vendor = strdup ("Mustek"); 1643141cc406Sopenharmony_ci *type = strdup ("flatbed (CCD 300 dpi)"); 1644141cc406Sopenharmony_ci DBG (3, 1645141cc406Sopenharmony_ci "ccd300_capabilities: 600 III EP Plus flatbed CCD (300 dpi) scanner\n"); 1646141cc406Sopenharmony_ci 1647141cc406Sopenharmony_ci *maxres = 300; 1648141cc406Sopenharmony_ci *minres = 50; 1649141cc406Sopenharmony_ci *maxhsize = CCD300_MAXHSIZE; 1650141cc406Sopenharmony_ci *maxvsize = CCD300_MAXVSIZE; 1651141cc406Sopenharmony_ci *caps = info | CAP_INVERT | CAP_LAMP_OFF; 1652141cc406Sopenharmony_ci} 1653141cc406Sopenharmony_ci 1654141cc406Sopenharmony_cistatic SANE_Status 1655141cc406Sopenharmony_ciccd300_open (SANE_String port, SANE_Int caps, SANE_Int * fd) 1656141cc406Sopenharmony_ci{ 1657141cc406Sopenharmony_ci SANE_Status status; 1658141cc406Sopenharmony_ci 1659141cc406Sopenharmony_ci if (caps & ~(CAP_NOTHING | CAP_INVERT | CAP_LAMP_OFF)) 1660141cc406Sopenharmony_ci { 1661141cc406Sopenharmony_ci DBG (1, "ccd300_open: called with unknown capabilities (%#02x)\n", 1662141cc406Sopenharmony_ci caps); 1663141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1664141cc406Sopenharmony_ci } 1665141cc406Sopenharmony_ci 1666141cc406Sopenharmony_ci DBG (3, "ccd300_open: called for port ``%s''\n", port); 1667141cc406Sopenharmony_ci 1668141cc406Sopenharmony_ci status = sanei_pa4s2_open (port, fd); 1669141cc406Sopenharmony_ci 1670141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1671141cc406Sopenharmony_ci DBG (2, "ccd300_open: open failed (%s)\n", sane_strstatus (status)); 1672141cc406Sopenharmony_ci 1673141cc406Sopenharmony_ci return status; 1674141cc406Sopenharmony_ci} 1675141cc406Sopenharmony_ci 1676141cc406Sopenharmony_cistatic void 1677141cc406Sopenharmony_ciccd300_setup (SANE_Handle handle) 1678141cc406Sopenharmony_ci{ 1679141cc406Sopenharmony_ci Mustek_pp_Handle *dev = handle; 1680141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv; 1681141cc406Sopenharmony_ci unsigned char asic, ccd; 1682141cc406Sopenharmony_ci 1683141cc406Sopenharmony_ci DBG (3, "ccd300_setup: called for port ``%s''\n", dev->dev->port); 1684141cc406Sopenharmony_ci 1685141cc406Sopenharmony_ci if ((priv = malloc (sizeof (mustek_pp_ccd300_priv))) == NULL) 1686141cc406Sopenharmony_ci { 1687141cc406Sopenharmony_ci DBG (1, "ccd300_setup: not enough memory\n"); 1688141cc406Sopenharmony_ci return; /* can you here the shit hitting the fan? */ 1689141cc406Sopenharmony_ci } 1690141cc406Sopenharmony_ci 1691141cc406Sopenharmony_ci dev->priv = priv; 1692141cc406Sopenharmony_ci memset (priv, 0, sizeof (mustek_pp_ccd300_priv)); 1693141cc406Sopenharmony_ci 1694141cc406Sopenharmony_ci priv->bw = 128; 1695141cc406Sopenharmony_ci priv->wait_bank = 700; 1696141cc406Sopenharmony_ci priv->top = 47; 1697141cc406Sopenharmony_ci 1698141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_TRUE); 1699141cc406Sopenharmony_ci 1700141cc406Sopenharmony_ci sanei_pa4s2_readbegin (dev->fd, 0); 1701141cc406Sopenharmony_ci sanei_pa4s2_readbyte (dev->fd, &asic); 1702141cc406Sopenharmony_ci sanei_pa4s2_readend (dev->fd); 1703141cc406Sopenharmony_ci sanei_pa4s2_readbegin (dev->fd, 2); 1704141cc406Sopenharmony_ci sanei_pa4s2_readbyte (dev->fd, &ccd); 1705141cc406Sopenharmony_ci sanei_pa4s2_readend (dev->fd); 1706141cc406Sopenharmony_ci ccd &= (asic == CCD300_ASIC1013 ? 0x04 : 0x05); 1707141cc406Sopenharmony_ci priv->asic = asic; 1708141cc406Sopenharmony_ci priv->ccd_type = ccd; 1709141cc406Sopenharmony_ci 1710141cc406Sopenharmony_ci return_home (dev, SANE_TRUE); 1711141cc406Sopenharmony_ci lamp (dev, SANE_TRUE); 1712141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_FALSE); 1713141cc406Sopenharmony_ci dev->lamp_on = time (NULL); 1714141cc406Sopenharmony_ci dev->res = priv->hwres = 300; 1715141cc406Sopenharmony_ci dev->mode = MODE_COLOR; 1716141cc406Sopenharmony_ci} 1717141cc406Sopenharmony_ci 1718141cc406Sopenharmony_cistatic void 1719141cc406Sopenharmony_ciccd300_close (SANE_Handle handle) 1720141cc406Sopenharmony_ci{ 1721141cc406Sopenharmony_ci 1722141cc406Sopenharmony_ci Mustek_pp_Handle *dev = handle; 1723141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1724141cc406Sopenharmony_ci 1725141cc406Sopenharmony_ci DBG (3, "ccd300_close: called for port ``%s''\n", dev->dev->port); 1726141cc406Sopenharmony_ci 1727141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_TRUE); 1728141cc406Sopenharmony_ci lamp (dev, SANE_FALSE); 1729141cc406Sopenharmony_ci return_home (dev, SANE_FALSE); 1730141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_FALSE); 1731141cc406Sopenharmony_ci 1732141cc406Sopenharmony_ci sanei_pa4s2_close (dev->fd); 1733141cc406Sopenharmony_ci free (priv); 1734141cc406Sopenharmony_ci 1735141cc406Sopenharmony_ci DBG (3, "ccd300_close: device shut down and all buffers freed\n"); 1736141cc406Sopenharmony_ci} 1737141cc406Sopenharmony_ci 1738141cc406Sopenharmony_cistatic SANE_Status 1739141cc406Sopenharmony_ciccd300_config (SANE_Handle handle, SANE_String_Const optname, 1740141cc406Sopenharmony_ci SANE_String_Const optval) 1741141cc406Sopenharmony_ci{ 1742141cc406Sopenharmony_ci Mustek_pp_Handle *dev = handle; 1743141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1744141cc406Sopenharmony_ci int value = -1; 1745141cc406Sopenharmony_ci 1746141cc406Sopenharmony_ci DBG (3, "ccd300_config: called for port ``%s'' (%s%s%s)\n", 1747141cc406Sopenharmony_ci dev->dev->port, 1748141cc406Sopenharmony_ci optname, (optval ? " = " : ""), (optval ? optval : "")); 1749141cc406Sopenharmony_ci 1750141cc406Sopenharmony_ci if (!strcmp (optname, "bw")) 1751141cc406Sopenharmony_ci { 1752141cc406Sopenharmony_ci 1753141cc406Sopenharmony_ci if (!optval) 1754141cc406Sopenharmony_ci { 1755141cc406Sopenharmony_ci DBG (1, "ccd300_config: missing value for option ``bw''\n"); 1756141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1757141cc406Sopenharmony_ci } 1758141cc406Sopenharmony_ci 1759141cc406Sopenharmony_ci /* ok, ok, should be strtol... know what? send me a patch. */ 1760141cc406Sopenharmony_ci value = atoi (optval); 1761141cc406Sopenharmony_ci 1762141cc406Sopenharmony_ci if ((value < 0) || (value > 255)) 1763141cc406Sopenharmony_ci { 1764141cc406Sopenharmony_ci DBG (1, 1765141cc406Sopenharmony_ci "ccd300_config: value ``%s'' for option ``bw'' is out of range (0 <= bw <= 255)\n", 1766141cc406Sopenharmony_ci optval); 1767141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1768141cc406Sopenharmony_ci } 1769141cc406Sopenharmony_ci 1770141cc406Sopenharmony_ci priv->bw = value; 1771141cc406Sopenharmony_ci 1772141cc406Sopenharmony_ci } 1773141cc406Sopenharmony_ci else if (!strcmp (optname, "waitbank")) 1774141cc406Sopenharmony_ci { 1775141cc406Sopenharmony_ci 1776141cc406Sopenharmony_ci if (!optval) 1777141cc406Sopenharmony_ci { 1778141cc406Sopenharmony_ci DBG (1, "ccd300_config: missing value for option ``waitbank''\n"); 1779141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1780141cc406Sopenharmony_ci } 1781141cc406Sopenharmony_ci 1782141cc406Sopenharmony_ci value = atoi (optval); 1783141cc406Sopenharmony_ci 1784141cc406Sopenharmony_ci if (value < 0) 1785141cc406Sopenharmony_ci { 1786141cc406Sopenharmony_ci DBG (1, 1787141cc406Sopenharmony_ci "ccd300_config: value ``%s'' for option ``waitbank'' is out of range (>= 0)\n", 1788141cc406Sopenharmony_ci optval); 1789141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1790141cc406Sopenharmony_ci } 1791141cc406Sopenharmony_ci 1792141cc406Sopenharmony_ci priv->wait_bank = value; 1793141cc406Sopenharmony_ci } 1794141cc406Sopenharmony_ci else if (!strcmp (optname, "top")) 1795141cc406Sopenharmony_ci { 1796141cc406Sopenharmony_ci 1797141cc406Sopenharmony_ci if (!optval) 1798141cc406Sopenharmony_ci { 1799141cc406Sopenharmony_ci DBG (1, "ccd300_config: missing value for option ``top''\n"); 1800141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1801141cc406Sopenharmony_ci } 1802141cc406Sopenharmony_ci 1803141cc406Sopenharmony_ci value = atoi (optval); 1804141cc406Sopenharmony_ci 1805141cc406Sopenharmony_ci if (value < 0) 1806141cc406Sopenharmony_ci { 1807141cc406Sopenharmony_ci DBG (1, 1808141cc406Sopenharmony_ci "ccd300_config: value ``%s'' for option ``top'' is out of range (>= 0)\n", 1809141cc406Sopenharmony_ci optval); 1810141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1811141cc406Sopenharmony_ci } 1812141cc406Sopenharmony_ci 1813141cc406Sopenharmony_ci priv->top = value; 1814141cc406Sopenharmony_ci } 1815141cc406Sopenharmony_ci else 1816141cc406Sopenharmony_ci { 1817141cc406Sopenharmony_ci DBG (1, "ccd300_config: unknown option ``%s''", optname); 1818141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1819141cc406Sopenharmony_ci } 1820141cc406Sopenharmony_ci 1821141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1822141cc406Sopenharmony_ci 1823141cc406Sopenharmony_ci} 1824141cc406Sopenharmony_ci 1825141cc406Sopenharmony_cistatic void 1826141cc406Sopenharmony_ciccd300_stop (SANE_Handle handle) 1827141cc406Sopenharmony_ci{ 1828141cc406Sopenharmony_ci Mustek_pp_Handle *dev = handle; 1829141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1830141cc406Sopenharmony_ci int cnt; 1831141cc406Sopenharmony_ci 1832141cc406Sopenharmony_ci DBG (3, "ccd300_stop: stopping scan operating on port ``%s''\n", 1833141cc406Sopenharmony_ci dev->dev->port); 1834141cc406Sopenharmony_ci 1835141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_TRUE); 1836141cc406Sopenharmony_ci return_home (dev, SANE_TRUE); 1837141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_FALSE); 1838141cc406Sopenharmony_ci 1839141cc406Sopenharmony_ci free (priv->calib_r); 1840141cc406Sopenharmony_ci free (priv->calib_g); 1841141cc406Sopenharmony_ci free (priv->calib_b); 1842141cc406Sopenharmony_ci 1843141cc406Sopenharmony_ci if (priv->red) 1844141cc406Sopenharmony_ci { 1845141cc406Sopenharmony_ci for (cnt = 0; cnt < priv->green_offs; cnt++) 1846141cc406Sopenharmony_ci free (priv->red[cnt]); 1847141cc406Sopenharmony_ci free (priv->red); 1848141cc406Sopenharmony_ci } 1849141cc406Sopenharmony_ci if (priv->blue) 1850141cc406Sopenharmony_ci { 1851141cc406Sopenharmony_ci for (cnt = 0; cnt < priv->blue_offs; cnt++) 1852141cc406Sopenharmony_ci free (priv->blue[cnt]); 1853141cc406Sopenharmony_ci free (priv->blue); 1854141cc406Sopenharmony_ci } 1855141cc406Sopenharmony_ci free (priv->green); 1856141cc406Sopenharmony_ci 1857141cc406Sopenharmony_ci priv->calib_r = priv->calib_g = priv->calib_b = NULL; 1858141cc406Sopenharmony_ci priv->red = priv->blue = NULL; 1859141cc406Sopenharmony_ci priv->green = NULL; 1860141cc406Sopenharmony_ci 1861141cc406Sopenharmony_ci} 1862141cc406Sopenharmony_ci 1863141cc406Sopenharmony_cistatic SANE_Status 1864141cc406Sopenharmony_ciccd300_start (SANE_Handle handle) 1865141cc406Sopenharmony_ci{ 1866141cc406Sopenharmony_ci Mustek_pp_Handle *dev = handle; 1867141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 1868141cc406Sopenharmony_ci 1869141cc406Sopenharmony_ci DBG (3, "ccd300_start: called for port ``%s''\n", dev->dev->port); 1870141cc406Sopenharmony_ci 1871141cc406Sopenharmony_ci if (dev->res <= 100) 1872141cc406Sopenharmony_ci priv->hwres = 100; 1873141cc406Sopenharmony_ci else if (dev->res <= 200) 1874141cc406Sopenharmony_ci priv->hwres = 200; 1875141cc406Sopenharmony_ci else if (dev->res <= 300) 1876141cc406Sopenharmony_ci priv->hwres = 300; 1877141cc406Sopenharmony_ci 1878141cc406Sopenharmony_ci DBG (4, "ccd300_start: setting hardware resolution to %d dpi\n", 1879141cc406Sopenharmony_ci priv->hwres); 1880141cc406Sopenharmony_ci 1881141cc406Sopenharmony_ci priv->skipimagebytes = dev->topX; 1882141cc406Sopenharmony_ci 1883141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_TRUE); 1884141cc406Sopenharmony_ci config_ccd (dev); 1885141cc406Sopenharmony_ci set_voltages (dev); 1886141cc406Sopenharmony_ci get_bank_count (dev); 1887141cc406Sopenharmony_ci 1888141cc406Sopenharmony_ci if (priv->bank_count != 0) 1889141cc406Sopenharmony_ci { 1890141cc406Sopenharmony_ci DBG (2, "ccd300_start: bank count is not zero...\n"); 1891141cc406Sopenharmony_ci } 1892141cc406Sopenharmony_ci 1893141cc406Sopenharmony_ci return_home (dev, SANE_FALSE); 1894141cc406Sopenharmony_ci 1895141cc406Sopenharmony_ci priv->motor_step = 0; 1896141cc406Sopenharmony_ci 1897141cc406Sopenharmony_ci /* allocate memory for calibration */ 1898141cc406Sopenharmony_ci if ((priv->calib_g = malloc (dev->params.pixels_per_line)) == NULL) 1899141cc406Sopenharmony_ci { 1900141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_FALSE); 1901141cc406Sopenharmony_ci DBG (1, "ccd300_start: not enough memory\n"); 1902141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1903141cc406Sopenharmony_ci } 1904141cc406Sopenharmony_ci 1905141cc406Sopenharmony_ci if (dev->mode == MODE_COLOR) 1906141cc406Sopenharmony_ci { 1907141cc406Sopenharmony_ci priv->calib_r = malloc (dev->params.pixels_per_line); 1908141cc406Sopenharmony_ci priv->calib_b = malloc (dev->params.pixels_per_line); 1909141cc406Sopenharmony_ci 1910141cc406Sopenharmony_ci if ((priv->calib_r == NULL) || (priv->calib_b == NULL)) 1911141cc406Sopenharmony_ci { 1912141cc406Sopenharmony_ci free (priv->calib_g); 1913141cc406Sopenharmony_ci free (priv->calib_r); 1914141cc406Sopenharmony_ci free (priv->calib_b); 1915141cc406Sopenharmony_ci priv->calib_r = priv->calib_g = priv->calib_b = NULL; 1916141cc406Sopenharmony_ci 1917141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_FALSE); 1918141cc406Sopenharmony_ci DBG (1, "ccd300_start: not enough memory\n"); 1919141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1920141cc406Sopenharmony_ci } 1921141cc406Sopenharmony_ci } 1922141cc406Sopenharmony_ci 1923141cc406Sopenharmony_ci calibrate (dev); 1924141cc406Sopenharmony_ci 1925141cc406Sopenharmony_ci if (priv->ccd_type == 1) 1926141cc406Sopenharmony_ci { 1927141cc406Sopenharmony_ci priv->blue_offs = 4; 1928141cc406Sopenharmony_ci priv->green_offs = 8; 1929141cc406Sopenharmony_ci } 1930141cc406Sopenharmony_ci else 1931141cc406Sopenharmony_ci { 1932141cc406Sopenharmony_ci priv->blue_offs = 8; 1933141cc406Sopenharmony_ci priv->green_offs = 16; 1934141cc406Sopenharmony_ci } 1935141cc406Sopenharmony_ci 1936141cc406Sopenharmony_ci move_motor (dev, priv->top + dev->topY - 1937141cc406Sopenharmony_ci (dev->mode == MODE_COLOR ? priv->green_offs : 0), SANE_TRUE); 1938141cc406Sopenharmony_ci 1939141cc406Sopenharmony_ci if (priv->ccd_type == 1) 1940141cc406Sopenharmony_ci sanei_pa4s2_writebyte (dev->fd, 6, 0x15); 1941141cc406Sopenharmony_ci 1942141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_FALSE); 1943141cc406Sopenharmony_ci 1944141cc406Sopenharmony_ci if (dev->mode == MODE_COLOR) 1945141cc406Sopenharmony_ci { 1946141cc406Sopenharmony_ci int failed = SANE_FALSE, cnt; 1947141cc406Sopenharmony_ci 1948141cc406Sopenharmony_ci priv->line_step = SANE_FIX (300.0 / (float) dev->res); 1949141cc406Sopenharmony_ci priv->rdiff = priv->line_step; 1950141cc406Sopenharmony_ci priv->bdiff = priv->rdiff + (priv->blue_offs << SANE_FIXED_SCALE_SHIFT); 1951141cc406Sopenharmony_ci priv->gdiff = 1952141cc406Sopenharmony_ci priv->rdiff + (priv->green_offs << SANE_FIXED_SCALE_SHIFT); 1953141cc406Sopenharmony_ci 1954141cc406Sopenharmony_ci priv->red = malloc (sizeof (SANE_Byte *) * priv->green_offs); 1955141cc406Sopenharmony_ci priv->blue = malloc (sizeof (SANE_Byte *) * priv->blue_offs); 1956141cc406Sopenharmony_ci priv->green = malloc (dev->params.pixels_per_line); 1957141cc406Sopenharmony_ci 1958141cc406Sopenharmony_ci if ((priv->red == NULL) || (priv->blue == NULL) 1959141cc406Sopenharmony_ci || (priv->green == NULL)) 1960141cc406Sopenharmony_ci { 1961141cc406Sopenharmony_ci free (priv->calib_r); 1962141cc406Sopenharmony_ci free (priv->calib_g); 1963141cc406Sopenharmony_ci free (priv->calib_b); 1964141cc406Sopenharmony_ci priv->calib_r = priv->calib_g = priv->calib_b = NULL; 1965141cc406Sopenharmony_ci 1966141cc406Sopenharmony_ci free (priv->red); 1967141cc406Sopenharmony_ci free (priv->green); 1968141cc406Sopenharmony_ci free (priv->blue); 1969141cc406Sopenharmony_ci priv->red = priv->blue = NULL; 1970141cc406Sopenharmony_ci priv->green = NULL; 1971141cc406Sopenharmony_ci 1972141cc406Sopenharmony_ci DBG (1, "ccd300_start: not enough memory for ld buffers\n"); 1973141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1974141cc406Sopenharmony_ci } 1975141cc406Sopenharmony_ci 1976141cc406Sopenharmony_ci /* note to myself: better allocate one huge chunk of memory and set 1977141cc406Sopenharmony_ci pointers */ 1978141cc406Sopenharmony_ci for (cnt = 0; cnt < priv->green_offs; cnt++) 1979141cc406Sopenharmony_ci if ((priv->red[cnt] = malloc (dev->params.pixels_per_line)) == NULL) 1980141cc406Sopenharmony_ci failed = SANE_TRUE; 1981141cc406Sopenharmony_ci 1982141cc406Sopenharmony_ci for (cnt = 0; cnt < priv->blue_offs; cnt++) 1983141cc406Sopenharmony_ci if ((priv->blue[cnt] = malloc (dev->params.pixels_per_line)) == NULL) 1984141cc406Sopenharmony_ci failed = SANE_TRUE; 1985141cc406Sopenharmony_ci 1986141cc406Sopenharmony_ci if (failed == SANE_TRUE) 1987141cc406Sopenharmony_ci { 1988141cc406Sopenharmony_ci free (priv->calib_r); 1989141cc406Sopenharmony_ci free (priv->calib_g); 1990141cc406Sopenharmony_ci free (priv->calib_b); 1991141cc406Sopenharmony_ci priv->calib_r = priv->calib_g = priv->calib_b = NULL; 1992141cc406Sopenharmony_ci 1993141cc406Sopenharmony_ci for (cnt = 0; cnt < priv->green_offs; cnt++) 1994141cc406Sopenharmony_ci free (priv->red[cnt]); 1995141cc406Sopenharmony_ci for (cnt = 0; cnt < priv->blue_offs; cnt++) 1996141cc406Sopenharmony_ci free (priv->blue[cnt]); 1997141cc406Sopenharmony_ci 1998141cc406Sopenharmony_ci free (priv->red); 1999141cc406Sopenharmony_ci free (priv->green); 2000141cc406Sopenharmony_ci free (priv->blue); 2001141cc406Sopenharmony_ci priv->red = priv->blue = NULL; 2002141cc406Sopenharmony_ci priv->green = NULL; 2003141cc406Sopenharmony_ci 2004141cc406Sopenharmony_ci DBG (1, "ccd300_start: not enough memory for ld buffers\n"); 2005141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2006141cc406Sopenharmony_ci } 2007141cc406Sopenharmony_ci 2008141cc406Sopenharmony_ci priv->redline = priv->blueline = priv->ccd_line = 0; 2009141cc406Sopenharmony_ci } 2010141cc406Sopenharmony_ci 2011141cc406Sopenharmony_ci priv->lines = 0; 2012141cc406Sopenharmony_ci priv->lines_left = dev->params.lines; 2013141cc406Sopenharmony_ci 2014141cc406Sopenharmony_ci DBG (3, "ccd300_start: device ready for scanning\n"); 2015141cc406Sopenharmony_ci 2016141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2017141cc406Sopenharmony_ci} 2018141cc406Sopenharmony_ci 2019141cc406Sopenharmony_cistatic void 2020141cc406Sopenharmony_ciccd300_read (SANE_Handle handle, SANE_Byte * buffer) 2021141cc406Sopenharmony_ci{ 2022141cc406Sopenharmony_ci Mustek_pp_Handle *dev = handle; 2023141cc406Sopenharmony_ci mustek_pp_ccd300_priv *priv = dev->priv; 2024141cc406Sopenharmony_ci 2025141cc406Sopenharmony_ci DBG (3, "ccd300_read: receiving one line from port ``%s''\n", 2026141cc406Sopenharmony_ci dev->dev->port); 2027141cc406Sopenharmony_ci 2028141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_TRUE); 2029141cc406Sopenharmony_ci 2030141cc406Sopenharmony_ci switch (dev->mode) 2031141cc406Sopenharmony_ci { 2032141cc406Sopenharmony_ci case MODE_BW: 2033141cc406Sopenharmony_ci get_lineart_line (dev, buffer); 2034141cc406Sopenharmony_ci break; 2035141cc406Sopenharmony_ci 2036141cc406Sopenharmony_ci case MODE_GRAYSCALE: 2037141cc406Sopenharmony_ci get_grayscale_line (dev, buffer); 2038141cc406Sopenharmony_ci break; 2039141cc406Sopenharmony_ci 2040141cc406Sopenharmony_ci case MODE_COLOR: 2041141cc406Sopenharmony_ci get_color_line (dev, buffer); 2042141cc406Sopenharmony_ci break; 2043141cc406Sopenharmony_ci } 2044141cc406Sopenharmony_ci 2045141cc406Sopenharmony_ci priv->lines_left--; 2046141cc406Sopenharmony_ci priv->lines++; 2047141cc406Sopenharmony_ci 2048141cc406Sopenharmony_ci DBG (4, "ccd300_read: %d lines read (%d to go)\n", priv->lines, 2049141cc406Sopenharmony_ci priv->lines_left); 2050141cc406Sopenharmony_ci 2051141cc406Sopenharmony_ci if (priv->lines_left == 0) 2052141cc406Sopenharmony_ci { 2053141cc406Sopenharmony_ci DBG (3, "ccd300_read: scan finished\n"); 2054141cc406Sopenharmony_ci return_home (dev, SANE_TRUE); 2055141cc406Sopenharmony_ci } 2056141cc406Sopenharmony_ci 2057141cc406Sopenharmony_ci sanei_pa4s2_enable (dev->fd, SANE_FALSE); 2058141cc406Sopenharmony_ci 2059141cc406Sopenharmony_ci} 2060