1/*
2 * ESC/I commands for Epson scanners
3 *
4 * Based on Kazuhiro Sasayama previous
5 * Work on epson.[ch] file from the SANE package.
6 * Please see those files for original copyrights.
7 *
8 * Copyright (C) 2006 Tower Technologies
9 * Author: Alessandro Zummo <a.zummo@towertech.it>
10 *
11 * This file is part of the SANE package.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 */
17
18#define DEBUG_DECLARE_ONLY
19
20#include "sane/config.h"
21
22#include <byteorder.h>
23#include <math.h>
24#include <sys/types.h>
25
26#include "epson2.h"
27#include "epson2-io.h"
28#include "epson2-commands.h"
29
30
31/* ESC H, set zoom */
32SANE_Status
33esci_set_zoom(Epson_Scanner * s, unsigned char x, unsigned char y)
34{
35	SANE_Status status;
36	unsigned char params[2];
37
38	DBG(8, "%s: x = %d, y = %d\n", __func__, x, y);
39
40	if (!s->hw->cmd->set_zoom) {
41		DBG(1, "%s: not supported\n", __func__);
42		return SANE_STATUS_GOOD;
43	}
44
45	params[0] = ESC;
46	params[1] = s->hw->cmd->set_zoom;
47
48	status = e2_cmd_simple(s, params, 2);
49	if (status != SANE_STATUS_GOOD)
50		return status;
51
52	params[0] = x;
53	params[1] = y;
54
55	return e2_cmd_simple(s, params, 2);
56}
57
58/* ESC R */
59SANE_Status
60esci_set_resolution(Epson_Scanner * s, int x, int y)
61{
62	SANE_Status status;
63	unsigned char params[4];
64
65	DBG(8, "%s: x = %d, y = %d\n", __func__, x, y);
66
67	if (!s->hw->cmd->set_resolution) {
68		DBG(1, "%s: not supported\n", __func__);
69		return SANE_STATUS_GOOD;
70	}
71
72	params[0] = ESC;
73	params[1] = s->hw->cmd->set_resolution;
74
75	status = e2_cmd_simple(s, params, 2);
76	if (status != SANE_STATUS_GOOD)
77		return status;
78
79	params[0] = x;
80	params[1] = x >> 8;
81	params[2] = y;
82	params[3] = y >> 8;
83
84	return e2_cmd_simple(s, params, 4);
85}
86
87/*
88 * Sends the "set scan area" command to the scanner with the currently selected
89 * scan area. This scan area must be already corrected for "color shuffling" if
90 * necessary.
91 */
92
93SANE_Status
94esci_set_scan_area(Epson_Scanner * s, int x, int y, int width, int height)
95{
96	SANE_Status status;
97	unsigned char params[8];
98
99	DBG(8, "%s: x = %d, y = %d, w = %d, h = %d\n",
100	    __func__, x, y, width, height);
101
102	if (!s->hw->cmd->set_scan_area) {
103		DBG(1, "%s: not supported\n", __func__);
104		return SANE_STATUS_UNSUPPORTED;
105	}
106
107	/* verify the scan area */
108	if (x < 0 || y < 0 || width <= 0 || height <= 0)
109		return SANE_STATUS_INVAL;
110
111	params[0] = ESC;
112	params[1] = s->hw->cmd->set_scan_area;
113
114	status = e2_cmd_simple(s, params, 2);
115	if (status != SANE_STATUS_GOOD)
116		return status;
117
118	params[0] = x;
119	params[1] = x >> 8;
120	params[2] = y;
121	params[3] = y >> 8;
122	params[4] = width;
123	params[5] = width >> 8;
124	params[6] = height;
125	params[7] = height >> 8;
126
127	return e2_cmd_simple(s, params, 8);
128}
129
130static int
131get_roundup_index(double frac[], int n)
132{
133	int i, index = -1;
134	double max_val = 0.0;
135
136	for (i = 0; i < n; i++) {
137
138		if (frac[i] < 0)
139			continue;
140
141		if (max_val < frac[i]) {
142			index = i;
143			max_val = frac[i];
144		}
145	}
146
147	return index;
148}
149
150static int
151get_rounddown_index(double frac[], int n)
152{
153	int i, index = -1;
154	double min_val = 1.0;
155
156	for (i = 0; i < n; i++) {
157
158		if (frac[i] > 0)
159			continue;
160
161		if (min_val > frac[i]) {
162			index = i;
163			min_val = frac[i];
164		}
165	}
166
167	return index;
168}
169
170static unsigned char
171int2cpt(int val)
172{
173	if (val >= 0) {
174
175		if (val > 127)
176			val = 127;
177
178		return (unsigned char) val;
179
180	} else {
181
182		val = -val;
183
184		if (val > 127)
185			val = 127;
186
187		return (unsigned char) (0x80 | val);
188	}
189}
190
191static void
192round_cct(double org_cct[], int rnd_cct[])
193{
194	int loop = 0;
195	int i, j, sum[3];
196	double mult_cct[9], frac[9];
197
198	for (i = 0; i < 9; i++) {
199  		mult_cct[i] = org_cct[i] * 32;
200		rnd_cct[i] = (int) floor(mult_cct[i] + 0.5);
201	}
202
203	do {
204		for (i = 0; i < 3; i++) {
205
206			int k = i * 3;
207
208			if ((rnd_cct[k] == 11) &&
209				(rnd_cct[k] == rnd_cct[k + 1]) &&
210				(rnd_cct[k] == rnd_cct[k + 2])) {
211
212				rnd_cct[k + i]--;
213				mult_cct[k + i] = rnd_cct[k + i];
214			}
215		}
216
217		for (i = 0; i < 3; i++) {
218
219			int k = i * 3;
220
221			for (sum[i] = j = 0; j < 3; j++)
222				sum[i] += rnd_cct[k + j];
223		}
224
225		for (i = 0; i < 9; i++)
226			frac[i] = mult_cct[i] - rnd_cct[i];
227
228		for (i = 0; i < 3; i++) {
229
230			int k = i * 3;
231
232			if (sum[i] < 32) {
233
234				int index = get_roundup_index(&frac[k], 3);
235				if (index != -1) {
236					rnd_cct[k + index]++;
237					mult_cct[k + index] = rnd_cct[k + index];
238					sum[i]++;
239				}
240
241			} else if (sum[i] > 32) {
242
243				int index = get_rounddown_index(&frac[k], 3);
244				if (index != -1) {
245					rnd_cct[k + index]--;
246					mult_cct[k + index] = rnd_cct[k + index];
247					sum[i]--;
248				}
249			}
250		}
251	}
252
253	while ((++loop < 2)
254		&& ((sum[0] != 32) || (sum[1] != 32) || (sum[2] != 32)));
255}
256
257static void
258profile_to_colorcoeff(double *profile, unsigned char *color_coeff)
259{
260	int cc_idx[] = { 4, 1, 7, 3, 0, 6, 5, 2, 8 };
261	int i, color_table[9];
262
263  	round_cct(profile, color_table);
264
265  	for (i = 0; i < 9; i++)
266  		color_coeff[i] = int2cpt(color_table[cc_idx[i]]);
267}
268
269
270/*
271 * Sends the "set color correction coefficients" command with the
272 * currently selected parameters to the scanner.
273 */
274
275SANE_Status
276esci_set_color_correction_coefficients(Epson_Scanner * s, SANE_Word *table)
277{
278	SANE_Status status;
279	unsigned char params[2];
280	unsigned char data[9];
281	double cct[9];
282
283	DBG(8, "%s\n", __func__);
284	if (!s->hw->cmd->set_color_correction_coefficients) {
285		DBG(1, "%s: not supported\n", __func__);
286		return SANE_STATUS_UNSUPPORTED;
287	}
288
289	params[0] = ESC;
290	params[1] = s->hw->cmd->set_color_correction_coefficients;
291
292	status = e2_cmd_simple(s, params, 2);
293	if (status != SANE_STATUS_GOOD)
294		return status;
295
296	cct[0] = SANE_UNFIX(table[0]);
297	cct[1] = SANE_UNFIX(table[1]);
298	cct[2] = SANE_UNFIX(table[2]);
299	cct[3] = SANE_UNFIX(table[3]);
300	cct[4] = SANE_UNFIX(table[4]);
301	cct[5] = SANE_UNFIX(table[5]);
302	cct[6] = SANE_UNFIX(table[6]);
303	cct[7] = SANE_UNFIX(table[7]);
304	cct[8] = SANE_UNFIX(table[8]);
305
306	profile_to_colorcoeff(cct, data);
307
308	DBG(11, "%s: %d,%d,%d %d,%d,%d %d,%d,%d\n", __func__,
309	    data[0] , data[1], data[2], data[3],
310	    data[4], data[5], data[6], data[7], data[8]);
311
312	return e2_cmd_simple(s, data, 9);
313}
314
315SANE_Status
316esci_set_gamma_table(Epson_Scanner * s)
317{
318	SANE_Status status;
319	unsigned char params[2];
320	unsigned char gamma[257];
321	int n;
322	int table;
323
324/*	static const char gamma_cmds[] = { 'M', 'R', 'G', 'B' }; */
325	static const char gamma_cmds[] = { 'R', 'G', 'B' };
326
327	DBG(8, "%s\n", __func__);
328	if (!s->hw->cmd->set_gamma_table)
329		return SANE_STATUS_UNSUPPORTED;
330
331	params[0] = ESC;
332	params[1] = s->hw->cmd->set_gamma_table;
333
334	/* Print the gamma tables before sending them to the scanner */
335
336	if (DBG_LEVEL >= 16) {
337		int c, i, j;
338
339		for (c = 0; c < 3; c++) {
340			for (i = 0; i < 256; i += 16) {
341				char gammaValues[16 * 3 + 1], newValue[4];
342
343				gammaValues[0] = '\0';
344
345				for (j = 0; j < 16; j++) {
346					sprintf(newValue, " %02x",
347						s->gamma_table[c][i + j]);
348					strcat(gammaValues, newValue);
349				}
350
351				DBG(16, "gamma table[%d][%d] %s\n", c, i,
352				    gammaValues);
353			}
354		}
355	}
356
357	for (table = 0; table < 3; table++) {
358		gamma[0] = gamma_cmds[table];
359
360		for (n = 0; n < 256; ++n)
361			gamma[n + 1] = s->gamma_table[table][n];
362
363		status = e2_cmd_simple(s, params, 2);
364		if (status != SANE_STATUS_GOOD)
365			return status;
366
367		status = e2_cmd_simple(s, gamma, 257);
368		if (status != SANE_STATUS_GOOD)
369			return status;
370	}
371
372	return status;
373}
374
375/* ESC F - Request Status
376 * -> ESC f
377 * <- Information block
378 */
379
380SANE_Status
381esci_request_status(SANE_Handle handle, unsigned char *scanner_status)
382{
383	Epson_Scanner *s = (Epson_Scanner *) handle;
384	SANE_Status status;
385	unsigned char params[2];
386
387	DBG(8, "%s\n", __func__);
388
389	if (s->hw->cmd->request_status == 0)
390		return SANE_STATUS_UNSUPPORTED;
391
392	params[0] = ESC;
393	params[1] = s->hw->cmd->request_status;
394
395	e2_send(s, params, 2, 4, &status);
396	if (status != SANE_STATUS_GOOD)
397		return status;
398
399	status = e2_recv_info_block(s, params, 4, NULL);
400	if (status != SANE_STATUS_GOOD)
401		return status;
402
403	if (scanner_status)
404		*scanner_status = params[0];
405
406	DBG(1, "status: %02x\n", params[0]);
407
408	if (params[0] & STATUS_NOT_READY)
409		DBG(1, " scanner in use on another interface\n");
410	else
411		DBG(1, " ready\n");
412
413	if (params[0] & STATUS_FER)
414		DBG(1, " system error\n");
415
416	if (params[0] & STATUS_OPTION)
417		DBG(1, " option equipment is installed\n");
418	else
419		DBG(1, " no option equipment installed\n");
420
421	if (params[0] & STATUS_EXT_COMMANDS)
422		DBG(1, " support extended commands\n");
423	else
424		DBG(1, " does NOT support extended commands\n");
425
426	if (params[0] & STATUS_RESERVED)
427		DBG(0,
428		    " a reserved bit is set, please contact the author.\n");
429
430	return status;
431}
432
433/* extended commands */
434
435/* FS I, Request Extended Identity
436 * -> FS I
437 * <- Extended identity data (80)
438 *
439 * Request the properties of the scanner.
440 */
441
442SANE_Status
443esci_request_extended_identity(SANE_Handle handle, unsigned char *buf)
444{
445	unsigned char model[17];
446	Epson_Scanner *s = (Epson_Scanner *) handle;
447	SANE_Status status;
448	unsigned char params[2];
449
450	DBG(8, "%s\n", __func__);
451
452	if (buf == NULL)
453		return SANE_STATUS_INVAL;
454
455	if (s->hw->cmd->request_extended_identity == 0)
456		return SANE_STATUS_UNSUPPORTED;
457
458	params[0] = FS;
459	params[1] = s->hw->cmd->request_extended_identity;
460
461	status = e2_txrx(s, params, 2, buf, 80);
462	if (status != SANE_STATUS_GOOD)
463		return status;
464
465	DBG(1, " command level   : %c%c\n", buf[0], buf[1]);
466	DBG(1, " basic resolution: %lu\n", (unsigned long) le32atoh(&buf[4]));
467	DBG(1, " min resolution  : %lu\n", (unsigned long) le32atoh(&buf[8]));
468	DBG(1, " max resolution  : %lu\n", (unsigned long) le32atoh(&buf[12]));
469	DBG(1, " max pixel num   : %lu\n", (unsigned long) le32atoh(&buf[16]));
470	DBG(1, " scan area       : %lux%lu\n",
471	    (unsigned long) le32atoh(&buf[20]), (unsigned long) le32atoh(&buf[24]));
472
473	DBG(1, " adf area        : %lux%lu\n",
474	    (unsigned long) le32atoh(&buf[28]), (unsigned long) le32atoh(&buf[32]));
475
476	DBG(1, " tpu area        : %lux%lu\n",
477	    (unsigned long) le32atoh(&buf[36]), (unsigned long) le32atoh(&buf[40]));
478
479	DBG(1, " capabilities (1): 0x%02x\n", buf[44]);
480	DBG(1, " capabilities (2): 0x%02x\n", buf[45]);
481	DBG(1, " input depth     : %d\n", buf[66]);
482	DBG(1, " max output depth: %d\n", buf[67]);
483	DBG(1, " rom version     : %c%c%c%c\n",
484	    buf[62], buf[63], buf[64], buf[65]);
485
486	memcpy(model, &buf[46], 16);
487	model[16] = '\0';
488	DBG(1, " model name      : %s\n", model);
489
490	DBG(1, "options:\n");
491
492	if (le32atoh(&buf[28]) > 0)
493		DBG(1, " ADF detected\n");
494
495	if (le32atoh(&buf[36]) > 0)
496		DBG(1, " TPU detected\n");
497
498	if (buf[44])
499		DBG(1, "capabilities (1):\n");
500
501	if (buf[44] & EXT_IDTY_CAP1_DLF)
502		DBG(1, " main lamp change is supported\n");
503
504	if (buf[44] & EXT_IDTY_CAP1_NOTFBF)
505		DBG(1, " the device is NOT flatbed\n");
506
507	if (buf[44] & EXT_IDTY_CAP1_ADFT)
508		DBG(1, " page type ADF is installed\n");
509
510	if (buf[44] & EXT_IDTY_CAP1_ADFS)
511		DBG(1, " ADF is duplex capable\n");
512
513	if (buf[44] & EXT_IDTY_CAP1_ADFO)
514		DBG(1, " page type ADF loads from the first sheet\n");
515
516	if (buf[44] & EXT_IDTY_CAP1_LID)
517		DBG(1, " lid type option is installed\n");
518
519	if (buf[44] & EXT_IDTY_CAP1_TPIR)
520		DBG(1, " infrared scanning is supported\n");
521
522	if (buf[44] & EXT_IDTY_CAP1_PB)
523		DBG(1, " push button is supported\n");
524
525
526	if (buf[45])
527		DBG(1, "capabilities (2):\n");
528
529	if (buf[45] & EXT_IDTY_CAP2_AFF)
530		DBG(1, " ADF has auto form feed\n");
531
532	if (buf[45] & EXT_IDTY_CAP2_DFD)
533		DBG(1, " ADF has double feed detection\n");
534
535	if (buf[45] & EXT_IDTY_CAP2_ADFAS)
536		DBG(1, " ADF has auto scan\n");
537
538	return SANE_STATUS_GOOD;
539}
540
541/* FS F, request scanner status */
542SANE_Status
543esci_request_scanner_status(SANE_Handle handle, unsigned char *buf)
544{
545	Epson_Scanner *s = (Epson_Scanner *) handle;
546	SANE_Status status;
547	unsigned char params[2];
548
549	DBG(8, "%s\n", __func__);
550
551	if (!s->hw->extended_commands)
552		return SANE_STATUS_UNSUPPORTED;
553
554	if (buf == NULL)
555		return SANE_STATUS_INVAL;
556
557	params[0] = FS;
558	params[1] = 'F';
559
560	status = e2_txrx(s, params, 2, buf, 16);
561	if (status != SANE_STATUS_GOOD)
562		return status;
563
564	DBG(1, "global status   : 0x%02x\n", buf[0]);
565
566	if (buf[0] & FSF_STATUS_MAIN_FER)
567		DBG(1, " system error\n");
568
569	if (buf[0] & FSF_STATUS_MAIN_NR)
570		DBG(1, " not ready\n");
571
572	if (buf[0] & FSF_STATUS_MAIN_WU)
573		DBG(1, " scanner is warming up\n");
574
575	if (buf[0] & FSF_STATUS_MAIN_CWU)
576		DBG(1, " warmup can be cancelled\n");
577
578
579	DBG(1, "adf status      : 0x%02x\n", buf[1]);
580
581	if (buf[1] & FSF_STATUS_ADF_IST)
582		DBG(11, " installed\n");
583	else
584		DBG(11, " not installed\n");
585
586	if (buf[1] & FSF_STATUS_ADF_EN)
587		DBG(11, " enabled\n");
588	else
589		DBG(11, " not enabled\n");
590
591	if (buf[1] & FSF_STATUS_ADF_ERR)
592		DBG(1, " error\n");
593
594	if (buf[1] & FSF_STATUS_ADF_PE)
595		DBG(1, " paper empty\n");
596
597	if (buf[1] & FSF_STATUS_ADF_PJ)
598		DBG(1, " paper jam\n");
599
600	if (buf[1] & FSF_STATUS_ADF_OPN)
601		DBG(1, " cover open\n");
602
603	if (buf[1] & FSF_STATUS_ADF_PAG)
604		DBG(1, " duplex capable\n");
605
606
607	DBG(1, "tpu status      : 0x%02x\n", buf[2]);
608
609	if (buf[2] & FSF_STATUS_TPU_IST)
610		DBG(11, " installed\n");
611	else
612		DBG(11, " not installed\n");
613
614	if (buf[2] & FSF_STATUS_TPU_EN)
615		DBG(11, " enabled\n");
616	else
617		DBG(11, " not enabled\n");
618
619	if (buf[2] & FSF_STATUS_TPU_ERR)
620		DBG(1, " error\n");
621
622	if (buf[1] & FSF_STATUS_TPU_OPN)
623		DBG(1, " cover open\n");
624
625
626	DBG(1, "device type     : 0x%02x\n", buf[3] & 0xC0);
627	DBG(1, "main body status: 0x%02x\n", buf[3] & 0x3F);
628
629	if (buf[3] & FSF_STATUS_MAIN2_PE)
630		DBG(1, " paper empty\n");
631
632	if (buf[3] & FSF_STATUS_MAIN2_PJ)
633		DBG(1, " paper jam\n");
634
635	if (buf[3] & FSF_STATUS_MAIN2_OPN)
636		DBG(1, " cover open\n");
637
638	return SANE_STATUS_GOOD;
639}
640
641SANE_Status
642esci_set_scanning_parameter(SANE_Handle handle, unsigned char *buf)
643{
644	Epson_Scanner *s = (Epson_Scanner *) handle;
645	SANE_Status status;
646	unsigned char params[2];
647
648	DBG(8, "%s\n", __func__);
649
650	if (buf == NULL)
651		return SANE_STATUS_INVAL;
652
653	params[0] = FS;
654	params[1] = 'W';
655
656	DBG(10, "resolution of main scan     : %lu\n", (unsigned long) le32atoh(&buf[0]));
657	DBG(10, "resolution of sub scan      : %lu\n", (unsigned long) le32atoh(&buf[4]));
658	DBG(10, "offset length of main scan  : %lu\n", (unsigned long) le32atoh(&buf[8]));
659	DBG(10, "offset length of sub scan   : %lu\n", (unsigned long) le32atoh(&buf[12]));
660	DBG(10, "scanning length of main scan: %lu\n", (unsigned long) le32atoh(&buf[16]));
661	DBG(10, "scanning length of sub scan : %lu\n", (unsigned long) le32atoh(&buf[20]));
662	DBG(10, "scanning color              : %d\n", buf[24]);
663	DBG(10, "data format                 : %d\n", buf[25]);
664	DBG(10, "option control              : %d\n", buf[26]);
665	DBG(10, "scanning mode               : %d\n", buf[27]);
666	DBG(10, "block line number           : %d\n", buf[28]);
667	DBG(10, "gamma correction            : %d\n", buf[29]);
668	DBG(10, "brightness                  : %d\n", buf[30]);
669	DBG(10, "color correction            : %d\n", buf[31]);
670	DBG(10, "halftone processing         : %d\n", buf[32]);
671	DBG(10, "threshold                   : %d\n", buf[33]);
672	DBG(10, "auto area segmentation      : %d\n", buf[34]);
673	DBG(10, "sharpness control           : %d\n", buf[35]);
674	DBG(10, "mirroring                   : %d\n", buf[36]);
675	DBG(10, "film type                   : %d\n", buf[37]);
676	DBG(10, "main lamp lighting mode     : %d\n", buf[38]);
677
678	status = e2_cmd_simple(s, params, 2);
679	if (status != SANE_STATUS_GOOD)
680		return status;
681
682	status = e2_cmd_simple(s, buf, 64);
683	if (status != SANE_STATUS_GOOD) {
684		DBG(1, "%s: invalid scanning parameters\n", __func__);
685		return status;
686	}
687
688	return SANE_STATUS_GOOD;
689}
690
691/* FS S */
692
693SANE_Status
694esci_get_scanning_parameter(SANE_Handle handle, unsigned char *buf)
695{
696	Epson_Scanner *s = (Epson_Scanner *) handle;
697	SANE_Status status;
698	unsigned char params[2];
699
700	DBG(8, "%s\n", __func__);
701
702	if (buf == NULL)
703		return SANE_STATUS_INVAL;
704
705	params[0] = FS;
706	params[1] = 'S';
707
708	status = e2_txrx(s, params, 2, buf, 64);
709	if (status != SANE_STATUS_GOOD)
710		return status;
711
712	DBG(10, "resolution of main scan     : %lu\n",
713	    (u_long) le32atoh(&buf[0]));
714	DBG(10, "resolution of sub scan      : %lu\n",
715	    (u_long) le32atoh(&buf[4]));
716	DBG(10, "offset length of main scan  : %lu\n",
717	    (u_long) le32atoh(&buf[8]));
718	DBG(10, "offset length of sub scan   : %lu\n",
719	    (u_long) le32atoh(&buf[12]));
720	DBG(10, "scanning length of main scan: %lu\n",
721	    (u_long) le32atoh(&buf[16]));
722	DBG(10, "scanning length of sub scan : %lu\n",
723	    (u_long) le32atoh(&buf[20]));
724	DBG(10, "scanning color              : %d\n", buf[24]);
725	DBG(10, "data format                 : %d\n", buf[25]);
726	DBG(10, "option control              : %d\n", buf[26]);
727	DBG(10, "scanning mode               : %d\n", buf[27]);
728	DBG(10, "block line number           : %d\n", buf[28]);
729	DBG(10, "gamma correction            : %d\n", buf[29]);
730	DBG(10, "brightness                  : %d\n", buf[30]);
731	DBG(10, "color correction            : %d\n", buf[31]);
732	DBG(10, "halftone processing         : %d\n", buf[32]);
733	DBG(10, "threshold                   : %d\n", buf[33]);
734	DBG(10, "auto area segmentation      : %d\n", buf[34]);
735	DBG(10, "sharpness control           : %d\n", buf[35]);
736	DBG(10, "mirroring                   : %d\n", buf[36]);
737	DBG(10, "film type                   : %d\n", buf[37]);
738	DBG(10, "main lamp lighting mode     : %d\n", buf[38]);
739
740	return SANE_STATUS_GOOD;
741}
742
743/* ESC # */
744
745SANE_Status
746esci_enable_infrared(SANE_Handle handle)
747{
748	Epson_Scanner *s = (Epson_Scanner *) handle;
749	SANE_Status status;
750	int i;
751	unsigned char params[2];
752	unsigned char buf[64];
753
754	unsigned char seq[32] = {
755		0xCA, 0xFB, 0x77, 0x71, 0x20, 0x16, 0xDA, 0x09,
756		0x5F, 0x57, 0x09, 0x12, 0x04, 0x83, 0x76, 0x77,
757		0x3C, 0x73, 0x9C, 0xBE, 0x7A, 0xE0, 0x52, 0xE2,
758		0x90, 0x0D, 0xFF, 0x9A, 0xEF, 0x4C, 0x2C, 0x81
759	};
760
761	DBG(8, "%s\n", __func__);
762
763	status = esci_get_scanning_parameter(handle, buf);
764	if (status != SANE_STATUS_GOOD)
765		return status;
766
767	for (i = 0; i < 32; i++) {
768		buf[i] = seq[i] ^ buf[i];
769	}
770
771	params[0] = ESC;
772	params[1] = '#';
773
774	status = e2_cmd_simple(s, params, 2);
775	if (status != SANE_STATUS_GOOD)
776		return status;
777
778	status = e2_cmd_simple(s, buf, 32);
779	if (status != SANE_STATUS_GOOD)
780		return status;
781
782	return SANE_STATUS_GOOD;
783}
784
785SANE_Status
786esci_request_command_parameter(SANE_Handle handle, unsigned char *buf)
787{
788	Epson_Scanner *s = (Epson_Scanner *) handle;
789	SANE_Status status;
790	unsigned char params[2];
791
792	DBG(8, "%s\n", __func__);
793
794	if (s->hw->cmd->request_condition == 0)
795		return SANE_STATUS_UNSUPPORTED;
796
797	params[0] = ESC;
798	params[1] = s->hw->cmd->request_condition;
799
800	status = e2_cmd_info_block(s, params, 2, 45, &buf, NULL);
801	if (status != SANE_STATUS_GOOD)
802		return status;
803
804	DBG(1, "scanning parameters:\n");
805	DBG(1, "color                  : %d\n", buf[1]);
806	DBG(1, "resolution             : %dx%d\n",
807	    buf[4] << 8 | buf[3], buf[6] << 8 | buf[5]);
808	DBG(1, "halftone               : %d\n", buf[19]);
809	DBG(1, "brightness             : %d\n", buf[21]);
810	DBG(1, "color correction       : %d\n", buf[28]);
811	DBG(1, "gamma                  : %d\n", buf[23]);
812	DBG(1, "sharpness              : %d\n", buf[30]);
813	DBG(1, "threshold              : %d\n", buf[38]);
814	DBG(1, "data format            : %d\n", buf[17]);
815	DBG(1, "mirroring              : %d\n", buf[34]);
816	DBG(1, "option unit control    : %d\n", buf[42]);
817	DBG(1, "film type              : %d\n", buf[44]);
818	DBG(1, "auto area segmentation : %d\n", buf[36]);
819	DBG(1, "line counter           : %d\n", buf[40]);
820	DBG(1, "scanning mode          : %d\n", buf[32]);
821	DBG(1, "zoom                   : %d,%d\n", buf[26], buf[25]);
822	DBG(1, "scan area              : %d,%d %d,%d\n",
823	    buf[9] << 8 | buf[8], buf[11] << 8 | buf[10],
824	    buf[13] << 8 | buf[12], buf[15] << 8 | buf[14]);
825	return status;
826}
827
828/* ESC q - Request Focus Position
829 * -> ESC q
830 * <- Information block
831 * <- Focus position status (2)
832 *	0 - Error status
833 *	1 - Focus position
834 */
835
836SANE_Status
837esci_request_focus_position(SANE_Handle handle, unsigned char *position)
838{
839	SANE_Status status;
840	unsigned char *buf;
841	Epson_Scanner *s = (Epson_Scanner *) handle;
842
843	unsigned char params[2];
844
845	DBG(8, "%s\n", __func__);
846
847	if (s->hw->cmd->request_focus_position == 0)
848		return SANE_STATUS_UNSUPPORTED;
849
850	params[0] = ESC;
851	params[1] = s->hw->cmd->request_focus_position;
852
853	status = e2_cmd_info_block(s, params, 2, 2, &buf, NULL);
854	if (status != SANE_STATUS_GOOD)
855		return status;
856
857	if (buf[0] & 0x01)
858		DBG(1, "autofocus error\n");
859
860	*position = buf[1];
861	DBG(8, " focus position = 0x%x\n", buf[1]);
862
863	free(buf);
864
865	return status;
866}
867
868/* ESC ! - Request Push Button Status
869 * -> ESC !
870 * <- Information block
871 * <- Push button status (1)
872 */
873
874SANE_Status
875esci_request_push_button_status(SANE_Handle handle, unsigned char *bstatus)
876{
877	Epson_Scanner *s = (Epson_Scanner *) handle;
878	SANE_Status status;
879	unsigned char params[2];
880	unsigned char *buf;
881
882	DBG(8, "%s\n", __func__);
883
884	if (s->hw->cmd->request_push_button_status == 0) {
885		DBG(1, "push button status unsupported\n");
886		return SANE_STATUS_UNSUPPORTED;
887	}
888
889	params[0] = ESC;
890	params[1] = s->hw->cmd->request_push_button_status;
891
892	status = e2_cmd_info_block(s, params, 2, 1, &buf, NULL);
893	if (status != SANE_STATUS_GOOD)
894		return status;
895
896	DBG(1, "push button status = %d\n", buf[0]);
897	*bstatus = buf[0];
898
899	free(buf);
900
901	return status;
902}
903
904
905/*
906 * Request Identity information from scanner and fill in information
907 * into dev and/or scanner structures.
908 * XXX information should be parsed separately.
909 */
910SANE_Status
911esci_request_identity(SANE_Handle handle, unsigned char **buf, size_t *len)
912{
913	Epson_Scanner *s = (Epson_Scanner *) handle;
914	unsigned char params[2];
915
916	DBG(8, "%s\n", __func__);
917
918	if (!s->hw->cmd->request_identity)
919		return SANE_STATUS_INVAL;
920
921	params[0] = ESC;
922	params[1] = s->hw->cmd->request_identity;
923
924	return e2_cmd_info_block(s, params, 2, 0, buf, len);
925}
926
927
928/*
929 * Request information from scanner
930 */
931SANE_Status
932esci_request_identity2(SANE_Handle handle, unsigned char **buf)
933{
934	Epson_Scanner *s = (Epson_Scanner *) handle;
935	SANE_Status status;
936	size_t len;
937	unsigned char params[2];
938
939	DBG(8, "%s\n", __func__);
940
941	if (s->hw->cmd->request_identity2 == 0)
942		return SANE_STATUS_UNSUPPORTED;
943
944	params[0] = ESC;
945	params[1] = s->hw->cmd->request_identity2;
946
947	status = e2_cmd_info_block(s, params, 2, 0, buf, &len);
948	if (status != SANE_STATUS_GOOD)
949		return status;
950
951	return status;
952}
953
954/* Send the "initialize scanner" command to the device and reset it */
955
956SANE_Status
957esci_reset(Epson_Scanner * s)
958{
959	SANE_Status status;
960	unsigned char params[2];
961
962	DBG(8, "%s\n", __func__);
963
964	if (!s->hw->cmd->initialize_scanner)
965		return SANE_STATUS_GOOD;
966
967	params[0] = ESC;
968	params[1] = s->hw->cmd->initialize_scanner;
969
970	if (s->fd == -1)
971		return SANE_STATUS_GOOD;
972
973	status = e2_cmd_simple(s, params, 2);
974
975	return status;
976}
977
978SANE_Status
979esci_feed(Epson_Scanner * s)
980{
981	unsigned char params[1];
982
983	DBG(8, "%s\n", __func__);
984
985	if (!s->hw->cmd->feed)
986		return SANE_STATUS_UNSUPPORTED;
987
988	params[0] = s->hw->cmd->feed;
989
990	return e2_cmd_simple(s, params, 1);
991}
992
993
994/*
995 * Eject the current page from the ADF. The scanner is opened prior to
996 * sending the command and closed afterwards.
997 */
998
999SANE_Status
1000esci_eject(Epson_Scanner * s)
1001{
1002	unsigned char params[1];
1003
1004	DBG(8, "%s\n", __func__);
1005
1006	if (!s->hw->cmd->eject)
1007		return SANE_STATUS_UNSUPPORTED;
1008
1009	if (s->fd == -1)
1010		return SANE_STATUS_GOOD;
1011
1012	params[0] = s->hw->cmd->eject;
1013
1014	return e2_cmd_simple(s, params, 1);
1015}
1016
1017SANE_Status
1018esci_request_extended_status(SANE_Handle handle, unsigned char **data,
1019			size_t * data_len)
1020{
1021	Epson_Scanner *s = (Epson_Scanner *) handle;
1022	SANE_Status status = SANE_STATUS_GOOD;
1023	unsigned char params[2];
1024	unsigned char *buf;
1025	size_t buf_len;
1026
1027	DBG(8, "%s\n", __func__);
1028
1029	if (s->hw->cmd->request_extended_status == 0)
1030		return SANE_STATUS_UNSUPPORTED;
1031
1032	params[0] = ESC;
1033	params[1] = s->hw->cmd->request_extended_status;
1034
1035	/* This command returns 33 bytes of data on old scanners
1036	 * and 42 (CMD_SIZE_EXT_STATUS) on new ones.
1037	 */
1038	status = e2_cmd_info_block(s, params, 2, CMD_SIZE_EXT_STATUS,
1039				       &buf, &buf_len);
1040	if (status != SANE_STATUS_GOOD)
1041		return status;
1042
1043	switch (buf_len) {
1044	case 33:
1045	case 42:
1046		break;
1047	default:
1048		DBG(1, "%s: unknown reply length (%lu)\n", __func__,
1049			(unsigned long) buf_len);
1050		break;
1051	}
1052
1053	DBG(4, "main = %02x, ADF = %02x, TPU = %02x, main 2 = %02x\n",
1054		buf[0], buf[1], buf[6], buf[11]);
1055
1056	if (buf[0] & EXT_STATUS_FER)
1057		DBG(1, "system error\n");
1058
1059	if (buf[0] & EXT_STATUS_WU)
1060		DBG(1, "scanner is warming up\n");
1061
1062	if (buf[1] & EXT_STATUS_ERR)
1063		DBG(1, "ADF: other error\n");
1064
1065	if (buf[1] & EXT_STATUS_PE)
1066		DBG(1, "ADF: no paper\n");
1067
1068	if (buf[1] & EXT_STATUS_PJ)
1069		DBG(1, "ADF: paper jam\n");
1070
1071	if (buf[1] & EXT_STATUS_OPN)
1072		DBG(1, "ADF: cover open\n");
1073
1074	if (buf[6] & EXT_STATUS_ERR)
1075		DBG(1, "TPU: other error\n");
1076
1077	/* give back a pointer to the payload
1078	 * if the user requested it, otherwise
1079	 * free it.
1080	 */
1081
1082	if (data)
1083		*data = buf;
1084	else
1085		free(buf);
1086
1087	if (data_len)
1088		*data_len = buf_len;
1089
1090	return status;
1091}
1092