1141cc406Sopenharmony_ci/* SANE - Scanner Access Now Easy.
2141cc406Sopenharmony_ci
3141cc406Sopenharmony_ci   Copyright (C) 2011-2020 Rolf Bensch <rolf at bensch hyphen online dot de>
4141cc406Sopenharmony_ci   Copyright (C) 2007-2009 Nicolas Martin, <nicols-guest at alioth dot debian dot org>
5141cc406Sopenharmony_ci   Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
6141cc406Sopenharmony_ci
7141cc406Sopenharmony_ci   This file is part of the SANE package.
8141cc406Sopenharmony_ci
9141cc406Sopenharmony_ci   This program is free software; you can redistribute it and/or
10141cc406Sopenharmony_ci   modify it under the terms of the GNU General Public License as
11141cc406Sopenharmony_ci   published by the Free Software Foundation; either version 2 of the
12141cc406Sopenharmony_ci   License, or (at your option) any later version.
13141cc406Sopenharmony_ci
14141cc406Sopenharmony_ci   This program is distributed in the hope that it will be useful, but
15141cc406Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
16141cc406Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17141cc406Sopenharmony_ci   General Public License for more details.
18141cc406Sopenharmony_ci
19141cc406Sopenharmony_ci   You should have received a copy of the GNU General Public License
20141cc406Sopenharmony_ci   along with this program.  If not, see <https://www.gnu.org/licenses/>.
21141cc406Sopenharmony_ci
22141cc406Sopenharmony_ci   As a special exception, the authors of SANE give permission for
23141cc406Sopenharmony_ci   additional uses of the libraries contained in this release of SANE.
24141cc406Sopenharmony_ci
25141cc406Sopenharmony_ci   The exception is that, if you link a SANE library with other files
26141cc406Sopenharmony_ci   to produce an executable, this does not by itself cause the
27141cc406Sopenharmony_ci   resulting executable to be covered by the GNU General Public
28141cc406Sopenharmony_ci   License.  Your use of that executable is in no way restricted on
29141cc406Sopenharmony_ci   account of linking the SANE library code into it.
30141cc406Sopenharmony_ci
31141cc406Sopenharmony_ci   This exception does not, however, invalidate any other reasons why
32141cc406Sopenharmony_ci   the executable file might be covered by the GNU General Public
33141cc406Sopenharmony_ci   License.
34141cc406Sopenharmony_ci
35141cc406Sopenharmony_ci   If you submit changes to SANE to the maintainers to be included in
36141cc406Sopenharmony_ci   a subsequent release, you agree by submitting the changes that
37141cc406Sopenharmony_ci   those changes may be distributed with this exception intact.
38141cc406Sopenharmony_ci
39141cc406Sopenharmony_ci   If you write modifications of your own for SANE, it is your choice
40141cc406Sopenharmony_ci   whether to permit this exception to apply to your modifications.
41141cc406Sopenharmony_ci   If you do not wish that, delete this exception notice.
42141cc406Sopenharmony_ci */
43141cc406Sopenharmony_ci/* test cases
44141cc406Sopenharmony_ci   1. short USB packet (must be no -ETIMEDOUT)
45141cc406Sopenharmony_ci   2. cancel using button on the printer (look for abort command)
46141cc406Sopenharmony_ci   3. start scan while busy (status 0x1414)
47141cc406Sopenharmony_ci   4. cancel using ctrl-c (must send abort command)
48141cc406Sopenharmony_ci */
49141cc406Sopenharmony_ci
50141cc406Sopenharmony_ci#include "../include/sane/config.h"
51141cc406Sopenharmony_ci
52141cc406Sopenharmony_ci#include <stdio.h>
53141cc406Sopenharmony_ci#include <stdlib.h>
54141cc406Sopenharmony_ci#include <string.h>
55141cc406Sopenharmony_ci#include <time.h>		/* localtime(C90) */
56141cc406Sopenharmony_ci
57141cc406Sopenharmony_ci#include "pixma_rename.h"
58141cc406Sopenharmony_ci#include "pixma_common.h"
59141cc406Sopenharmony_ci#include "pixma_io.h"
60141cc406Sopenharmony_ci
61141cc406Sopenharmony_ci/* Some macro code to enhance readability */
62141cc406Sopenharmony_ci#define RET_IF_ERR(x) do {	\
63141cc406Sopenharmony_ci    if ((error = (x)) < 0)	\
64141cc406Sopenharmony_ci      return error;		\
65141cc406Sopenharmony_ci  } while(0)
66141cc406Sopenharmony_ci
67141cc406Sopenharmony_ci#define WAIT_INTERRUPT(x) do {			\
68141cc406Sopenharmony_ci    error = handle_interrupt (s, x);		\
69141cc406Sopenharmony_ci    if (s->cancel)				\
70141cc406Sopenharmony_ci      return PIXMA_ECANCELED;			\
71141cc406Sopenharmony_ci    if (error != PIXMA_ECANCELED && error < 0)	\
72141cc406Sopenharmony_ci      return error;				\
73141cc406Sopenharmony_ci  } while(0)
74141cc406Sopenharmony_ci
75141cc406Sopenharmony_ci#ifdef __GNUC__
76141cc406Sopenharmony_ci# define UNUSED(v) (void) v
77141cc406Sopenharmony_ci#else
78141cc406Sopenharmony_ci# define UNUSED(v)
79141cc406Sopenharmony_ci#endif
80141cc406Sopenharmony_ci
81141cc406Sopenharmony_ci/* Size of the command buffer should be multiple of wMaxPacketLength and
82141cc406Sopenharmony_ci   greater than 4096+24.
83141cc406Sopenharmony_ci   4096 = size of gamma table. 24 = header + checksum */
84141cc406Sopenharmony_ci#define IMAGE_BLOCK_SIZE (512*1024)
85141cc406Sopenharmony_ci#define CMDBUF_SIZE (4096 + 24)
86141cc406Sopenharmony_ci#define UNKNOWN_PID 0xffff
87141cc406Sopenharmony_ci
88141cc406Sopenharmony_ci
89141cc406Sopenharmony_ci#define CANON_VID 0x04a9
90141cc406Sopenharmony_ci
91141cc406Sopenharmony_ci/* Generation 1 */
92141cc406Sopenharmony_ci#define MP150_PID 0x1709
93141cc406Sopenharmony_ci#define MP170_PID 0x170a
94141cc406Sopenharmony_ci#define MP450_PID 0x170b
95141cc406Sopenharmony_ci#define MP500_PID 0x170c
96141cc406Sopenharmony_ci#define MP530_PID 0x1712
97141cc406Sopenharmony_ci
98141cc406Sopenharmony_ci/* Generation 2 */
99141cc406Sopenharmony_ci#define MP160_PID 0x1714
100141cc406Sopenharmony_ci#define MP180_PID 0x1715
101141cc406Sopenharmony_ci#define MP460_PID 0x1716
102141cc406Sopenharmony_ci#define MP510_PID 0x1717
103141cc406Sopenharmony_ci#define MP600_PID 0x1718
104141cc406Sopenharmony_ci#define MP600R_PID 0x1719
105141cc406Sopenharmony_ci
106141cc406Sopenharmony_ci#define MP140_PID 0x172b
107141cc406Sopenharmony_ci
108141cc406Sopenharmony_ci/* Generation 3 */
109141cc406Sopenharmony_ci/* PIXMA 2007 vintage */
110141cc406Sopenharmony_ci#define MX7600_PID 0x171c
111141cc406Sopenharmony_ci#define MP210_PID 0x1721
112141cc406Sopenharmony_ci#define MP220_PID 0x1722
113141cc406Sopenharmony_ci#define MP470_PID 0x1723
114141cc406Sopenharmony_ci#define MP520_PID 0x1724
115141cc406Sopenharmony_ci#define MP610_PID 0x1725
116141cc406Sopenharmony_ci#define MX300_PID 0x1727
117141cc406Sopenharmony_ci#define MX310_PID 0x1728
118141cc406Sopenharmony_ci#define MX700_PID 0x1729
119141cc406Sopenharmony_ci#define MX850_PID 0x172c
120141cc406Sopenharmony_ci
121141cc406Sopenharmony_ci/* PIXMA 2008 vintage */
122141cc406Sopenharmony_ci#define MP630_PID 0x172e
123141cc406Sopenharmony_ci#define MP620_PID 0x172f
124141cc406Sopenharmony_ci#define MP540_PID 0x1730
125141cc406Sopenharmony_ci#define MP480_PID 0x1731
126141cc406Sopenharmony_ci#define MP240_PID 0x1732
127141cc406Sopenharmony_ci#define MP260_PID 0x1733
128141cc406Sopenharmony_ci#define MP190_PID 0x1734
129141cc406Sopenharmony_ci
130141cc406Sopenharmony_ci/* PIXMA 2009 vintage */
131141cc406Sopenharmony_ci#define MX860_PID 0x1735
132141cc406Sopenharmony_ci#define MX320_PID 0x1736    /* untested */
133141cc406Sopenharmony_ci#define MX330_PID 0x1737
134141cc406Sopenharmony_ci
135141cc406Sopenharmony_ci/* Generation 4 */
136141cc406Sopenharmony_ci#define MP250_PID 0x173a
137141cc406Sopenharmony_ci#define MP270_PID 0x173b
138141cc406Sopenharmony_ci#define MP490_PID 0x173c
139141cc406Sopenharmony_ci#define MP550_PID 0x173d
140141cc406Sopenharmony_ci#define MP560_PID 0x173e
141141cc406Sopenharmony_ci#define MP640_PID 0x173f
142141cc406Sopenharmony_ci
143141cc406Sopenharmony_ci/* PIXMA 2010 vintage */
144141cc406Sopenharmony_ci#define MX340_PID 0x1741
145141cc406Sopenharmony_ci#define MX350_PID 0x1742
146141cc406Sopenharmony_ci#define MX870_PID 0x1743
147141cc406Sopenharmony_ci
148141cc406Sopenharmony_ci/* 2010 new devices (untested) */
149141cc406Sopenharmony_ci#define MP280_PID 0x1746
150141cc406Sopenharmony_ci#define MP495_PID 0x1747
151141cc406Sopenharmony_ci#define MG5100_PID 0x1748
152141cc406Sopenharmony_ci#define MG5200_PID 0x1749
153141cc406Sopenharmony_ci#define MG6100_PID 0x174a
154141cc406Sopenharmony_ci
155141cc406Sopenharmony_ci/* PIXMA 2011 vintage */
156141cc406Sopenharmony_ci#define MX360_PID 0x174d
157141cc406Sopenharmony_ci#define MX410_PID 0x174e
158141cc406Sopenharmony_ci#define MX420_PID 0x174f
159141cc406Sopenharmony_ci#define MX880_PID 0x1750
160141cc406Sopenharmony_ci
161141cc406Sopenharmony_ci/* Generation 5 */
162141cc406Sopenharmony_ci/* 2011 new devices (untested) */
163141cc406Sopenharmony_ci#define MG2100_PID 0x1751
164141cc406Sopenharmony_ci#define MG3100_PID 0x1752
165141cc406Sopenharmony_ci#define MG4100_PID 0x1753
166141cc406Sopenharmony_ci#define MG5300_PID 0x1754
167141cc406Sopenharmony_ci#define MG6200_PID 0x1755
168141cc406Sopenharmony_ci#define MP493_PID 0x1757
169141cc406Sopenharmony_ci#define E500_PID 0x1758
170141cc406Sopenharmony_ci
171141cc406Sopenharmony_ci/* 2012 new devices (untested) */
172141cc406Sopenharmony_ci#define MX370_PID 0x1759
173141cc406Sopenharmony_ci#define MX430_PID 0x175B
174141cc406Sopenharmony_ci#define MX510_PID 0x175C
175141cc406Sopenharmony_ci#define MX710_PID 0x175D
176141cc406Sopenharmony_ci#define MX890_PID 0x175E
177141cc406Sopenharmony_ci#define E600_PID 0x175A
178141cc406Sopenharmony_ci#define MG4200_PID 0x1763
179141cc406Sopenharmony_ci
180141cc406Sopenharmony_ci/* 2013 new devices */
181141cc406Sopenharmony_ci#define MP230_PID 0x175F
182141cc406Sopenharmony_ci#define MG6300_PID 0x1765
183141cc406Sopenharmony_ci
184141cc406Sopenharmony_ci/* 2013 new devices (untested) */
185141cc406Sopenharmony_ci#define MG2200_PID 0x1760
186141cc406Sopenharmony_ci#define E510_PID 0x1761
187141cc406Sopenharmony_ci#define MG3200_PID 0x1762
188141cc406Sopenharmony_ci#define MG5400_PID 0x1764
189141cc406Sopenharmony_ci#define MX390_PID 0x1766
190141cc406Sopenharmony_ci#define E610_PID 0x1767
191141cc406Sopenharmony_ci#define MX450_PID 0x1768
192141cc406Sopenharmony_ci#define MX520_PID 0x1769
193141cc406Sopenharmony_ci#define MX720_PID 0x176a
194141cc406Sopenharmony_ci#define MX920_PID 0x176b
195141cc406Sopenharmony_ci#define MG2400_PID 0x176c
196141cc406Sopenharmony_ci#define MG2500_PID 0x176d
197141cc406Sopenharmony_ci#define MG3500_PID 0x176e
198141cc406Sopenharmony_ci#define MG6500_PID 0x176f
199141cc406Sopenharmony_ci#define MG6400_PID 0x1770
200141cc406Sopenharmony_ci#define MG5500_PID 0x1771
201141cc406Sopenharmony_ci#define MG7100_PID 0x1772
202141cc406Sopenharmony_ci
203141cc406Sopenharmony_ci/* 2014 new devices (untested) */
204141cc406Sopenharmony_ci#define MX470_PID 0x1774
205141cc406Sopenharmony_ci#define MX530_PID 0x1775
206141cc406Sopenharmony_ci#define MB5000_PID 0x1776
207141cc406Sopenharmony_ci#define MB5300_PID 0x1777
208141cc406Sopenharmony_ci#define MB2000_PID 0x1778
209141cc406Sopenharmony_ci#define MB2300_PID 0x1779
210141cc406Sopenharmony_ci#define E400_PID 0x177a
211141cc406Sopenharmony_ci#define E560_PID 0x177b
212141cc406Sopenharmony_ci#define MG7500_PID 0x177c
213141cc406Sopenharmony_ci#define MG6600_PID 0x177e
214141cc406Sopenharmony_ci#define MG5600_PID 0x177f
215141cc406Sopenharmony_ci#define MG2900_PID 0x1780
216141cc406Sopenharmony_ci#define E460_PID 0x1788
217141cc406Sopenharmony_ci
218141cc406Sopenharmony_ci/* 2015 new devices (untested) */
219141cc406Sopenharmony_ci#define MX490_PID 0x1787
220141cc406Sopenharmony_ci#define E480_PID 0x1789
221141cc406Sopenharmony_ci#define MG3600_PID 0x178a
222141cc406Sopenharmony_ci#define MG7700_PID 0x178b
223141cc406Sopenharmony_ci#define MG6900_PID 0x178c
224141cc406Sopenharmony_ci#define MG6800_PID 0x178d
225141cc406Sopenharmony_ci#define MG5700_PID 0x178e
226141cc406Sopenharmony_ci
227141cc406Sopenharmony_ci/* 2016 new devices (untested) */
228141cc406Sopenharmony_ci#define MB2700_PID 0x1792
229141cc406Sopenharmony_ci#define MB2100_PID 0x1793
230141cc406Sopenharmony_ci#define G3000_PID 0x1794
231141cc406Sopenharmony_ci#define G2000_PID 0x1795
232141cc406Sopenharmony_ci#define TS9000_PID 0x179f
233141cc406Sopenharmony_ci#define TS8000_PID 0x1800       /* tested: TS8030 */
234141cc406Sopenharmony_ci#define TS6000_PID 0x1801
235141cc406Sopenharmony_ci#define TS5000_PID 0x1802
236141cc406Sopenharmony_ci#define MG3000_PID 0x180b
237141cc406Sopenharmony_ci#define E470_PID 0x180c
238141cc406Sopenharmony_ci#define E410_PID 0x181e
239141cc406Sopenharmony_ci
240141cc406Sopenharmony_ci/* 2017 new devices (untested) */
241141cc406Sopenharmony_ci#define G4000_PID 0x181d
242141cc406Sopenharmony_ci#define TS6100_PID 0x1822
243141cc406Sopenharmony_ci#define TS5100_PID 0x1825
244141cc406Sopenharmony_ci#define TS3100_PID 0x1827
245141cc406Sopenharmony_ci#define E3100_PID 0x1828
246141cc406Sopenharmony_ci
247141cc406Sopenharmony_ci/* 2018 new devices (untested) */
248141cc406Sopenharmony_ci#define MB5400_PID 0x178f
249141cc406Sopenharmony_ci#define MB5100_PID 0x1790
250141cc406Sopenharmony_ci#define TS9100_PID 0x1820
251141cc406Sopenharmony_ci#define TR8500_PID 0x1823
252141cc406Sopenharmony_ci#define TR7500_PID 0x1824
253141cc406Sopenharmony_ci#define TS9500_PID 0x185c
254141cc406Sopenharmony_ci#define LIDE400_PID 0x1912  /* tested */
255141cc406Sopenharmony_ci#define LIDE300_PID 0x1913  /* tested */
256141cc406Sopenharmony_ci
257141cc406Sopenharmony_ci/* 2019 new devices (untested) */
258141cc406Sopenharmony_ci#define TS8100_PID 0x1821
259141cc406Sopenharmony_ci#define G2010_PID 0x183a
260141cc406Sopenharmony_ci#define G3010_PID 0x183b
261141cc406Sopenharmony_ci#define G4010_PID 0x183d
262141cc406Sopenharmony_ci#define TS9180_PID 0x183e
263141cc406Sopenharmony_ci#define TS8180_PID 0x183f
264141cc406Sopenharmony_ci#define TS6180_PID 0x1840
265141cc406Sopenharmony_ci#define TR8580_PID 0x1841
266141cc406Sopenharmony_ci#define TS8130_PID 0x1842
267141cc406Sopenharmony_ci#define TS6130_PID 0x1843
268141cc406Sopenharmony_ci#define TR8530_PID 0x1844
269141cc406Sopenharmony_ci#define TR7530_PID 0x1845
270141cc406Sopenharmony_ci#define XK50_PID 0x1846
271141cc406Sopenharmony_ci#define XK70_PID 0x1847
272141cc406Sopenharmony_ci#define TR4500_PID 0x1854
273141cc406Sopenharmony_ci#define E4200_PID 0x1855
274141cc406Sopenharmony_ci#define TS6200_PID 0x1856
275141cc406Sopenharmony_ci#define TS6280_PID 0x1857
276141cc406Sopenharmony_ci#define TS6230_PID 0x1858
277141cc406Sopenharmony_ci#define TS8200_PID 0x1859
278141cc406Sopenharmony_ci#define TS8280_PID 0x185a
279141cc406Sopenharmony_ci#define TS8230_PID 0x185b
280141cc406Sopenharmony_ci#define TS9580_PID 0x185d
281141cc406Sopenharmony_ci#define TR9530_PID 0x185e
282141cc406Sopenharmony_ci#define G7000_PID 0x1863
283141cc406Sopenharmony_ci#define G6000_PID 0x1865
284141cc406Sopenharmony_ci#define G6080_PID 0x1866
285141cc406Sopenharmony_ci#define GM4000_PID 0x1869
286141cc406Sopenharmony_ci#define XK80_PID 0x1873
287141cc406Sopenharmony_ci#define TS5300_PID 0x188b
288141cc406Sopenharmony_ci#define TS5380_PID 0x188c
289141cc406Sopenharmony_ci#define TS6300_PID 0x188d
290141cc406Sopenharmony_ci#define TS6380_PID 0x188e
291141cc406Sopenharmony_ci#define TS7330_PID 0x188f
292141cc406Sopenharmony_ci#define TS8300_PID 0x1890
293141cc406Sopenharmony_ci#define TS8380_PID 0x1891
294141cc406Sopenharmony_ci#define TS8330_PID 0x1892
295141cc406Sopenharmony_ci#define XK60_PID   0x1893
296141cc406Sopenharmony_ci#define TS6330_PID 0x1894
297141cc406Sopenharmony_ci#define TS3300_PID 0x18a2
298141cc406Sopenharmony_ci#define E3300_PID  0x18a3
299141cc406Sopenharmony_ci
300141cc406Sopenharmony_ci/* 2020 new devices (untested) */
301141cc406Sopenharmony_ci#define G7080_PID 0x1864
302141cc406Sopenharmony_ci#define GM4080_PID 0x186A
303141cc406Sopenharmony_ci#define TS3400_PID 0x18B7
304141cc406Sopenharmony_ci#define E3400_PID 0x18B8
305141cc406Sopenharmony_ci#define TR7000_PID 0x18B9
306141cc406Sopenharmony_ci#define G2020_PID 0x18BD
307141cc406Sopenharmony_ci#define G3060_PID 0x18C3
308141cc406Sopenharmony_ci#define G2060_PID 0x18C1
309141cc406Sopenharmony_ci#define G3020_PID 0x18BF
310141cc406Sopenharmony_ci#define TS7430_PID 0x18B2
311141cc406Sopenharmony_ci#define XK90_PID 0x18B6 /* tested */
312141cc406Sopenharmony_ci#define TS8430_PID 0x18B5
313141cc406Sopenharmony_ci#define TR7600_PID 0x18AA
314141cc406Sopenharmony_ci#define TR8600_PID 0x18AD
315141cc406Sopenharmony_ci#define TR8630_PID 0x18AF
316141cc406Sopenharmony_ci#define TS6400_PID 0x18D3
317141cc406Sopenharmony_ci#define TS7400_PID 0x18D7
318141cc406Sopenharmony_ci
319141cc406Sopenharmony_ci/* 2021 new device (untested) */
320141cc406Sopenharmony_ci#define TS5350i_PID 0x18D9
321141cc406Sopenharmony_ci#define G600_PID 0x18D5
322141cc406Sopenharmony_ci#define TS3500_PID 0x18D4
323141cc406Sopenharmony_ci#define TR4600_PID 0x18DA
324141cc406Sopenharmony_ci#define E4500_PID 0x18DB
325141cc406Sopenharmony_ci#define TR4700_PID 0x18DC
326141cc406Sopenharmony_ci#define XK500_PID 0x18DF
327141cc406Sopenharmony_ci#define TS8530_PID 0x18E0
328141cc406Sopenharmony_ci#define XK100_PID 0x18E2
329141cc406Sopenharmony_ci#define TS7530_PID 0x18E1
330141cc406Sopenharmony_ci#define TS7450i_PID 0x18F7
331141cc406Sopenharmony_ci#define GX6000_PID 0x18A6
332141cc406Sopenharmony_ci#define GX7000_PID 0x18A8
333141cc406Sopenharmony_ci#define TS5400_PID 0x18D8
334141cc406Sopenharmony_ci
335141cc406Sopenharmony_ci/* 2022 new device (untested) */
336141cc406Sopenharmony_ci#define TS2400_PID 0x1108
337141cc406Sopenharmony_ci#define TS2600_PID 0x1107
338141cc406Sopenharmony_ci
339141cc406Sopenharmony_ci
340141cc406Sopenharmony_ci/* Generation 4 XML messages that encapsulates the Pixma protocol messages */
341141cc406Sopenharmony_ci#define XML_START_1   \
342141cc406Sopenharmony_ci"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\
343141cc406Sopenharmony_ci<cmd xmlns:ivec=\"http://www.canon.com/ns/cmd/2008/07/common/\">\
344141cc406Sopenharmony_ci<ivec:contents><ivec:operation>StartJob</ivec:operation>\
345141cc406Sopenharmony_ci<ivec:param_set servicetype=\"scan\"><ivec:jobID>00000001</ivec:jobID>\
346141cc406Sopenharmony_ci<ivec:bidi>1</ivec:bidi></ivec:param_set></ivec:contents></cmd>"
347141cc406Sopenharmony_ci
348141cc406Sopenharmony_ci#define XML_START_2   \
349141cc406Sopenharmony_ci"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\
350141cc406Sopenharmony_ci<cmd xmlns:ivec=\"http://www.canon.com/ns/cmd/2008/07/common/\" xmlns:vcn=\"http://www.canon.com/ns/cmd/2008/07/canon/\">\
351141cc406Sopenharmony_ci<ivec:contents><ivec:operation>VendorCmd</ivec:operation>\
352141cc406Sopenharmony_ci<ivec:param_set servicetype=\"scan\"><ivec:jobID>00000001</ivec:jobID>\
353141cc406Sopenharmony_ci<vcn:ijoperation>ModeShift</vcn:ijoperation><vcn:ijmode>1</vcn:ijmode>\
354141cc406Sopenharmony_ci</ivec:param_set></ivec:contents></cmd>"
355141cc406Sopenharmony_ci
356141cc406Sopenharmony_ci#define XML_END   \
357141cc406Sopenharmony_ci"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\
358141cc406Sopenharmony_ci<cmd xmlns:ivec=\"http://www.canon.com/ns/cmd/2008/07/common/\">\
359141cc406Sopenharmony_ci<ivec:contents><ivec:operation>EndJob</ivec:operation>\
360141cc406Sopenharmony_ci<ivec:param_set servicetype=\"scan\"><ivec:jobID>00000001</ivec:jobID>\
361141cc406Sopenharmony_ci</ivec:param_set></ivec:contents></cmd>"
362141cc406Sopenharmony_ci
363141cc406Sopenharmony_ci#if !defined(HAVE_LIBXML2)
364141cc406Sopenharmony_ci#define XML_OK   "<ivec:response>OK</ivec:response>"
365141cc406Sopenharmony_ci#endif
366141cc406Sopenharmony_ci
367141cc406Sopenharmony_cienum mp150_state_t
368141cc406Sopenharmony_ci{
369141cc406Sopenharmony_ci  state_idle,
370141cc406Sopenharmony_ci  state_warmup,
371141cc406Sopenharmony_ci  state_scanning,
372141cc406Sopenharmony_ci  state_transfering,
373141cc406Sopenharmony_ci  state_finished
374141cc406Sopenharmony_ci};
375141cc406Sopenharmony_ci
376141cc406Sopenharmony_cienum mp150_cmd_t
377141cc406Sopenharmony_ci{
378141cc406Sopenharmony_ci  cmd_start_session = 0xdb20,
379141cc406Sopenharmony_ci  cmd_select_source = 0xdd20,
380141cc406Sopenharmony_ci  cmd_gamma = 0xee20,
381141cc406Sopenharmony_ci  cmd_scan_param = 0xde20,
382141cc406Sopenharmony_ci  cmd_status = 0xf320,
383141cc406Sopenharmony_ci  cmd_abort_session = 0xef20,
384141cc406Sopenharmony_ci  cmd_time = 0xeb80,
385141cc406Sopenharmony_ci  cmd_read_image = 0xd420,
386141cc406Sopenharmony_ci  cmd_error_info = 0xff20,
387141cc406Sopenharmony_ci
388141cc406Sopenharmony_ci  cmd_scan_param_3 = 0xd820,
389141cc406Sopenharmony_ci  cmd_scan_start_3 = 0xd920,
390141cc406Sopenharmony_ci  cmd_status_3 = 0xda20,
391141cc406Sopenharmony_ci};
392141cc406Sopenharmony_ci
393141cc406Sopenharmony_citypedef struct mp150_t
394141cc406Sopenharmony_ci{
395141cc406Sopenharmony_ci  enum mp150_state_t state;
396141cc406Sopenharmony_ci  pixma_cmdbuf_t cb;
397141cc406Sopenharmony_ci  uint8_t *imgbuf;
398141cc406Sopenharmony_ci  uint8_t current_status[16];
399141cc406Sopenharmony_ci  unsigned last_block;
400141cc406Sopenharmony_ci  uint8_t generation;
401141cc406Sopenharmony_ci  /* for Generation 3 shift */
402141cc406Sopenharmony_ci  uint8_t *linebuf;
403141cc406Sopenharmony_ci  uint8_t *data_left_ofs;
404141cc406Sopenharmony_ci  unsigned data_left_len;
405141cc406Sopenharmony_ci  uint8_t adf_state;            /* handle adf scanning */
406141cc406Sopenharmony_ci  unsigned scale;               /* Scale factor for lower resolutions, the
407141cc406Sopenharmony_ci                                 * scanner doesn't support. We scale down the
408141cc406Sopenharmony_ci                                 * image after scanning minimum possible
409141cc406Sopenharmony_ci                                 * resolution.
410141cc406Sopenharmony_ci                                 */
411141cc406Sopenharmony_ci
412141cc406Sopenharmony_ci} mp150_t;
413141cc406Sopenharmony_ci
414141cc406Sopenharmony_ci/*
415141cc406Sopenharmony_ci  STAT:  0x0606 = ok,
416141cc406Sopenharmony_ci         0x1515 = failed (PIXMA_ECANCELED),
417141cc406Sopenharmony_ci	 0x1414 = busy (PIXMA_EBUSY)
418141cc406Sopenharmony_ci
419141cc406Sopenharmony_ci  Transaction scheme
420141cc406Sopenharmony_ci    1. command_header/data | result_header
421141cc406Sopenharmony_ci    2. command_header      | result_header/data
422141cc406Sopenharmony_ci    3. command_header      | result_header/image_data
423141cc406Sopenharmony_ci
424141cc406Sopenharmony_ci  - data has checksum in the last byte.
425141cc406Sopenharmony_ci  - image_data has no checksum.
426141cc406Sopenharmony_ci  - data and image_data begins in the same USB packet as
427141cc406Sopenharmony_ci    command_header or result_header.
428141cc406Sopenharmony_ci
429141cc406Sopenharmony_ci  command format #1:
430141cc406Sopenharmony_ci   u16be      cmd
431141cc406Sopenharmony_ci   u8[6]      0
432141cc406Sopenharmony_ci   u8[4]      0
433141cc406Sopenharmony_ci   u32be      PLEN parameter length
434141cc406Sopenharmony_ci   u8[PLEN-1] parameter
435141cc406Sopenharmony_ci   u8         parameter check sum
436141cc406Sopenharmony_ci  result:
437141cc406Sopenharmony_ci   u16be      STAT
438141cc406Sopenharmony_ci   u8         0
439141cc406Sopenharmony_ci   u8         0 or 0x21 if STAT == 0x1414
440141cc406Sopenharmony_ci   u8[4]      0
441141cc406Sopenharmony_ci
442141cc406Sopenharmony_ci  command format #2:
443141cc406Sopenharmony_ci   u16be      cmd
444141cc406Sopenharmony_ci   u8[6]      0
445141cc406Sopenharmony_ci   u8[4]      0
446141cc406Sopenharmony_ci   u32be      RLEN result length
447141cc406Sopenharmony_ci  result:
448141cc406Sopenharmony_ci   u16be      STAT
449141cc406Sopenharmony_ci   u8[6]      0
450141cc406Sopenharmony_ci   u8[RLEN-1] result
451141cc406Sopenharmony_ci   u8         result check sum
452141cc406Sopenharmony_ci
453141cc406Sopenharmony_ci  command format #3: (only used by read_image_block)
454141cc406Sopenharmony_ci   u16be      0xd420
455141cc406Sopenharmony_ci   u8[6]      0
456141cc406Sopenharmony_ci   u8[4]      0
457141cc406Sopenharmony_ci   u32be      max. block size + 8
458141cc406Sopenharmony_ci  result:
459141cc406Sopenharmony_ci   u16be      STAT
460141cc406Sopenharmony_ci   u8[6]      0
461141cc406Sopenharmony_ci   u8         block info bitfield: 0x8 = end of scan, 0x10 = no more paper, 0x20 = no more data
462141cc406Sopenharmony_ci   u8[3]      0
463141cc406Sopenharmony_ci   u32be      ILEN image data size
464141cc406Sopenharmony_ci   u8[ILEN]   image data
465141cc406Sopenharmony_ci */
466141cc406Sopenharmony_ci
467141cc406Sopenharmony_cistatic void mp150_finish_scan (pixma_t * s);
468141cc406Sopenharmony_ci
469141cc406Sopenharmony_cistatic int
470141cc406Sopenharmony_ciis_scanning_from_adf (pixma_t * s)
471141cc406Sopenharmony_ci{
472141cc406Sopenharmony_ci  return (s->param->source == PIXMA_SOURCE_ADF
473141cc406Sopenharmony_ci	  || s->param->source == PIXMA_SOURCE_ADFDUP);
474141cc406Sopenharmony_ci}
475141cc406Sopenharmony_ci
476141cc406Sopenharmony_cistatic int
477141cc406Sopenharmony_ciis_scanning_from_adfdup (pixma_t * s)
478141cc406Sopenharmony_ci{
479141cc406Sopenharmony_ci  return (s->param->source == PIXMA_SOURCE_ADFDUP);
480141cc406Sopenharmony_ci}
481141cc406Sopenharmony_ci
482141cc406Sopenharmony_cistatic int
483141cc406Sopenharmony_ciis_scanning_jpeg (pixma_t *s)
484141cc406Sopenharmony_ci{
485141cc406Sopenharmony_ci  return s->param->mode_jpeg;
486141cc406Sopenharmony_ci}
487141cc406Sopenharmony_ci
488141cc406Sopenharmony_cistatic int
489141cc406Sopenharmony_cisend_xml_dialog (pixma_t * s, const char * xml_message)
490141cc406Sopenharmony_ci{
491141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
492141cc406Sopenharmony_ci  int datalen;
493141cc406Sopenharmony_ci
494141cc406Sopenharmony_ci  datalen = pixma_cmd_transaction (s, xml_message, strlen (xml_message),
495141cc406Sopenharmony_ci                                   mp->cb.buf, 1024);
496141cc406Sopenharmony_ci  if (datalen < 0)
497141cc406Sopenharmony_ci    return datalen;
498141cc406Sopenharmony_ci
499141cc406Sopenharmony_ci  mp->cb.buf[datalen] = 0;
500141cc406Sopenharmony_ci
501141cc406Sopenharmony_ci  PDBG (pixma_dbg (10, "XML message sent to scanner:\n%s\n", xml_message));
502141cc406Sopenharmony_ci  PDBG (pixma_dbg (10, "XML response back from scanner:\n%s\n", mp->cb.buf));
503141cc406Sopenharmony_ci
504141cc406Sopenharmony_ci#if defined(HAVE_LIBXML2)
505141cc406Sopenharmony_ci  return pixma_parse_xml_response((const char*)mp->cb.buf) == PIXMA_STATUS_OK;
506141cc406Sopenharmony_ci#else
507141cc406Sopenharmony_ci  return (strcasestr ((const char *) mp->cb.buf, XML_OK) != NULL);
508141cc406Sopenharmony_ci#endif
509141cc406Sopenharmony_ci}
510141cc406Sopenharmony_ci
511141cc406Sopenharmony_cistatic int
512141cc406Sopenharmony_cistart_session (pixma_t * s)
513141cc406Sopenharmony_ci{
514141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
515141cc406Sopenharmony_ci
516141cc406Sopenharmony_ci  pixma_newcmd (&mp->cb, cmd_start_session, 0, 0);
517141cc406Sopenharmony_ci  mp->cb.buf[3] = 0x00;
518141cc406Sopenharmony_ci  return pixma_exec (s, &mp->cb);
519141cc406Sopenharmony_ci}
520141cc406Sopenharmony_ci
521141cc406Sopenharmony_cistatic int
522141cc406Sopenharmony_cistart_scan_3 (pixma_t * s)
523141cc406Sopenharmony_ci{
524141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
525141cc406Sopenharmony_ci
526141cc406Sopenharmony_ci  pixma_newcmd (&mp->cb, cmd_scan_start_3, 0, 0);
527141cc406Sopenharmony_ci  mp->cb.buf[3] = 0x00;
528141cc406Sopenharmony_ci  return pixma_exec (s, &mp->cb);
529141cc406Sopenharmony_ci}
530141cc406Sopenharmony_ci
531141cc406Sopenharmony_cistatic int
532141cc406Sopenharmony_ciis_calibrated (pixma_t * s)
533141cc406Sopenharmony_ci{
534141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
535141cc406Sopenharmony_ci  if (mp->generation >= 3)
536141cc406Sopenharmony_ci    {
537141cc406Sopenharmony_ci      return ((mp->current_status[0] & 0x01) == 1 || (mp->current_status[0] & 0x02) == 2);
538141cc406Sopenharmony_ci    }
539141cc406Sopenharmony_ci  if (mp->generation == 1)
540141cc406Sopenharmony_ci    {
541141cc406Sopenharmony_ci      return (mp->current_status[8] == 1);
542141cc406Sopenharmony_ci    }
543141cc406Sopenharmony_ci  else
544141cc406Sopenharmony_ci    {
545141cc406Sopenharmony_ci      return (mp->current_status[9] == 1);
546141cc406Sopenharmony_ci    }
547141cc406Sopenharmony_ci}
548141cc406Sopenharmony_ci
549141cc406Sopenharmony_cistatic int
550141cc406Sopenharmony_cihas_paper (pixma_t * s)
551141cc406Sopenharmony_ci{
552141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
553141cc406Sopenharmony_ci
554141cc406Sopenharmony_ci  if (is_scanning_from_adfdup (s))
555141cc406Sopenharmony_ci    return (mp->current_status[1] == 0 || mp->current_status[2] == 0);
556141cc406Sopenharmony_ci  else
557141cc406Sopenharmony_ci    return (mp->current_status[1] == 0);
558141cc406Sopenharmony_ci}
559141cc406Sopenharmony_ci
560141cc406Sopenharmony_cistatic void
561141cc406Sopenharmony_cidrain_bulk_in (pixma_t * s)
562141cc406Sopenharmony_ci{
563141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
564141cc406Sopenharmony_ci  while (pixma_read (s->io, mp->imgbuf, IMAGE_BLOCK_SIZE) >= 0);
565141cc406Sopenharmony_ci}
566141cc406Sopenharmony_ci
567141cc406Sopenharmony_cistatic int
568141cc406Sopenharmony_ciabort_session (pixma_t * s)
569141cc406Sopenharmony_ci{
570141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
571141cc406Sopenharmony_ci  mp->adf_state = state_idle;           /* reset adf scanning */
572141cc406Sopenharmony_ci  return pixma_exec_short_cmd (s, &mp->cb, cmd_abort_session);
573141cc406Sopenharmony_ci}
574141cc406Sopenharmony_ci
575141cc406Sopenharmony_cistatic int
576141cc406Sopenharmony_ciselect_source (pixma_t * s)
577141cc406Sopenharmony_ci{
578141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
579141cc406Sopenharmony_ci  uint8_t *data;
580141cc406Sopenharmony_ci
581141cc406Sopenharmony_ci  data = pixma_newcmd (&mp->cb, cmd_select_source, 12, 0);
582141cc406Sopenharmony_ci  data[5] = ((mp->generation == 2) ? 1 : 0);
583141cc406Sopenharmony_ci  switch (s->param->source)
584141cc406Sopenharmony_ci    {
585141cc406Sopenharmony_ci      case PIXMA_SOURCE_FLATBED:
586141cc406Sopenharmony_ci        data[0] = 1;
587141cc406Sopenharmony_ci        data[1] = 1;
588141cc406Sopenharmony_ci        break;
589141cc406Sopenharmony_ci
590141cc406Sopenharmony_ci      case PIXMA_SOURCE_ADF:
591141cc406Sopenharmony_ci        data[0] = 2;
592141cc406Sopenharmony_ci        data[5] = 1;
593141cc406Sopenharmony_ci        data[6] = 1;
594141cc406Sopenharmony_ci        break;
595141cc406Sopenharmony_ci
596141cc406Sopenharmony_ci      case PIXMA_SOURCE_ADFDUP:
597141cc406Sopenharmony_ci        data[0] = 2;
598141cc406Sopenharmony_ci        data[5] = 3;
599141cc406Sopenharmony_ci        data[6] = 3;
600141cc406Sopenharmony_ci        break;
601141cc406Sopenharmony_ci
602141cc406Sopenharmony_ci      default:
603141cc406Sopenharmony_ci        return PIXMA_EPROTO;
604141cc406Sopenharmony_ci    }
605141cc406Sopenharmony_ci  return pixma_exec (s, &mp->cb);
606141cc406Sopenharmony_ci}
607141cc406Sopenharmony_ci
608141cc406Sopenharmony_cistatic int
609141cc406Sopenharmony_cisend_gamma_table (pixma_t * s)
610141cc406Sopenharmony_ci{
611141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
612141cc406Sopenharmony_ci  const uint8_t *lut = s->param->gamma_table;
613141cc406Sopenharmony_ci  uint8_t *data;
614141cc406Sopenharmony_ci
615141cc406Sopenharmony_ci  if (s->cfg->cap & PIXMA_CAP_GT_4096)
616141cc406Sopenharmony_ci    {
617141cc406Sopenharmony_ci      data = pixma_newcmd (&mp->cb, cmd_gamma, 4096 + 8, 0);
618141cc406Sopenharmony_ci      data[0] = (s->param->channels == 3) ? 0x10 : 0x01;
619141cc406Sopenharmony_ci      pixma_set_be16 (0x1004, data + 2);
620141cc406Sopenharmony_ci      if (lut)
621141cc406Sopenharmony_ci        {
622141cc406Sopenharmony_ci          /* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 4096 bytes from LUT ***** \n")); */
623141cc406Sopenharmony_ci          /* PDBG (pixma_hexdump (4, lut, 4096)); */
624141cc406Sopenharmony_ci          memcpy (data + 4, lut, 4096);
625141cc406Sopenharmony_ci        }
626141cc406Sopenharmony_ci      else
627141cc406Sopenharmony_ci        {
628141cc406Sopenharmony_ci          /* fallback: we should never see this */
629141cc406Sopenharmony_ci          PDBG (pixma_dbg (4, "*send_gamma_table***** Generate 4096 bytes Table with %f ***** \n",
630141cc406Sopenharmony_ci                           s->param->gamma));
631141cc406Sopenharmony_ci          pixma_fill_gamma_table (s->param->gamma, data + 4, 4096);
632141cc406Sopenharmony_ci          /* PDBG (pixma_hexdump (4, data + 4, 4096)); */
633141cc406Sopenharmony_ci        }
634141cc406Sopenharmony_ci    }
635141cc406Sopenharmony_ci  else
636141cc406Sopenharmony_ci    {
637141cc406Sopenharmony_ci      /* Gamma table for 2nd+ generation: 1024 * uint16_le */
638141cc406Sopenharmony_ci      data = pixma_newcmd (&mp->cb, cmd_gamma, 1024 * 2 + 8, 0);
639141cc406Sopenharmony_ci      data[0] = 0x10;
640141cc406Sopenharmony_ci      pixma_set_be16 (0x0804, data + 2);
641141cc406Sopenharmony_ci      if (lut)
642141cc406Sopenharmony_ci        {
643141cc406Sopenharmony_ci          /* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 1024 * 2 bytes from LUT ***** \n")); */
644141cc406Sopenharmony_ci          /* PDBG (pixma_hexdump (4, lut, 1024 * 2)); */
645141cc406Sopenharmony_ci          memcpy (data + 4, lut, 1024 * 2);
646141cc406Sopenharmony_ci        }
647141cc406Sopenharmony_ci      else
648141cc406Sopenharmony_ci        {
649141cc406Sopenharmony_ci          /* fallback: we should never see this */
650141cc406Sopenharmony_ci          PDBG (pixma_dbg (4, "*send_gamma_table***** Generate 1024 * 2 Table with %f ***** \n",
651141cc406Sopenharmony_ci                           s->param->gamma));
652141cc406Sopenharmony_ci          pixma_fill_gamma_table (s->param->gamma, data + 4, 1024);
653141cc406Sopenharmony_ci          /* PDBG (pixma_hexdump (4, data + 4, 1024 * 2)); */
654141cc406Sopenharmony_ci        }
655141cc406Sopenharmony_ci    }
656141cc406Sopenharmony_ci  return pixma_exec (s, &mp->cb);
657141cc406Sopenharmony_ci}
658141cc406Sopenharmony_ci
659141cc406Sopenharmony_cistatic unsigned
660141cc406Sopenharmony_cicalc_raw_width (const mp150_t * mp, const pixma_scan_param_t * param)
661141cc406Sopenharmony_ci{
662141cc406Sopenharmony_ci  unsigned raw_width;
663141cc406Sopenharmony_ci  /* NOTE: Actually, we can send arbitrary width to MP150. Lines returned
664141cc406Sopenharmony_ci     are always padded to multiple of 4 or 12 pixels. Is this valid for
665141cc406Sopenharmony_ci     other models, too? */
666141cc406Sopenharmony_ci  if (mp->generation >= 2)
667141cc406Sopenharmony_ci    {
668141cc406Sopenharmony_ci      raw_width = ALIGN_SUP ((param->w * mp->scale) + param->xs, 32);
669141cc406Sopenharmony_ci      /* PDBG (pixma_dbg (4, "*calc_raw_width***** width %i extended by %i and rounded to %i *****\n", param->w, param->xs, raw_width)); */
670141cc406Sopenharmony_ci    }
671141cc406Sopenharmony_ci  else if (param->channels == 1)
672141cc406Sopenharmony_ci    {
673141cc406Sopenharmony_ci      raw_width = ALIGN_SUP (param->w + param->xs, 12);
674141cc406Sopenharmony_ci    }
675141cc406Sopenharmony_ci  else
676141cc406Sopenharmony_ci    {
677141cc406Sopenharmony_ci      raw_width = ALIGN_SUP (param->w + param->xs, 4);
678141cc406Sopenharmony_ci    }
679141cc406Sopenharmony_ci  return raw_width;
680141cc406Sopenharmony_ci}
681141cc406Sopenharmony_ci
682141cc406Sopenharmony_cistatic int
683141cc406Sopenharmony_ciis_gray_16 (pixma_t * s)
684141cc406Sopenharmony_ci{
685141cc406Sopenharmony_ci  return (s->param->mode == PIXMA_SCAN_MODE_GRAY_16);
686141cc406Sopenharmony_ci}
687141cc406Sopenharmony_ci
688141cc406Sopenharmony_cistatic unsigned
689141cc406Sopenharmony_ciget_cis_line_size (pixma_t * s)
690141cc406Sopenharmony_ci{
691141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
692141cc406Sopenharmony_ci
693141cc406Sopenharmony_ci  /*PDBG (pixma_dbg (4, "%s: line_size=%ld, w=%d, wx=%d, scale=%d\n",
694141cc406Sopenharmony_ci                   __func__, s->param->line_size, s->param->w, s->param->wx, mp->scale));*/
695141cc406Sopenharmony_ci
696141cc406Sopenharmony_ci  return (s->param->wx ? s->param->line_size / s->param->w * s->param->wx
697141cc406Sopenharmony_ci                       : s->param->line_size)
698141cc406Sopenharmony_ci         * mp->scale
699141cc406Sopenharmony_ci         * (is_gray_16(s) ? 3 : 1);
700141cc406Sopenharmony_ci}
701141cc406Sopenharmony_ci
702141cc406Sopenharmony_cistatic int
703141cc406Sopenharmony_cisend_scan_param (pixma_t * s)
704141cc406Sopenharmony_ci{
705141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
706141cc406Sopenharmony_ci  uint8_t *data;
707141cc406Sopenharmony_ci  unsigned xdpi = s->param->xdpi * mp->scale;
708141cc406Sopenharmony_ci  unsigned ydpi = s->param->xdpi * mp->scale;
709141cc406Sopenharmony_ci  unsigned x = s->param->x * mp->scale;
710141cc406Sopenharmony_ci  unsigned xs = s->param->xs;
711141cc406Sopenharmony_ci  unsigned y = s->param->y * mp->scale;
712141cc406Sopenharmony_ci  unsigned wx = calc_raw_width (mp, s->param);
713141cc406Sopenharmony_ci  unsigned h = MIN (s->param->h, s->cfg->height * s->param->ydpi / 75) * mp->scale;
714141cc406Sopenharmony_ci
715141cc406Sopenharmony_ci  if (mp->generation <= 2)
716141cc406Sopenharmony_ci    {
717141cc406Sopenharmony_ci      PDBG (pixma_dbg (4, "*send_scan_param gen. 1-2 ***** Setting: xdpi=%u ydpi=%u  x=%i y=%i  wx=%i ***** \n",
718141cc406Sopenharmony_ci                           xdpi, ydpi, x-xs, y, wx));
719141cc406Sopenharmony_ci      data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x30, 0);
720141cc406Sopenharmony_ci      pixma_set_be16 (xdpi | 0x8000, data + 0x04);
721141cc406Sopenharmony_ci      pixma_set_be16 (ydpi | 0x8000, data + 0x06);
722141cc406Sopenharmony_ci      pixma_set_be32 (x, data + 0x08);
723141cc406Sopenharmony_ci      if (mp->generation == 2)
724141cc406Sopenharmony_ci        pixma_set_be32 (x - s->param->xs, data + 0x08);
725141cc406Sopenharmony_ci      pixma_set_be32 (y, data + 0x0c);
726141cc406Sopenharmony_ci      pixma_set_be32 (wx, data + 0x10);
727141cc406Sopenharmony_ci      pixma_set_be32 (h, data + 0x14);
728141cc406Sopenharmony_ci      data[0x18] = (s->param->channels != 1) ? 0x08 : 0x04;
729141cc406Sopenharmony_ci      data[0x19] = ((s->param->software_lineart) ? 8 : s->param->depth)
730141cc406Sopenharmony_ci                    * s->param->channels;   /* bits per pixel */
731141cc406Sopenharmony_ci      data[0x1a] = 0;
732141cc406Sopenharmony_ci      data[0x20] = 0xff;
733141cc406Sopenharmony_ci      data[0x23] = 0x81;
734141cc406Sopenharmony_ci      data[0x26] = 0x02;
735141cc406Sopenharmony_ci      data[0x27] = 0x01;
736141cc406Sopenharmony_ci    }
737141cc406Sopenharmony_ci  else
738141cc406Sopenharmony_ci    {
739141cc406Sopenharmony_ci      PDBG (pixma_dbg (4, "*send_scan_param gen. 3+ ***** Setting: xdpi=%u ydpi=%u x=%i xs=%i y=%i  wx=%i h=%i ***** \n",
740141cc406Sopenharmony_ci                           xdpi, ydpi, x, xs, y, wx, h));
741141cc406Sopenharmony_ci      data = pixma_newcmd (&mp->cb, cmd_scan_param_3, 0x38, 0);
742141cc406Sopenharmony_ci      data[0x00] = (is_scanning_from_adf (s)) ? 0x02 : 0x01;
743141cc406Sopenharmony_ci      data[0x01] = 0x01;
744141cc406Sopenharmony_ci      data[0x02] = 0x01;
745141cc406Sopenharmony_ci      if (is_scanning_from_adfdup (s))
746141cc406Sopenharmony_ci        {
747141cc406Sopenharmony_ci          data[0x02] = 0x03;
748141cc406Sopenharmony_ci          data[0x03] = 0x03;
749141cc406Sopenharmony_ci        }
750141cc406Sopenharmony_ci      if (is_scanning_jpeg (s))
751141cc406Sopenharmony_ci        {
752141cc406Sopenharmony_ci          data[0x03] = 0x01;
753141cc406Sopenharmony_ci        }
754141cc406Sopenharmony_ci      data[0x05] = pixma_calc_calibrate (s);
755141cc406Sopenharmony_ci      pixma_set_be16 (xdpi | 0x8000, data + 0x08);
756141cc406Sopenharmony_ci      pixma_set_be16 (ydpi | 0x8000, data + 0x0a);
757141cc406Sopenharmony_ci      pixma_set_be32 (x - xs, data + 0x0c);
758141cc406Sopenharmony_ci      pixma_set_be32 (y, data + 0x10);
759141cc406Sopenharmony_ci      pixma_set_be32 (wx, data + 0x14);
760141cc406Sopenharmony_ci      pixma_set_be32 (h, data + 0x18);
761141cc406Sopenharmony_ci      /*PDBG (pixma_dbg (4, "*send_scan_param gen. 3+ ***** Setting: channels=%hi depth=%hi ***** \n",
762141cc406Sopenharmony_ci                       s->param->channels, s->param->depth));*/
763141cc406Sopenharmony_ci      data[0x1c] = ((s->param->channels != 1) || (is_gray_16(s)) ? 0x08 : 0x04);
764141cc406Sopenharmony_ci
765141cc406Sopenharmony_ci      data[0x1d] = ((s->param->software_lineart) ? 8 : s->param->depth)
766141cc406Sopenharmony_ci                    * (is_gray_16(s) ? 3 : s->param->channels); /* bits per pixel */
767141cc406Sopenharmony_ci
768141cc406Sopenharmony_ci      data[0x1f] = 0x01;        /* This one also seen at 0. Don't know yet what's used for */
769141cc406Sopenharmony_ci      data[0x20] = 0xff;
770141cc406Sopenharmony_ci      if (is_scanning_jpeg (s))
771141cc406Sopenharmony_ci        {
772141cc406Sopenharmony_ci          data[0x21] = 0x83;
773141cc406Sopenharmony_ci        }
774141cc406Sopenharmony_ci      else
775141cc406Sopenharmony_ci        {
776141cc406Sopenharmony_ci          data[0x21] = 0x81;
777141cc406Sopenharmony_ci        }
778141cc406Sopenharmony_ci      data[0x23] = 0x02;
779141cc406Sopenharmony_ci      data[0x24] = 0x01;
780141cc406Sopenharmony_ci
781141cc406Sopenharmony_ci      switch (s->cfg->pid)
782141cc406Sopenharmony_ci        {
783141cc406Sopenharmony_ci	case MG5300_PID:
784141cc406Sopenharmony_ci	  /* unknown values (perhaps counter) for MG5300 series---values must be 0x30-0x39: decimal 0-9 */
785141cc406Sopenharmony_ci	  data[0x26] = 0x32; /* using example values from a real scan here */
786141cc406Sopenharmony_ci	  data[0x27] = 0x31;
787141cc406Sopenharmony_ci	  data[0x28] = 0x34;
788141cc406Sopenharmony_ci	  data[0x29] = 0x35;
789141cc406Sopenharmony_ci	  break;
790141cc406Sopenharmony_ci
791141cc406Sopenharmony_ci	default:
792141cc406Sopenharmony_ci	  break;
793141cc406Sopenharmony_ci	}
794141cc406Sopenharmony_ci
795141cc406Sopenharmony_ci      data[0x30] = 0x01;
796141cc406Sopenharmony_ci    }
797141cc406Sopenharmony_ci  return pixma_exec (s, &mp->cb);
798141cc406Sopenharmony_ci}
799141cc406Sopenharmony_ci
800141cc406Sopenharmony_cistatic int
801141cc406Sopenharmony_ciquery_status_3 (pixma_t * s)
802141cc406Sopenharmony_ci{
803141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
804141cc406Sopenharmony_ci  uint8_t *data;
805141cc406Sopenharmony_ci  int error, status_len;
806141cc406Sopenharmony_ci
807141cc406Sopenharmony_ci  status_len = 8;
808141cc406Sopenharmony_ci  data = pixma_newcmd (&mp->cb, cmd_status_3, 0, status_len);
809141cc406Sopenharmony_ci  RET_IF_ERR (pixma_exec (s, &mp->cb));
810141cc406Sopenharmony_ci  memcpy (mp->current_status, data, status_len);
811141cc406Sopenharmony_ci  return error;
812141cc406Sopenharmony_ci}
813141cc406Sopenharmony_ci
814141cc406Sopenharmony_cistatic int
815141cc406Sopenharmony_ciquery_status (pixma_t * s)
816141cc406Sopenharmony_ci{
817141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
818141cc406Sopenharmony_ci  uint8_t *data;
819141cc406Sopenharmony_ci  int error, status_len;
820141cc406Sopenharmony_ci
821141cc406Sopenharmony_ci  status_len = (mp->generation == 1) ? 12 : 16;
822141cc406Sopenharmony_ci  data = pixma_newcmd (&mp->cb, cmd_status, 0, status_len);
823141cc406Sopenharmony_ci  RET_IF_ERR (pixma_exec (s, &mp->cb));
824141cc406Sopenharmony_ci  memcpy (mp->current_status, data, status_len);
825141cc406Sopenharmony_ci  PDBG (pixma_dbg (3, "Current status: paper=%u cal=%u lamp=%u busy=%u\n",
826141cc406Sopenharmony_ci		       data[1], data[8], data[7], data[9]));
827141cc406Sopenharmony_ci  return error;
828141cc406Sopenharmony_ci}
829141cc406Sopenharmony_ci
830141cc406Sopenharmony_ci#if 0
831141cc406Sopenharmony_cistatic int
832141cc406Sopenharmony_cisend_time (pixma_t * s)
833141cc406Sopenharmony_ci{
834141cc406Sopenharmony_ci  /* Why does a scanner need a time? */
835141cc406Sopenharmony_ci  time_t now;
836141cc406Sopenharmony_ci  struct tm *t;
837141cc406Sopenharmony_ci  uint8_t *data;
838141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
839141cc406Sopenharmony_ci
840141cc406Sopenharmony_ci  data = pixma_newcmd (&mp->cb, cmd_time, 20, 0);
841141cc406Sopenharmony_ci  pixma_get_time (&now, NULL);
842141cc406Sopenharmony_ci  t = localtime (&now);
843141cc406Sopenharmony_ci  strftime ((char *) data, 16, "%y/%m/%d %H:%M", t);
844141cc406Sopenharmony_ci  PDBG (pixma_dbg (3, "Sending time: '%s'\n", (char *) data));
845141cc406Sopenharmony_ci  return pixma_exec (s, &mp->cb);
846141cc406Sopenharmony_ci}
847141cc406Sopenharmony_ci#endif
848141cc406Sopenharmony_ci
849141cc406Sopenharmony_ci/* TODO: Simplify this function. Read the whole data packet in one shot. */
850141cc406Sopenharmony_cistatic int
851141cc406Sopenharmony_ciread_image_block (pixma_t * s, uint8_t * header, uint8_t * data)
852141cc406Sopenharmony_ci{
853141cc406Sopenharmony_ci  uint8_t cmd[16];
854141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
855141cc406Sopenharmony_ci  const int hlen = 8 + 8;
856141cc406Sopenharmony_ci  int error, datalen;
857141cc406Sopenharmony_ci
858141cc406Sopenharmony_ci  memset (cmd, 0, sizeof (cmd));
859141cc406Sopenharmony_ci  pixma_set_be16 (cmd_read_image, cmd);
860141cc406Sopenharmony_ci  if ((mp->last_block & 0x20) == 0)
861141cc406Sopenharmony_ci    pixma_set_be32 ((IMAGE_BLOCK_SIZE / 65536) * 65536 + 8, cmd + 0xc);
862141cc406Sopenharmony_ci  else
863141cc406Sopenharmony_ci    pixma_set_be32 (32 + 8, cmd + 0xc);
864141cc406Sopenharmony_ci
865141cc406Sopenharmony_ci  mp->state = state_transfering;
866141cc406Sopenharmony_ci  mp->cb.reslen =
867141cc406Sopenharmony_ci    pixma_cmd_transaction (s, cmd, sizeof (cmd), mp->cb.buf, 512);
868141cc406Sopenharmony_ci  datalen = mp->cb.reslen;
869141cc406Sopenharmony_ci  if (datalen < 0)
870141cc406Sopenharmony_ci    return datalen;
871141cc406Sopenharmony_ci
872141cc406Sopenharmony_ci  memcpy (header, mp->cb.buf, hlen);
873141cc406Sopenharmony_ci
874141cc406Sopenharmony_ci  if (datalen >= hlen)
875141cc406Sopenharmony_ci    {
876141cc406Sopenharmony_ci      datalen -= hlen;
877141cc406Sopenharmony_ci      memcpy (data, mp->cb.buf + hlen, datalen);
878141cc406Sopenharmony_ci      data += datalen;
879141cc406Sopenharmony_ci      if (mp->cb.reslen == 512)
880141cc406Sopenharmony_ci        {
881141cc406Sopenharmony_ci          error = pixma_read (s->io, data, IMAGE_BLOCK_SIZE - 512 + hlen);
882141cc406Sopenharmony_ci          RET_IF_ERR (error);
883141cc406Sopenharmony_ci          datalen += error;
884141cc406Sopenharmony_ci        }
885141cc406Sopenharmony_ci    }
886141cc406Sopenharmony_ci
887141cc406Sopenharmony_ci  mp->state = state_scanning;
888141cc406Sopenharmony_ci  mp->cb.expected_reslen = 0;
889141cc406Sopenharmony_ci  RET_IF_ERR (pixma_check_result (&mp->cb));
890141cc406Sopenharmony_ci  if (mp->cb.reslen < hlen)
891141cc406Sopenharmony_ci    return PIXMA_EPROTO;
892141cc406Sopenharmony_ci  return datalen;
893141cc406Sopenharmony_ci}
894141cc406Sopenharmony_ci
895141cc406Sopenharmony_cistatic int
896141cc406Sopenharmony_ciread_error_info (pixma_t * s, void *buf, unsigned size)
897141cc406Sopenharmony_ci{
898141cc406Sopenharmony_ci  unsigned len = 16;
899141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
900141cc406Sopenharmony_ci  uint8_t *data;
901141cc406Sopenharmony_ci  int error;
902141cc406Sopenharmony_ci
903141cc406Sopenharmony_ci  data = pixma_newcmd (&mp->cb, cmd_error_info, 0, len);
904141cc406Sopenharmony_ci  RET_IF_ERR (pixma_exec (s, &mp->cb));
905141cc406Sopenharmony_ci  if (buf && len < size)
906141cc406Sopenharmony_ci    {
907141cc406Sopenharmony_ci      size = len;
908141cc406Sopenharmony_ci      /* NOTE: I've absolutely no idea what the returned data mean. */
909141cc406Sopenharmony_ci      memcpy (buf, data, size);
910141cc406Sopenharmony_ci      error = len;
911141cc406Sopenharmony_ci    }
912141cc406Sopenharmony_ci  return error;
913141cc406Sopenharmony_ci}
914141cc406Sopenharmony_ci
915141cc406Sopenharmony_ci/*
916141cc406Sopenharmony_cihandle_interrupt() waits until it receives an interrupt packet or times out.
917141cc406Sopenharmony_ciIt calls send_time() and query_status() if necessary. Therefore, make sure
918141cc406Sopenharmony_cithat handle_interrupt() is only called from a safe context for send_time()
919141cc406Sopenharmony_ciand query_status().
920141cc406Sopenharmony_ci
921141cc406Sopenharmony_ci   Returns:
922141cc406Sopenharmony_ci   0     timed out
923141cc406Sopenharmony_ci   1     an interrupt packet received
924141cc406Sopenharmony_ci   PIXMA_ECANCELED interrupted by signal
925141cc406Sopenharmony_ci   <0    error
926141cc406Sopenharmony_ci*/
927141cc406Sopenharmony_cistatic int
928141cc406Sopenharmony_cihandle_interrupt (pixma_t * s, int timeout)
929141cc406Sopenharmony_ci{
930141cc406Sopenharmony_ci  uint8_t buf[64];
931141cc406Sopenharmony_ci  int len;
932141cc406Sopenharmony_ci
933141cc406Sopenharmony_ci  len = pixma_wait_interrupt (s->io, buf, sizeof (buf), timeout);
934141cc406Sopenharmony_ci  if (len == PIXMA_ETIMEDOUT)
935141cc406Sopenharmony_ci    return 0;
936141cc406Sopenharmony_ci  if (len < 0)
937141cc406Sopenharmony_ci    return len;
938141cc406Sopenharmony_ci  if (len%16)           /* len must be a multiple of 16 bytes */
939141cc406Sopenharmony_ci    {
940141cc406Sopenharmony_ci      PDBG (pixma_dbg
941141cc406Sopenharmony_ci	    (1, "WARNING:unexpected interrupt packet length %d\n", len));
942141cc406Sopenharmony_ci      return PIXMA_EPROTO;
943141cc406Sopenharmony_ci    }
944141cc406Sopenharmony_ci
945141cc406Sopenharmony_ci  /* s->event = 0x0brroott
946141cc406Sopenharmony_ci   * b:  button
947141cc406Sopenharmony_ci   * oo: original
948141cc406Sopenharmony_ci   * tt: target
949141cc406Sopenharmony_ci   * rr: scan resolution
950141cc406Sopenharmony_ci   * poll event with 'scanimage -A' */
951141cc406Sopenharmony_ci  if (s->cfg->pid == MG5300_PID
952141cc406Sopenharmony_ci      || s->cfg->pid == MG5400_PID
953141cc406Sopenharmony_ci      || s->cfg->pid == MG5700_PID
954141cc406Sopenharmony_ci      || s->cfg->pid == MG6200_PID
955141cc406Sopenharmony_ci      || s->cfg->pid == MG6300_PID
956141cc406Sopenharmony_ci      || s->cfg->pid == MX340_PID
957141cc406Sopenharmony_ci      || s->cfg->pid == MX520_PID
958141cc406Sopenharmony_ci      || s->cfg->pid == MX720_PID
959141cc406Sopenharmony_ci      || s->cfg->pid == MX920_PID
960141cc406Sopenharmony_ci      || s->cfg->pid == MB2300_PID
961141cc406Sopenharmony_ci      || s->cfg->pid == MB5000_PID
962141cc406Sopenharmony_ci      || s->cfg->pid == MB5400_PID
963141cc406Sopenharmony_ci      || s->cfg->pid == TR4500_PID)
964141cc406Sopenharmony_ci  /* button no. in buf[7]
965141cc406Sopenharmony_ci   * size in buf[10] 01=A4; 02=Letter; 08=10x15; 09=13x18; 0b=auto
966141cc406Sopenharmony_ci   * format in buf[11] 01=JPEG; 02=TIFF; 03=PDF; 04=Kompakt-PDF
967141cc406Sopenharmony_ci   * dpi in buf[12] 01=75; 02=150; 03=300; 04=600
968141cc406Sopenharmony_ci   * target = format; original = size; scan-resolution = dpi */
969141cc406Sopenharmony_ci  {
970141cc406Sopenharmony_ci    if (buf[7] & 1)
971141cc406Sopenharmony_ci    {
972141cc406Sopenharmony_ci      /* color scan */
973141cc406Sopenharmony_ci      s->events = PIXMA_EV_BUTTON1 | (buf[11] & 0x0f) | (buf[10] & 0x0f) << 8
974141cc406Sopenharmony_ci                  | (buf[12] & 0x0f) << 16;
975141cc406Sopenharmony_ci    }
976141cc406Sopenharmony_ci    if (buf[7] & 2)
977141cc406Sopenharmony_ci    {
978141cc406Sopenharmony_ci      /* b/w scan */
979141cc406Sopenharmony_ci      s->events = PIXMA_EV_BUTTON2 | (buf[11] & 0x0f) | (buf[10] & 0x0f) << 8
980141cc406Sopenharmony_ci                  | (buf[12] & 0x0f) << 16;
981141cc406Sopenharmony_ci    }
982141cc406Sopenharmony_ci
983141cc406Sopenharmony_ci    /* some scanners provide additional information:
984141cc406Sopenharmony_ci     * document type in buf[6] 01=Document; 02=Photo; 03=Auto Scan
985141cc406Sopenharmony_ci     * ADF status in buf[8] 01 = ADF empty; 02 = ADF filled
986141cc406Sopenharmony_ci     * ADF orientation in buf[16] 01=Portrait; 02=Landscape
987141cc406Sopenharmony_ci     *
988141cc406Sopenharmony_ci     * ToDo: maybe this if isn't needed
989141cc406Sopenharmony_ci     */
990141cc406Sopenharmony_ci    if (s->cfg->pid == TR4500_PID || s->cfg->pid == MX340_PID)
991141cc406Sopenharmony_ci      {
992141cc406Sopenharmony_ci        s->events |= (buf[6] & 0x0f) << 12;
993141cc406Sopenharmony_ci        s->events |= (buf[8] & 0x0f) << 20;
994141cc406Sopenharmony_ci        s->events |= (buf[16] & 0x0f) << 4;
995141cc406Sopenharmony_ci      }
996141cc406Sopenharmony_ci  }
997141cc406Sopenharmony_ci  else if (s->cfg->pid == LIDE300_PID
998141cc406Sopenharmony_ci           || s->cfg->pid == LIDE400_PID)
999141cc406Sopenharmony_ci  /* unknown value in buf[4]
1000141cc406Sopenharmony_ci   * target in buf[0x13] 01=copy; 02=auto; 03=send; 05=start PDF; 06=finish PDF
1001141cc406Sopenharmony_ci   * "Finish PDF" is Button-2, all others are Button-1 */
1002141cc406Sopenharmony_ci  {
1003141cc406Sopenharmony_ci    if (buf[0x13] == 0x06)
1004141cc406Sopenharmony_ci    {
1005141cc406Sopenharmony_ci      /* button 2 = cancel / end scan */
1006141cc406Sopenharmony_ci      s->events = PIXMA_EV_BUTTON2 | (buf[0x13] & 0x0f);
1007141cc406Sopenharmony_ci    }
1008141cc406Sopenharmony_ci    else if (buf[0x13])
1009141cc406Sopenharmony_ci    {
1010141cc406Sopenharmony_ci      /* button 1 = start scan */
1011141cc406Sopenharmony_ci      s->events = PIXMA_EV_BUTTON1 | (buf[0x13] & 0x0f);
1012141cc406Sopenharmony_ci    }
1013141cc406Sopenharmony_ci  }
1014141cc406Sopenharmony_ci  else
1015141cc406Sopenharmony_ci  /* button no. in buf[0]
1016141cc406Sopenharmony_ci   * original in buf[0]
1017141cc406Sopenharmony_ci   * target in buf[1] */
1018141cc406Sopenharmony_ci  {
1019141cc406Sopenharmony_ci    /* More than one event can be reported at the same time. */
1020141cc406Sopenharmony_ci    if (buf[3] & 1)
1021141cc406Sopenharmony_ci      /* FIXME: This function makes trouble with a lot of scanners
1022141cc406Sopenharmony_ci      send_time (s);
1023141cc406Sopenharmony_ci       */
1024141cc406Sopenharmony_ci      PDBG (pixma_dbg (1, "WARNING:send_time() disabled!\n"));
1025141cc406Sopenharmony_ci    if (buf[9] & 2)
1026141cc406Sopenharmony_ci      query_status (s);
1027141cc406Sopenharmony_ci    if (buf[0] & 2)
1028141cc406Sopenharmony_ci    {
1029141cc406Sopenharmony_ci      /* b/w scan */
1030141cc406Sopenharmony_ci      s->events = PIXMA_EV_BUTTON2 | (buf[1] & 0x0f) | (buf[0] & 0xf0) << 4;
1031141cc406Sopenharmony_ci    }
1032141cc406Sopenharmony_ci    if (buf[0] & 1)
1033141cc406Sopenharmony_ci    {
1034141cc406Sopenharmony_ci      /* color scan */
1035141cc406Sopenharmony_ci      s->events = PIXMA_EV_BUTTON1 | (buf[1] & 0x0f) | ((buf[0] & 0xf0) << 4);
1036141cc406Sopenharmony_ci    }
1037141cc406Sopenharmony_ci  }
1038141cc406Sopenharmony_ci  return 1;
1039141cc406Sopenharmony_ci}
1040141cc406Sopenharmony_ci
1041141cc406Sopenharmony_cistatic int
1042141cc406Sopenharmony_ciwait_until_ready (pixma_t * s)
1043141cc406Sopenharmony_ci{
1044141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
1045141cc406Sopenharmony_ci  int error, tmo = 120;         /* some scanners need a long timeout */
1046141cc406Sopenharmony_ci
1047141cc406Sopenharmony_ci  RET_IF_ERR ((mp->generation >= 3) ? query_status_3 (s)
1048141cc406Sopenharmony_ci                                    : query_status (s));
1049141cc406Sopenharmony_ci  while (!is_calibrated (s))
1050141cc406Sopenharmony_ci    {
1051141cc406Sopenharmony_ci      WAIT_INTERRUPT (1000);
1052141cc406Sopenharmony_ci      if (mp->generation >= 3)
1053141cc406Sopenharmony_ci        RET_IF_ERR (query_status_3 (s));
1054141cc406Sopenharmony_ci      else if (s->cfg->pid == MP600_PID ||
1055141cc406Sopenharmony_ci               s->cfg->pid == MP600R_PID)
1056141cc406Sopenharmony_ci        RET_IF_ERR (query_status (s));
1057141cc406Sopenharmony_ci      if (--tmo == 0)
1058141cc406Sopenharmony_ci        {
1059141cc406Sopenharmony_ci          PDBG (pixma_dbg (1, "WARNING:Timed out in wait_until_ready()\n"));
1060141cc406Sopenharmony_ci          PDBG (query_status (s));
1061141cc406Sopenharmony_ci          return PIXMA_ETIMEDOUT;
1062141cc406Sopenharmony_ci        }
1063141cc406Sopenharmony_ci    }
1064141cc406Sopenharmony_ci  return 0;
1065141cc406Sopenharmony_ci}
1066141cc406Sopenharmony_ci
1067141cc406Sopenharmony_cistatic void
1068141cc406Sopenharmony_cireorder_pixels (uint8_t * linebuf, uint8_t * sptr, unsigned c, unsigned n,
1069141cc406Sopenharmony_ci                unsigned m, unsigned w, unsigned line_size)
1070141cc406Sopenharmony_ci{
1071141cc406Sopenharmony_ci  unsigned i;
1072141cc406Sopenharmony_ci
1073141cc406Sopenharmony_ci  for (i = 0; i < w; i++)
1074141cc406Sopenharmony_ci    {
1075141cc406Sopenharmony_ci      memcpy (linebuf + c * (n * (i % m) + i / m), sptr + c * i, c);
1076141cc406Sopenharmony_ci    }
1077141cc406Sopenharmony_ci  memcpy (sptr, linebuf, line_size);
1078141cc406Sopenharmony_ci}
1079141cc406Sopenharmony_ci
1080141cc406Sopenharmony_ci/* the scanned image must be shrunk by factor "scale"
1081141cc406Sopenharmony_ci * the image can be formatted as rgb (c=3) or gray (c=1)
1082141cc406Sopenharmony_ci * we need to crop the left side (xs)
1083141cc406Sopenharmony_ci * we ignore more pixels inside scanned line (wx), behind needed line (w)
1084141cc406Sopenharmony_ci *
1085141cc406Sopenharmony_ci * example (scale=2):
1086141cc406Sopenharmony_ci * line | pixel[0] | pixel[1] | ... | pixel[w-1]
1087141cc406Sopenharmony_ci * ---------
1088141cc406Sopenharmony_ci *  0   |  rgbrgb  |  rgbrgb  | ... |  rgbrgb
1089141cc406Sopenharmony_ci * wx*c |  rgbrgb  |  rgbrgb  | ... |  rgbrgb
1090141cc406Sopenharmony_ci */
1091141cc406Sopenharmony_ciuint8_t *
1092141cc406Sopenharmony_cishrink_image (uint8_t * dptr, uint8_t * sptr, unsigned xs, unsigned w,
1093141cc406Sopenharmony_ci              unsigned wx, unsigned scale, unsigned c)
1094141cc406Sopenharmony_ci{
1095141cc406Sopenharmony_ci  unsigned i, ic;
1096141cc406Sopenharmony_ci  uint16_t pixel;
1097141cc406Sopenharmony_ci  uint8_t *dst = dptr;  /* don't change dptr */
1098141cc406Sopenharmony_ci  uint8_t *src = sptr;  /* don't change sptr */
1099141cc406Sopenharmony_ci
1100141cc406Sopenharmony_ci  /*PDBG (pixma_dbg (4, "%s: w=%d, wx=%d, c=%d, scale=%d\n",
1101141cc406Sopenharmony_ci                   __func__, w, wx, c, scale));
1102141cc406Sopenharmony_ci  PDBG (pixma_dbg (4, "\tdptr=%ld, sptr=%ld\n",
1103141cc406Sopenharmony_ci                   dptr, sptr));*/
1104141cc406Sopenharmony_ci
1105141cc406Sopenharmony_ci  /* crop left side */
1106141cc406Sopenharmony_ci  src += c * xs;
1107141cc406Sopenharmony_ci
1108141cc406Sopenharmony_ci  /* process line */
1109141cc406Sopenharmony_ci  for (i = 0; i < w; i++)
1110141cc406Sopenharmony_ci  {
1111141cc406Sopenharmony_ci    /* process rgb or gray pixel */
1112141cc406Sopenharmony_ci    for (ic = 0; ic < c; ic++)
1113141cc406Sopenharmony_ci    {
1114141cc406Sopenharmony_ci#if 0
1115141cc406Sopenharmony_ci      dst[ic] = src[ic];
1116141cc406Sopenharmony_ci#else
1117141cc406Sopenharmony_ci      pixel = 0;
1118141cc406Sopenharmony_ci
1119141cc406Sopenharmony_ci      /* sum shrink pixels */
1120141cc406Sopenharmony_ci      for (unsigned m = 0; m < scale; m++)    /* get pixels from shrunk lines */
1121141cc406Sopenharmony_ci      {
1122141cc406Sopenharmony_ci        for (unsigned n = 0; n < scale; n++)  /* get pixels from same line */
1123141cc406Sopenharmony_ci        {
1124141cc406Sopenharmony_ci          pixel += src[ic + c * n + wx * c * m];
1125141cc406Sopenharmony_ci        }
1126141cc406Sopenharmony_ci      }
1127141cc406Sopenharmony_ci      dst[ic] = pixel / (scale * scale);
1128141cc406Sopenharmony_ci#endif
1129141cc406Sopenharmony_ci    }
1130141cc406Sopenharmony_ci
1131141cc406Sopenharmony_ci    /* jump over shrunk data */
1132141cc406Sopenharmony_ci    src += c * scale;
1133141cc406Sopenharmony_ci    /* next pixel */
1134141cc406Sopenharmony_ci    dst += c;
1135141cc406Sopenharmony_ci  }
1136141cc406Sopenharmony_ci
1137141cc406Sopenharmony_ci  return dst;
1138141cc406Sopenharmony_ci}
1139141cc406Sopenharmony_ci
1140141cc406Sopenharmony_ci/* This function deals with Generation >= 3 high dpi images.
1141141cc406Sopenharmony_ci * Each complete line in mp->imgbuf is processed for reordering pixels above
1142141cc406Sopenharmony_ci * 600 dpi for Generation >= 3. */
1143141cc406Sopenharmony_cistatic unsigned
1144141cc406Sopenharmony_cipost_process_image_data (pixma_t * s, pixma_imagebuf_t * ib)
1145141cc406Sopenharmony_ci{
1146141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
1147141cc406Sopenharmony_ci  unsigned c, lines, line_size, n, m, cw, cx;
1148141cc406Sopenharmony_ci  uint8_t *sptr, *dptr, *gptr, *cptr;
1149141cc406Sopenharmony_ci
1150141cc406Sopenharmony_ci  if (s->param->mode_jpeg)
1151141cc406Sopenharmony_ci    {
1152141cc406Sopenharmony_ci      /* No post-processing, send raw JPEG data to main */
1153141cc406Sopenharmony_ci      ib->rptr = mp->imgbuf;
1154141cc406Sopenharmony_ci      ib->rend = mp->data_left_ofs;
1155141cc406Sopenharmony_ci      return 0;    /* # of non processed bytes */
1156141cc406Sopenharmony_ci    }
1157141cc406Sopenharmony_ci
1158141cc406Sopenharmony_ci  /* process image sizes */
1159141cc406Sopenharmony_ci  c = (is_gray_16(s) ? 3 : s->param->channels)
1160141cc406Sopenharmony_ci      * ((s->param->software_lineart) ? 8 : s->param->depth) / 8;   /* color channels count */
1161141cc406Sopenharmony_ci  cw = c * s->param->w;                                             /* image width */
1162141cc406Sopenharmony_ci  cx = c * s->param->xs;                                            /* x-offset */
1163141cc406Sopenharmony_ci
1164141cc406Sopenharmony_ci  /* special image format parameters
1165141cc406Sopenharmony_ci   * n: no. of sub-images
1166141cc406Sopenharmony_ci   * m: sub-image width
1167141cc406Sopenharmony_ci   */
1168141cc406Sopenharmony_ci  if (mp->generation >= 3)
1169141cc406Sopenharmony_ci    n = s->param->xdpi / 600;
1170141cc406Sopenharmony_ci  else
1171141cc406Sopenharmony_ci    n = s->param->xdpi / 2400;
1172141cc406Sopenharmony_ci  if (s->cfg->pid == MP600_PID || s->cfg->pid == MP600R_PID || s->cfg->pid == XK90_PID)
1173141cc406Sopenharmony_ci    n = s->param->xdpi / 1200;
1174141cc406Sopenharmony_ci  m = (n > 0) ? s->param->wx / n : 1;
1175141cc406Sopenharmony_ci
1176141cc406Sopenharmony_ci  /* Initialize pointers */
1177141cc406Sopenharmony_ci  sptr = dptr = gptr = cptr = mp->imgbuf;
1178141cc406Sopenharmony_ci
1179141cc406Sopenharmony_ci  /* walk through complete received lines */
1180141cc406Sopenharmony_ci  line_size = get_cis_line_size (s);
1181141cc406Sopenharmony_ci  lines = (mp->data_left_ofs - mp->imgbuf) / line_size;
1182141cc406Sopenharmony_ci  if (lines > 0)
1183141cc406Sopenharmony_ci    {
1184141cc406Sopenharmony_ci      unsigned i;
1185141cc406Sopenharmony_ci
1186141cc406Sopenharmony_ci      /*PDBG (pixma_dbg (4, "*post_process_image_data***** Processing with c=%u, n=%u, m=%u, wx=%i, line_size=%u, cx=%u, cw=%u ***** \n",
1187141cc406Sopenharmony_ci                       c, n, m, s->param->wx, line_size, cx, cw));*/
1188141cc406Sopenharmony_ci      /*PDBG (pixma_dbg (4, "*post_process_image_data***** lines = %i ***** \n", lines));*/
1189141cc406Sopenharmony_ci
1190141cc406Sopenharmony_ci      for (i = 0; i < lines; i++, sptr += line_size)
1191141cc406Sopenharmony_ci        {
1192141cc406Sopenharmony_ci          /*PDBG (pixma_dbg (4, "*post_process_image_data***** Processing with c=%u, n=%u, m=%u, w=%i, line_size=%u ***** \n",
1193141cc406Sopenharmony_ci                           c, n, m, s->param->wx, line_size));*/
1194141cc406Sopenharmony_ci          /*PDBG (pixma_dbg (4, "*post_process_image_data***** Pointers: sptr=%lx, dptr=%lx, linebuf=%lx ***** \n",
1195141cc406Sopenharmony_ci                           sptr, dptr, mp->linebuf));*/
1196141cc406Sopenharmony_ci
1197141cc406Sopenharmony_ci          /* special image format for *most* devices at high dpi.
1198141cc406Sopenharmony_ci           * MP220, MX360 and generation 5 scanners are exceptions */
1199141cc406Sopenharmony_ci          if (n > 1
1200141cc406Sopenharmony_ci              && s->cfg->pid != MP220_PID
1201141cc406Sopenharmony_ci              && s->cfg->pid != MX360_PID
1202141cc406Sopenharmony_ci              && (mp->generation < 5
1203141cc406Sopenharmony_ci                  /* generation 5 scanners *with* special image format */
1204141cc406Sopenharmony_ci                  || s->cfg->pid == MG2200_PID
1205141cc406Sopenharmony_ci                  || s->cfg->pid == MG3200_PID
1206141cc406Sopenharmony_ci                  || s->cfg->pid == MG4200_PID
1207141cc406Sopenharmony_ci                  || s->cfg->pid == MG5600_PID
1208141cc406Sopenharmony_ci                  || s->cfg->pid == MG5700_PID
1209141cc406Sopenharmony_ci                  || s->cfg->pid == MG6200_PID
1210141cc406Sopenharmony_ci                  || s->cfg->pid == MP230_PID
1211141cc406Sopenharmony_ci                  || s->cfg->pid == MX470_PID
1212141cc406Sopenharmony_ci                  || s->cfg->pid == MX510_PID
1213141cc406Sopenharmony_ci                  || s->cfg->pid == XK90_PID
1214141cc406Sopenharmony_ci                  || s->cfg->pid == MX520_PID))
1215141cc406Sopenharmony_ci              reorder_pixels (mp->linebuf, sptr, c, n, m, s->param->wx, line_size);
1216141cc406Sopenharmony_ci
1217141cc406Sopenharmony_ci
1218141cc406Sopenharmony_ci          /* scale image */
1219141cc406Sopenharmony_ci          if (mp->scale > 1)
1220141cc406Sopenharmony_ci          {
1221141cc406Sopenharmony_ci            /* Crop line inside shrink_image() */
1222141cc406Sopenharmony_ci            shrink_image(cptr, sptr, s->param->xs, s->param->w, s->param->wx, mp->scale, c);
1223141cc406Sopenharmony_ci          }
1224141cc406Sopenharmony_ci          else
1225141cc406Sopenharmony_ci          {
1226141cc406Sopenharmony_ci            /* Crop line to selected borders */
1227141cc406Sopenharmony_ci            memmove(cptr, sptr + cx, cw);
1228141cc406Sopenharmony_ci          }
1229141cc406Sopenharmony_ci
1230141cc406Sopenharmony_ci          /* Color / Gray to Lineart convert */
1231141cc406Sopenharmony_ci          if (s->param->software_lineart)
1232141cc406Sopenharmony_ci              cptr = gptr = pixma_binarize_line (s->param, gptr, cptr, s->param->w, c);
1233141cc406Sopenharmony_ci          /* Color to Grayscale convert for 16bit gray */
1234141cc406Sopenharmony_ci          else if (is_gray_16(s))
1235141cc406Sopenharmony_ci            cptr = gptr = pixma_rgb_to_gray (gptr, cptr, s->param->w, c);
1236141cc406Sopenharmony_ci          else
1237141cc406Sopenharmony_ci              cptr += cw;
1238141cc406Sopenharmony_ci        }
1239141cc406Sopenharmony_ci    }
1240141cc406Sopenharmony_ci  ib->rptr = mp->imgbuf;
1241141cc406Sopenharmony_ci  ib->rend = cptr;
1242141cc406Sopenharmony_ci  return mp->data_left_ofs - sptr;    /* # of non processed bytes */
1243141cc406Sopenharmony_ci}
1244141cc406Sopenharmony_ci
1245141cc406Sopenharmony_cistatic int
1246141cc406Sopenharmony_cimp150_open (pixma_t * s)
1247141cc406Sopenharmony_ci{
1248141cc406Sopenharmony_ci  mp150_t *mp;
1249141cc406Sopenharmony_ci  uint8_t *buf;
1250141cc406Sopenharmony_ci
1251141cc406Sopenharmony_ci  mp = (mp150_t *) calloc (1, sizeof (*mp));
1252141cc406Sopenharmony_ci  if (!mp)
1253141cc406Sopenharmony_ci    return PIXMA_ENOMEM;
1254141cc406Sopenharmony_ci
1255141cc406Sopenharmony_ci  buf = (uint8_t *) malloc (CMDBUF_SIZE + IMAGE_BLOCK_SIZE);
1256141cc406Sopenharmony_ci  if (!buf)
1257141cc406Sopenharmony_ci    {
1258141cc406Sopenharmony_ci      free (mp);
1259141cc406Sopenharmony_ci      return PIXMA_ENOMEM;
1260141cc406Sopenharmony_ci    }
1261141cc406Sopenharmony_ci
1262141cc406Sopenharmony_ci  s->subdriver = mp;
1263141cc406Sopenharmony_ci  mp->state = state_idle;
1264141cc406Sopenharmony_ci
1265141cc406Sopenharmony_ci  mp->cb.buf = buf;
1266141cc406Sopenharmony_ci  mp->cb.size = CMDBUF_SIZE;
1267141cc406Sopenharmony_ci  mp->cb.res_header_len = 8;
1268141cc406Sopenharmony_ci  mp->cb.cmd_header_len = 16;
1269141cc406Sopenharmony_ci  mp->cb.cmd_len_field_ofs = 14;
1270141cc406Sopenharmony_ci
1271141cc406Sopenharmony_ci  mp->imgbuf = buf + CMDBUF_SIZE;
1272141cc406Sopenharmony_ci
1273141cc406Sopenharmony_ci  /* General rules for setting Pixma protocol generation # */
1274141cc406Sopenharmony_ci  mp->generation = (s->cfg->pid >= MP160_PID) ? 2 : 1;
1275141cc406Sopenharmony_ci
1276141cc406Sopenharmony_ci  if (s->cfg->pid >= MX7600_PID)
1277141cc406Sopenharmony_ci    mp->generation = 3;
1278141cc406Sopenharmony_ci
1279141cc406Sopenharmony_ci  if (s->cfg->pid >= MP250_PID)
1280141cc406Sopenharmony_ci    mp->generation = 4;
1281141cc406Sopenharmony_ci
1282141cc406Sopenharmony_ci  if (s->cfg->pid >= MG2100_PID)        /* this scanners generation doesn't need */
1283141cc406Sopenharmony_ci    mp->generation = 5;                 /* special image conversion @ high dpi */
1284141cc406Sopenharmony_ci
1285141cc406Sopenharmony_ci  /* And exceptions to be added here */
1286141cc406Sopenharmony_ci  if (s->cfg->pid == MP140_PID)
1287141cc406Sopenharmony_ci    mp->generation = 2;
1288141cc406Sopenharmony_ci
1289141cc406Sopenharmony_ci  PDBG (pixma_dbg (3, "*mp150_open***** This is a generation %d scanner.  *****\n", mp->generation));
1290141cc406Sopenharmony_ci
1291141cc406Sopenharmony_ci  /* adf scanning */
1292141cc406Sopenharmony_ci  mp->adf_state = state_idle;
1293141cc406Sopenharmony_ci
1294141cc406Sopenharmony_ci  if (mp->generation < 4)
1295141cc406Sopenharmony_ci    {
1296141cc406Sopenharmony_ci      query_status (s);
1297141cc406Sopenharmony_ci      handle_interrupt (s, 200);
1298141cc406Sopenharmony_ci    }
1299141cc406Sopenharmony_ci  return 0;
1300141cc406Sopenharmony_ci}
1301141cc406Sopenharmony_ci
1302141cc406Sopenharmony_cistatic void
1303141cc406Sopenharmony_cimp150_close (pixma_t * s)
1304141cc406Sopenharmony_ci{
1305141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
1306141cc406Sopenharmony_ci
1307141cc406Sopenharmony_ci  mp150_finish_scan (s);
1308141cc406Sopenharmony_ci  free (mp->cb.buf);
1309141cc406Sopenharmony_ci  free (mp);
1310141cc406Sopenharmony_ci  s->subdriver = NULL;
1311141cc406Sopenharmony_ci}
1312141cc406Sopenharmony_ci
1313141cc406Sopenharmony_cistatic int
1314141cc406Sopenharmony_cimp150_check_param (pixma_t * s, pixma_scan_param_t * sp)
1315141cc406Sopenharmony_ci{
1316141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
1317141cc406Sopenharmony_ci
1318141cc406Sopenharmony_ci  /* PDBG (pixma_dbg (4, "*mp150_check_param***** Initially: channels=%u, depth=%u, x=%u, y=%u, w=%u, h=%u, xs=%u, wx=%u, gamma=%f *****\n",
1319141cc406Sopenharmony_ci                   sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx, sp->gamma)); */
1320141cc406Sopenharmony_ci
1321141cc406Sopenharmony_ci  sp->channels = 3;
1322141cc406Sopenharmony_ci  sp->software_lineart = 0;
1323141cc406Sopenharmony_ci  switch (sp->mode)
1324141cc406Sopenharmony_ci  {
1325141cc406Sopenharmony_ci    /* standard scan modes
1326141cc406Sopenharmony_ci     * 8 bit per channel in color and grayscale mode */
1327141cc406Sopenharmony_ci    case PIXMA_SCAN_MODE_GRAY:
1328141cc406Sopenharmony_ci      sp->channels = 1;
1329141cc406Sopenharmony_ci      /* fall through */
1330141cc406Sopenharmony_ci    case PIXMA_SCAN_MODE_COLOR:
1331141cc406Sopenharmony_ci      sp->depth = 8;
1332141cc406Sopenharmony_ci      break;
1333141cc406Sopenharmony_ci      /* extended scan modes for 48 bit flatbed scanners
1334141cc406Sopenharmony_ci       * 16 bit per channel in color and grayscale mode */
1335141cc406Sopenharmony_ci    case PIXMA_SCAN_MODE_GRAY_16:
1336141cc406Sopenharmony_ci      sp->channels = 1;
1337141cc406Sopenharmony_ci      sp->depth = 16;
1338141cc406Sopenharmony_ci      break;
1339141cc406Sopenharmony_ci    case PIXMA_SCAN_MODE_COLOR_48:
1340141cc406Sopenharmony_ci      sp->channels = 3;
1341141cc406Sopenharmony_ci      sp->depth = 16;
1342141cc406Sopenharmony_ci      break;
1343141cc406Sopenharmony_ci      /* software lineart
1344141cc406Sopenharmony_ci       * 1 bit per channel */
1345141cc406Sopenharmony_ci    case PIXMA_SCAN_MODE_LINEART:
1346141cc406Sopenharmony_ci      sp->software_lineart = 1;
1347141cc406Sopenharmony_ci      sp->channels = 1;
1348141cc406Sopenharmony_ci      sp->depth = 1;
1349141cc406Sopenharmony_ci      break;
1350141cc406Sopenharmony_ci    default:
1351141cc406Sopenharmony_ci      break;
1352141cc406Sopenharmony_ci  }
1353141cc406Sopenharmony_ci
1354141cc406Sopenharmony_ci  /* for software lineart w must be a multiple of 8 */
1355141cc406Sopenharmony_ci  if (sp->software_lineart == 1 && sp->w % 8)
1356141cc406Sopenharmony_ci    {
1357141cc406Sopenharmony_ci      unsigned w_max;
1358141cc406Sopenharmony_ci
1359141cc406Sopenharmony_ci      sp->w += 8 - (sp->w % 8);
1360141cc406Sopenharmony_ci
1361141cc406Sopenharmony_ci      /* do not exceed the scanner capability */
1362141cc406Sopenharmony_ci      w_max = s->cfg->width * s->cfg->xdpi / 75;
1363141cc406Sopenharmony_ci      w_max -= w_max % 8;
1364141cc406Sopenharmony_ci      if (sp->w > w_max)
1365141cc406Sopenharmony_ci        sp->w = w_max;
1366141cc406Sopenharmony_ci    }
1367141cc406Sopenharmony_ci
1368141cc406Sopenharmony_ci  if (mp->generation >= 2)
1369141cc406Sopenharmony_ci    {
1370141cc406Sopenharmony_ci      /* mod 32 and expansion of the X scan limits */
1371141cc406Sopenharmony_ci      /*PDBG (pixma_dbg (4, "*mp150_check_param***** ----- Initially: x=%i, y=%i, w=%i, h=%i *****\n", sp->x, sp->y, sp->w, sp->h));*/
1372141cc406Sopenharmony_ci      sp->xs = (sp->x * mp->scale) % 32;
1373141cc406Sopenharmony_ci    }
1374141cc406Sopenharmony_ci  else
1375141cc406Sopenharmony_ci      sp->xs = 0;
1376141cc406Sopenharmony_ci  /*PDBG (pixma_dbg (4, "*mp150_check_param***** Selected origin, origin shift: %i, %i *****\n", sp->x, sp->xs));*/
1377141cc406Sopenharmony_ci  sp->wx = calc_raw_width (mp, sp);
1378141cc406Sopenharmony_ci  sp->line_size = sp->w * sp->channels * (((sp->software_lineart) ? 8 : sp->depth) / 8);              /* bytes per line per color after cropping */
1379141cc406Sopenharmony_ci  /*PDBG (pixma_dbg (4, "*mp150_check_param***** Final scan width and line-size: %i, %li *****\n", sp->wx, sp->line_size));*/
1380141cc406Sopenharmony_ci
1381141cc406Sopenharmony_ci  /* Some exceptions here for particular devices */
1382141cc406Sopenharmony_ci  /* Those devices can scan up to legal 14" with ADF, but A4 11.7" in flatbed */
1383141cc406Sopenharmony_ci  /* PIXMA_CAP_ADF also works for PIXMA_CAP_ADFDUP */
1384141cc406Sopenharmony_ci  if ((s->cfg->cap & PIXMA_CAP_ADF) && sp->source == PIXMA_SOURCE_FLATBED)
1385141cc406Sopenharmony_ci    sp->h = MIN (sp->h, 877 * sp->xdpi / 75);
1386141cc406Sopenharmony_ci
1387141cc406Sopenharmony_ci  if (sp->source == PIXMA_SOURCE_ADF || sp->source == PIXMA_SOURCE_ADFDUP)
1388141cc406Sopenharmony_ci    {
1389141cc406Sopenharmony_ci      uint8_t k = 1;
1390141cc406Sopenharmony_ci
1391141cc406Sopenharmony_ci  /* ADF/ADF duplex mode: max scan res is 600 dpi, at least for generation 4+ */
1392141cc406Sopenharmony_ci      if (mp->generation >= 4)
1393141cc406Sopenharmony_ci        k = sp->xdpi / MIN (sp->xdpi, 600);
1394141cc406Sopenharmony_ci      sp->x /= k;
1395141cc406Sopenharmony_ci      sp->xs /= k;
1396141cc406Sopenharmony_ci      sp->y /= k;
1397141cc406Sopenharmony_ci      sp->w /= k;
1398141cc406Sopenharmony_ci      sp->wx /= k;
1399141cc406Sopenharmony_ci      sp->h /= k;
1400141cc406Sopenharmony_ci      sp->xdpi /= k;
1401141cc406Sopenharmony_ci      sp->ydpi = sp->xdpi;
1402141cc406Sopenharmony_ci    }
1403141cc406Sopenharmony_ci
1404141cc406Sopenharmony_ci  sp->mode_jpeg = (s->cfg->cap & PIXMA_CAP_ADF_JPEG) &&
1405141cc406Sopenharmony_ci                      (sp->source == PIXMA_SOURCE_ADF ||
1406141cc406Sopenharmony_ci                       sp->source == PIXMA_SOURCE_ADFDUP);
1407141cc406Sopenharmony_ci
1408141cc406Sopenharmony_ci  mp->scale = 1;
1409141cc406Sopenharmony_ci  if (s->cfg->min_xdpi && sp->xdpi < s->cfg->min_xdpi)
1410141cc406Sopenharmony_ci  {
1411141cc406Sopenharmony_ci    mp->scale = s->cfg->min_xdpi / sp->xdpi;
1412141cc406Sopenharmony_ci  }
1413141cc406Sopenharmony_ci  /*PDBG (pixma_dbg (4, "*mp150_check_param***** xdpi=%u, min_xdpi=%u, scale=%u *****\n",
1414141cc406Sopenharmony_ci                   sp->xdpi, s->cfg->min_xdpi, mp->scale));*/
1415141cc406Sopenharmony_ci
1416141cc406Sopenharmony_ci  /*PDBG (pixma_dbg (4, "*mp150_check_param***** Finally: channels=%u, depth=%u, x=%u, y=%u, w=%u, h=%u, xs=%u, wx=%u *****\n",
1417141cc406Sopenharmony_ci                   sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx));*/
1418141cc406Sopenharmony_ci  return 0;
1419141cc406Sopenharmony_ci}
1420141cc406Sopenharmony_ci
1421141cc406Sopenharmony_cistatic int
1422141cc406Sopenharmony_cimp150_scan (pixma_t * s)
1423141cc406Sopenharmony_ci{
1424141cc406Sopenharmony_ci  int error = 0, tmo;
1425141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
1426141cc406Sopenharmony_ci
1427141cc406Sopenharmony_ci  if (mp->state != state_idle)
1428141cc406Sopenharmony_ci    return PIXMA_EBUSY;
1429141cc406Sopenharmony_ci
1430141cc406Sopenharmony_ci  /* no paper inserted after first adf page => abort session */
1431141cc406Sopenharmony_ci  if (s->param->adf_pageid && is_scanning_from_adf(s) && mp->adf_state == state_idle)
1432141cc406Sopenharmony_ci  {
1433141cc406Sopenharmony_ci    return PIXMA_ENO_PAPER;
1434141cc406Sopenharmony_ci  }
1435141cc406Sopenharmony_ci
1436141cc406Sopenharmony_ci  /* Generation 4+: send XML dialog */
1437141cc406Sopenharmony_ci  /* adf: first page or idle */
1438141cc406Sopenharmony_ci  if (mp->generation >= 4 && mp->adf_state == state_idle)
1439141cc406Sopenharmony_ci    {
1440141cc406Sopenharmony_ci      if (!send_xml_dialog (s, XML_START_1))
1441141cc406Sopenharmony_ci        return PIXMA_EPROTO;
1442141cc406Sopenharmony_ci      if (!send_xml_dialog (s, XML_START_2))
1443141cc406Sopenharmony_ci        return PIXMA_EPROTO;
1444141cc406Sopenharmony_ci    }
1445141cc406Sopenharmony_ci
1446141cc406Sopenharmony_ci  /* clear interrupt packets buffer */
1447141cc406Sopenharmony_ci  while (handle_interrupt (s, 0) > 0)
1448141cc406Sopenharmony_ci    {
1449141cc406Sopenharmony_ci    }
1450141cc406Sopenharmony_ci
1451141cc406Sopenharmony_ci  /* FIXME: Duplex ADF: check paper status only before odd pages (1,3,5,...). */
1452141cc406Sopenharmony_ci  if (is_scanning_from_adf (s))
1453141cc406Sopenharmony_ci    {
1454141cc406Sopenharmony_ci      if ((error = query_status (s)) < 0)
1455141cc406Sopenharmony_ci        return error;
1456141cc406Sopenharmony_ci
1457141cc406Sopenharmony_ci      /* wait for inserted paper
1458141cc406Sopenharmony_ci       * timeout: 10 sec */
1459141cc406Sopenharmony_ci      tmo = 10;
1460141cc406Sopenharmony_ci      while (!has_paper (s) && --tmo >= 0)
1461141cc406Sopenharmony_ci        {
1462141cc406Sopenharmony_ci          if ((error = query_status (s)) < 0)
1463141cc406Sopenharmony_ci            return error;
1464141cc406Sopenharmony_ci          WAIT_INTERRUPT (1000);
1465141cc406Sopenharmony_ci          PDBG (pixma_dbg
1466141cc406Sopenharmony_ci            (2, "No paper in ADF. Timed out in %d sec.\n", tmo));
1467141cc406Sopenharmony_ci        }
1468141cc406Sopenharmony_ci
1469141cc406Sopenharmony_ci      /* no paper inserted
1470141cc406Sopenharmony_ci       * => abort session */
1471141cc406Sopenharmony_ci      if (!has_paper (s))
1472141cc406Sopenharmony_ci      {
1473141cc406Sopenharmony_ci        PDBG (pixma_dbg (4, "*mp150_scan***** no paper in ADF *****\n"));
1474141cc406Sopenharmony_ci        error = abort_session (s);
1475141cc406Sopenharmony_ci        if (error < 0)
1476141cc406Sopenharmony_ci          return error;
1477141cc406Sopenharmony_ci
1478141cc406Sopenharmony_ci        /* Generation 4+: send XML dialog */
1479141cc406Sopenharmony_ci        /* adf: first page or idle */
1480141cc406Sopenharmony_ci        if (mp->generation >= 4 && mp->adf_state == state_idle)
1481141cc406Sopenharmony_ci        {
1482141cc406Sopenharmony_ci          if (!send_xml_dialog (s, XML_END))
1483141cc406Sopenharmony_ci            return PIXMA_EPROTO;
1484141cc406Sopenharmony_ci        }
1485141cc406Sopenharmony_ci
1486141cc406Sopenharmony_ci        return PIXMA_ENO_PAPER;
1487141cc406Sopenharmony_ci      }
1488141cc406Sopenharmony_ci    }
1489141cc406Sopenharmony_ci
1490141cc406Sopenharmony_ci  tmo = 10;
1491141cc406Sopenharmony_ci  /* adf: first page or idle */
1492141cc406Sopenharmony_ci  if (mp->generation <= 2 || mp->adf_state == state_idle)
1493141cc406Sopenharmony_ci    { /* single sheet or first sheet from ADF */
1494141cc406Sopenharmony_ci      PDBG (pixma_dbg (4, "*mp150_scan***** start scanning *****\n"));
1495141cc406Sopenharmony_ci      error = start_session (s);
1496141cc406Sopenharmony_ci      while (error == PIXMA_EBUSY && --tmo >= 0)
1497141cc406Sopenharmony_ci        {
1498141cc406Sopenharmony_ci          if (s->cancel)
1499141cc406Sopenharmony_ci            {
1500141cc406Sopenharmony_ci              error = PIXMA_ECANCELED;
1501141cc406Sopenharmony_ci              break;
1502141cc406Sopenharmony_ci            }
1503141cc406Sopenharmony_ci          PDBG (pixma_dbg
1504141cc406Sopenharmony_ci          (2, "Scanner is busy. Timed out in %d sec.\n", tmo + 1));
1505141cc406Sopenharmony_ci          pixma_sleep (1000000);
1506141cc406Sopenharmony_ci          error = start_session (s);
1507141cc406Sopenharmony_ci        }
1508141cc406Sopenharmony_ci      if (error == PIXMA_EBUSY || error == PIXMA_ETIMEDOUT)
1509141cc406Sopenharmony_ci        {
1510141cc406Sopenharmony_ci          /* The scanner maybe hangs. We try to empty output buffer of the
1511141cc406Sopenharmony_ci           * scanner and issue the cancel command. */
1512141cc406Sopenharmony_ci          PDBG (pixma_dbg (2, "Scanner hangs? Sending abort_session command.\n"));
1513141cc406Sopenharmony_ci          drain_bulk_in (s);
1514141cc406Sopenharmony_ci          abort_session (s);
1515141cc406Sopenharmony_ci          pixma_sleep (500000);
1516141cc406Sopenharmony_ci          error = start_session (s);
1517141cc406Sopenharmony_ci        }
1518141cc406Sopenharmony_ci      if ((error >= 0) || (mp->generation >= 3))
1519141cc406Sopenharmony_ci        mp->state = state_warmup;
1520141cc406Sopenharmony_ci      if ((error >= 0) && (mp->generation <= 2))
1521141cc406Sopenharmony_ci        error = select_source (s);
1522141cc406Sopenharmony_ci      if ((error >= 0) && !is_scanning_jpeg (s))
1523141cc406Sopenharmony_ci        {
1524141cc406Sopenharmony_ci          int i;
1525141cc406Sopenharmony_ci
1526141cc406Sopenharmony_ci          for (i = (mp->generation >= 3) ? 3 : 1 ; i > 0 && error >= 0; i--)
1527141cc406Sopenharmony_ci            error = send_gamma_table (s);
1528141cc406Sopenharmony_ci        }
1529141cc406Sopenharmony_ci    }
1530141cc406Sopenharmony_ci  else   /* ADF pageid != 0 and gen3 or above */
1531141cc406Sopenharmony_ci  { /* next sheet from ADF */
1532141cc406Sopenharmony_ci    PDBG (pixma_dbg (4, "*mp150_scan***** scan next sheet from ADF  *****\n"));
1533141cc406Sopenharmony_ci    pixma_sleep (1000000);
1534141cc406Sopenharmony_ci  }
1535141cc406Sopenharmony_ci  if ((error >= 0) || (mp->generation >= 3))
1536141cc406Sopenharmony_ci    mp->state = state_warmup;
1537141cc406Sopenharmony_ci  if (error >= 0)
1538141cc406Sopenharmony_ci    error = send_scan_param (s);
1539141cc406Sopenharmony_ci  if ((error >= 0) && (mp->generation >= 3))
1540141cc406Sopenharmony_ci    error = start_scan_3 (s);
1541141cc406Sopenharmony_ci  if (error < 0)
1542141cc406Sopenharmony_ci    {
1543141cc406Sopenharmony_ci      mp->last_block = 0x38;   /* Force abort session if ADF scan */
1544141cc406Sopenharmony_ci      mp150_finish_scan (s);
1545141cc406Sopenharmony_ci      return error;
1546141cc406Sopenharmony_ci    }
1547141cc406Sopenharmony_ci
1548141cc406Sopenharmony_ci  /* ADF scanning active */
1549141cc406Sopenharmony_ci  if (is_scanning_from_adf (s))
1550141cc406Sopenharmony_ci    mp->adf_state = state_scanning;
1551141cc406Sopenharmony_ci  return 0;
1552141cc406Sopenharmony_ci}
1553141cc406Sopenharmony_ci
1554141cc406Sopenharmony_cistatic int
1555141cc406Sopenharmony_cimp150_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib)
1556141cc406Sopenharmony_ci{
1557141cc406Sopenharmony_ci  int error;
1558141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
1559141cc406Sopenharmony_ci  unsigned block_size, bytes_received, proc_buf_size, line_size;
1560141cc406Sopenharmony_ci  uint8_t header[16];
1561141cc406Sopenharmony_ci
1562141cc406Sopenharmony_ci  if (mp->state == state_warmup)
1563141cc406Sopenharmony_ci    {
1564141cc406Sopenharmony_ci      RET_IF_ERR (wait_until_ready (s));
1565141cc406Sopenharmony_ci      pixma_sleep (1000000);	/* No need to sleep, actually, but Window's driver
1566141cc406Sopenharmony_ci				 * sleep 1.5 sec. */
1567141cc406Sopenharmony_ci      mp->state = state_scanning;
1568141cc406Sopenharmony_ci      mp->last_block = 0;
1569141cc406Sopenharmony_ci
1570141cc406Sopenharmony_ci      line_size = get_cis_line_size (s);
1571141cc406Sopenharmony_ci      proc_buf_size = 2 * line_size;
1572141cc406Sopenharmony_ci      mp->cb.buf = realloc (mp->cb.buf,
1573141cc406Sopenharmony_ci             CMDBUF_SIZE + IMAGE_BLOCK_SIZE + proc_buf_size);
1574141cc406Sopenharmony_ci      if (!mp->cb.buf)
1575141cc406Sopenharmony_ci        return PIXMA_ENOMEM;
1576141cc406Sopenharmony_ci      mp->linebuf = mp->cb.buf + CMDBUF_SIZE;
1577141cc406Sopenharmony_ci      mp->imgbuf = mp->data_left_ofs = mp->linebuf + line_size;
1578141cc406Sopenharmony_ci      mp->data_left_len = 0;
1579141cc406Sopenharmony_ci    }
1580141cc406Sopenharmony_ci
1581141cc406Sopenharmony_ci  do
1582141cc406Sopenharmony_ci    {
1583141cc406Sopenharmony_ci      if (s->cancel)
1584141cc406Sopenharmony_ci      {
1585141cc406Sopenharmony_ci        PDBG (pixma_dbg (4, "*mp150_fill_buffer***** s->cancel  *****\n"));
1586141cc406Sopenharmony_ci        return PIXMA_ECANCELED;
1587141cc406Sopenharmony_ci      }
1588141cc406Sopenharmony_ci      if ((mp->last_block & 0x28) == 0x28)
1589141cc406Sopenharmony_ci        {  /* end of image */
1590141cc406Sopenharmony_ci           PDBG (pixma_dbg (4, "*mp150_fill_buffer***** end of image  *****\n"));
1591141cc406Sopenharmony_ci           mp->state = state_finished;
1592141cc406Sopenharmony_ci           return 0;
1593141cc406Sopenharmony_ci        }
1594141cc406Sopenharmony_ci      /*PDBG (pixma_dbg (4, "*mp150_fill_buffer***** moving %u bytes into buffer *****\n", mp->data_left_len));*/
1595141cc406Sopenharmony_ci      memmove (mp->imgbuf, mp->data_left_ofs, mp->data_left_len);
1596141cc406Sopenharmony_ci      error = read_image_block (s, header, mp->imgbuf + mp->data_left_len);
1597141cc406Sopenharmony_ci      if (error < 0)
1598141cc406Sopenharmony_ci        {
1599141cc406Sopenharmony_ci          PDBG (pixma_dbg (4, "*mp150_fill_buffer***** scanner error (%d): end scan  *****\n", error));
1600141cc406Sopenharmony_ci          mp->last_block = 0x38;        /* end scan in mp150_finish_scan() */
1601141cc406Sopenharmony_ci          if (error == PIXMA_ECANCELED)
1602141cc406Sopenharmony_ci            {
1603141cc406Sopenharmony_ci               /* NOTE: I see this in traffic logs but I don't know its meaning. */
1604141cc406Sopenharmony_ci               read_error_info (s, NULL, 0);
1605141cc406Sopenharmony_ci            }
1606141cc406Sopenharmony_ci          return error;
1607141cc406Sopenharmony_ci        }
1608141cc406Sopenharmony_ci
1609141cc406Sopenharmony_ci      bytes_received = error;
1610141cc406Sopenharmony_ci      /*PDBG (pixma_dbg (4, "*mp150_fill_buffer***** %u bytes received by read_image_block *****\n", bytes_received));*/
1611141cc406Sopenharmony_ci      block_size = pixma_get_be32 (header + 12);
1612141cc406Sopenharmony_ci      mp->last_block = header[8] & 0x38;
1613141cc406Sopenharmony_ci      if ((header[8] & ~0x38) != 0)
1614141cc406Sopenharmony_ci        {
1615141cc406Sopenharmony_ci          PDBG (pixma_dbg (1, "WARNING: Unexpected result header\n"));
1616141cc406Sopenharmony_ci          PDBG (pixma_hexdump (1, header, 16));
1617141cc406Sopenharmony_ci        }
1618141cc406Sopenharmony_ci      PASSERT (bytes_received == block_size);
1619141cc406Sopenharmony_ci
1620141cc406Sopenharmony_ci      if (block_size == 0)
1621141cc406Sopenharmony_ci        {     /* no image data at this moment. */
1622141cc406Sopenharmony_ci          pixma_sleep (10000);
1623141cc406Sopenharmony_ci        }
1624141cc406Sopenharmony_ci      /* Post-process the image data */
1625141cc406Sopenharmony_ci      mp->data_left_ofs = mp->imgbuf + mp->data_left_len + bytes_received;
1626141cc406Sopenharmony_ci      mp->data_left_len = post_process_image_data (s, ib);
1627141cc406Sopenharmony_ci      mp->data_left_ofs -= mp->data_left_len;
1628141cc406Sopenharmony_ci    }
1629141cc406Sopenharmony_ci  while (ib->rend == ib->rptr);
1630141cc406Sopenharmony_ci
1631141cc406Sopenharmony_ci  return ib->rend - ib->rptr;
1632141cc406Sopenharmony_ci}
1633141cc406Sopenharmony_ci
1634141cc406Sopenharmony_cistatic void
1635141cc406Sopenharmony_cimp150_finish_scan (pixma_t * s)
1636141cc406Sopenharmony_ci{
1637141cc406Sopenharmony_ci  int error;
1638141cc406Sopenharmony_ci  mp150_t *mp = (mp150_t *) s->subdriver;
1639141cc406Sopenharmony_ci
1640141cc406Sopenharmony_ci  switch (mp->state)
1641141cc406Sopenharmony_ci    {
1642141cc406Sopenharmony_ci    case state_transfering:
1643141cc406Sopenharmony_ci      drain_bulk_in (s);
1644141cc406Sopenharmony_ci      /* fall through */
1645141cc406Sopenharmony_ci    case state_scanning:
1646141cc406Sopenharmony_ci    case state_warmup:
1647141cc406Sopenharmony_ci    case state_finished:
1648141cc406Sopenharmony_ci      /* FIXME: to process several pages ADF scan, must not send
1649141cc406Sopenharmony_ci       * abort_session and start_session between pages (last_block=0x28) */
1650141cc406Sopenharmony_ci      if (mp->generation <= 2 || !is_scanning_from_adf (s) || mp->last_block == 0x38)
1651141cc406Sopenharmony_ci        {
1652141cc406Sopenharmony_ci          PDBG (pixma_dbg (4, "*mp150_finish_scan***** abort session  *****\n"));
1653141cc406Sopenharmony_ci          error = abort_session (s);  /* FIXME: it probably doesn't work in duplex mode! */
1654141cc406Sopenharmony_ci          if (error < 0)
1655141cc406Sopenharmony_ci            PDBG (pixma_dbg (1, "WARNING:abort_session() failed %d\n", error));
1656141cc406Sopenharmony_ci
1657141cc406Sopenharmony_ci          /* Generation 4+: send XML end of scan dialog */
1658141cc406Sopenharmony_ci          if (mp->generation >= 4)
1659141cc406Sopenharmony_ci            {
1660141cc406Sopenharmony_ci              if (!send_xml_dialog (s, XML_END))
1661141cc406Sopenharmony_ci                PDBG (pixma_dbg (1, "WARNING:XML_END dialog failed \n"));
1662141cc406Sopenharmony_ci            }
1663141cc406Sopenharmony_ci        }
1664141cc406Sopenharmony_ci      else
1665141cc406Sopenharmony_ci        PDBG (pixma_dbg (4, "*mp150_finish_scan***** wait for next page from ADF  *****\n"));
1666141cc406Sopenharmony_ci
1667141cc406Sopenharmony_ci      mp->state = state_idle;
1668141cc406Sopenharmony_ci      /* fall through */
1669141cc406Sopenharmony_ci    case state_idle:
1670141cc406Sopenharmony_ci      break;
1671141cc406Sopenharmony_ci    }
1672141cc406Sopenharmony_ci}
1673141cc406Sopenharmony_ci
1674141cc406Sopenharmony_cistatic void
1675141cc406Sopenharmony_cimp150_wait_event (pixma_t * s, int timeout)
1676141cc406Sopenharmony_ci{
1677141cc406Sopenharmony_ci  /* FIXME: timeout is not correct. See usbGetCompleteUrbNoIntr() for
1678141cc406Sopenharmony_ci   * instance. */
1679141cc406Sopenharmony_ci  while (s->events == 0 && handle_interrupt (s, timeout) > 0)
1680141cc406Sopenharmony_ci    {
1681141cc406Sopenharmony_ci    }
1682141cc406Sopenharmony_ci}
1683141cc406Sopenharmony_ci
1684141cc406Sopenharmony_cistatic int
1685141cc406Sopenharmony_cimp150_get_status (pixma_t * s, pixma_device_status_t * status)
1686141cc406Sopenharmony_ci{
1687141cc406Sopenharmony_ci  int error;
1688141cc406Sopenharmony_ci
1689141cc406Sopenharmony_ci  RET_IF_ERR (query_status (s));
1690141cc406Sopenharmony_ci  status->hardware = PIXMA_HARDWARE_OK;
1691141cc406Sopenharmony_ci  status->adf = (has_paper (s)) ? PIXMA_ADF_OK : PIXMA_ADF_NO_PAPER;
1692141cc406Sopenharmony_ci  status->cal =
1693141cc406Sopenharmony_ci    (is_calibrated (s)) ? PIXMA_CALIBRATION_OK : PIXMA_CALIBRATION_OFF;
1694141cc406Sopenharmony_ci  return 0;
1695141cc406Sopenharmony_ci}
1696141cc406Sopenharmony_ci
1697141cc406Sopenharmony_cistatic const pixma_scan_ops_t pixma_mp150_ops = {
1698141cc406Sopenharmony_ci  mp150_open,
1699141cc406Sopenharmony_ci  mp150_close,
1700141cc406Sopenharmony_ci  mp150_scan,
1701141cc406Sopenharmony_ci  mp150_fill_buffer,
1702141cc406Sopenharmony_ci  mp150_finish_scan,
1703141cc406Sopenharmony_ci  mp150_wait_event,
1704141cc406Sopenharmony_ci  mp150_check_param,
1705141cc406Sopenharmony_ci  mp150_get_status
1706141cc406Sopenharmony_ci};
1707141cc406Sopenharmony_ci
1708141cc406Sopenharmony_ci#define DEVICE(name, model, pid, min_dpi, dpi, adftpu_min_dpi, adftpu_max_dpi, w, h, cap) { \
1709141cc406Sopenharmony_ci        name,              /* name */               \
1710141cc406Sopenharmony_ci        model,             /* model */              \
1711141cc406Sopenharmony_ci        CANON_VID, pid,    /* vid pid */            \
1712141cc406Sopenharmony_ci        0,                 /* iface */              \
1713141cc406Sopenharmony_ci        &pixma_mp150_ops,  /* ops */                \
1714141cc406Sopenharmony_ci        min_dpi,           /* min_xdpi */           \
1715141cc406Sopenharmony_ci        0,                 /* min_xdpi_16 not used in this subdriver */ \
1716141cc406Sopenharmony_ci        dpi, 2*(dpi),      /* xdpi, ydpi */         \
1717141cc406Sopenharmony_ci        adftpu_min_dpi, adftpu_max_dpi,         /* adftpu_min_dpi, adftpu_max_dpi */ \
1718141cc406Sopenharmony_ci        0, 0,              /* tpuir_min_dpi & tpuir_max_dpi not used in this subdriver */  \
1719141cc406Sopenharmony_ci        w, h,              /* width, height */      \
1720141cc406Sopenharmony_ci        PIXMA_CAP_EASY_RGB|                         \
1721141cc406Sopenharmony_ci        PIXMA_CAP_GRAY|    /* CIS with native grayscale */ \
1722141cc406Sopenharmony_ci        PIXMA_CAP_LINEART| /* all scanners with software lineart */ \
1723141cc406Sopenharmony_ci        PIXMA_CAP_GAMMA_TABLE|PIXMA_CAP_EVENTS|cap  \
1724141cc406Sopenharmony_ci}
1725141cc406Sopenharmony_ci
1726141cc406Sopenharmony_ci#define END_OF_DEVICE_LIST DEVICE(NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0)
1727141cc406Sopenharmony_ci
1728141cc406Sopenharmony_ciconst pixma_config_t pixma_mp150_devices[] = {
1729141cc406Sopenharmony_ci  /* Generation 1: CIS */
1730141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP150", "MP150", MP150_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_GT_4096),
1731141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP170", "MP170", MP170_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_GT_4096),
1732141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP450", "MP450", MP450_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_GT_4096),
1733141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP500", "MP500", MP500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_GT_4096),
1734141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP530", "MP530", MP530_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_GT_4096 | PIXMA_CAP_ADF),
1735141cc406Sopenharmony_ci
1736141cc406Sopenharmony_ci  /* Generation 2: CIS */
1737141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP140", "MP140", MP140_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1738141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP160", "MP160", MP160_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1739141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP180", "MP180", MP180_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1740141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP460", "MP460", MP460_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1741141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP510", "MP510", MP510_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1742141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP600", "MP600", MP600_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1743141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP600R", "MP600R", MP600R_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1744141cc406Sopenharmony_ci
1745141cc406Sopenharmony_ci  /* Generation 3: CIS */
1746141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP210", "MP210", MP210_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1747141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP220", "MP220", MP220_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1748141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP470", "MP470", MP470_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1749141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP520", "MP520", MP520_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1750141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP610", "MP610", MP610_PID, 0, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS),
1751141cc406Sopenharmony_ci
1752141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX300", "MX300", MX300_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1753141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX310", "MX310", MX310_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1754141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX700", "MX700", MX700_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1755141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX850", "MX850", MX850_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),
1756141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX7600", "MX7600", MX7600_PID, 0, 4800, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),
1757141cc406Sopenharmony_ci
1758141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP630", "MP630", MP630_PID, 0, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS),
1759141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP620", "MP620", MP620_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1760141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP540", "MP540", MP540_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1761141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP480", "MP480", MP480_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1762141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP240", "MP240", MP240_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1763141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP260", "MP260", MP260_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1764141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP190", "MP190", MP190_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1765141cc406Sopenharmony_ci
1766141cc406Sopenharmony_ci  /* PIXMA 2009 vintage */
1767141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX320", "MX320", MX320_PID, 0, 1200, 0, 600, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1768141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX330", "MX330", MX330_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1769141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX860", "MX860", MX860_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),
1770141cc406Sopenharmony_ci/* width and height adjusted to flatbed size 21.8 x 30.2 cm^2 respective
1771141cc406Sopenharmony_ci * Not sure if anything's going wrong here, leaving as is
1772141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX860", "MX860", MX860_PID, 0, 2400, 0, 0, 638, 880, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),*/
1773141cc406Sopenharmony_ci
1774141cc406Sopenharmony_ci  /* PIXMA 2010 vintage */
1775141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX340", "MX340", MX340_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1776141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX350", "MX350", MX350_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1777141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX870", "MX870", MX870_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),
1778141cc406Sopenharmony_ci
1779141cc406Sopenharmony_ci  /* PIXMA 2011 vintage */
1780141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX360", "MX360", MX360_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1781141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX410", "MX410", MX410_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1782141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX420", "MX420", MX420_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1783141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX880 Series", "MX880", MX880_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),
1784141cc406Sopenharmony_ci
1785141cc406Sopenharmony_ci  /* Generation 4: CIS */
1786141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP640", "MP640", MP640_PID, 0, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS),
1787141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP560", "MP560", MP560_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1788141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP550", "MP550", MP550_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1789141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP490", "MP490", MP490_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1790141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP250", "MP250", MP250_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1791141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP270", "MP270", MP270_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1792141cc406Sopenharmony_ci
1793141cc406Sopenharmony_ci  /* Latest devices (2010) Generation 4 CIS */
1794141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP280",  "MP280",  MP280_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), /* TODO: 1200dpi doesn't work yet */
1795141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP495",  "MP495",  MP495_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), /* ToDo: max. scan resolution = 1200x600dpi */
1796141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG5100", "MG5100", MG5100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1797141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG5200", "MG5200", MG5200_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1798141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG6100", "MG6100", MG6100_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1799141cc406Sopenharmony_ci
1800141cc406Sopenharmony_ci  /* Latest devices (2011) Generation 5 CIS */
1801141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG2100", "MG2100", MG2100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1802141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG3100", "MG3100", MG3100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1803141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG4100", "MG4100", MG4100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1804141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG5300", "MG5300", MG5300_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1805141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG6200", "MG6200", MG6200_PID, 0, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS),
1806141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP493",  "MP493",  MP493_PID, 0,  1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1807141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E500",   "E500",   E500_PID, 0,   1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1808141cc406Sopenharmony_ci
1809141cc406Sopenharmony_ci  /* Latest devices (2012) Generation 5 CIS */
1810141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX370 Series", "MX370", MX370_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1811141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX430 Series", "MX430", MX430_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1812141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX510 Series", "MX510", MX510_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1813141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX710 Series", "MX710", MX710_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),
1814141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX890 Series", "MX890", MX890_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),
1815141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E600 Series",  "E600",  E600_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1816141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG4200", "MG4200", MG4200_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1817141cc406Sopenharmony_ci
1818141cc406Sopenharmony_ci  /* Latest devices (2013) Generation 5 CIS */
1819141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E510",  "E510",  E510_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1820141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E610",  "E610",  E610_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1821141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MP230", "MP230", MP230_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1822141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG2200 Series", "MG2200", MG2200_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1823141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG3200 Series", "MG3200", MG3200_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1824141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG5400 Series", "MG5400", MG5400_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1825141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG6300 Series", "MG6300", MG6300_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1826141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX390 Series", "MX390", MX390_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1827141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX450 Series", "MX450", MX450_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1828141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX520 Series", "MX520", MX520_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1829141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX720 Series", "MX720", MX720_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),
1830141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX920 Series", "MX920", MX920_PID, 0, 2400, 0, 600, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),
1831141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG2400 Series", "MG2400", MG2400_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1832141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG2500 Series", "MG2500", MG2500_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1833141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG3500 Series", "MG3500", MG3500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1834141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG5500 Series", "MG5500", MG5500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1835141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG6400 Series", "MG6400", MG6400_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1836141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG6500 Series", "MG6500", MG6500_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1837141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG7100 Series", "MG7100", MG7100_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1838141cc406Sopenharmony_ci
1839141cc406Sopenharmony_ci  /* Latest devices (2014) Generation 5 CIS */
1840141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX470 Series", "MX470", MX470_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1841141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX530 Series", "MX530", MX530_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1842141cc406Sopenharmony_ci  DEVICE ("Canon MAXIFY MB5000 Series", "MB5000", MB5000_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG),
1843141cc406Sopenharmony_ci  DEVICE ("Canon MAXIFY MB5300 Series", "MB5300", MB5300_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),
1844141cc406Sopenharmony_ci  DEVICE ("Canon MAXIFY MB2000 Series", "MB2000", MB2000_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP | PIXMA_CAP_ADF_JPEG),
1845141cc406Sopenharmony_ci  DEVICE ("Canon MAXIFY MB2100 Series", "MB2100", MB2100_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG),
1846141cc406Sopenharmony_ci  DEVICE ("Canon MAXIFY MB2300 Series", "MB2300", MB2300_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG),
1847141cc406Sopenharmony_ci  DEVICE ("Canon MAXIFY MB2700 Series", "MB2700", MB2700_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG),
1848141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E400",  "E400",  E400_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1849141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E560",  "E560",  E560_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1850141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG7500 Series", "MG7500", MG7500_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1851141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG6600 Series", "MG6600", MG6600_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1852141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG5600 Series", "MG5600", MG5600_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1853141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG2900 Series", "MG2900", MG2900_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1854141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E460 Series",  "E460",  E460_PID, 0,  600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1855141cc406Sopenharmony_ci
1856141cc406Sopenharmony_ci  /* Latest devices (2015) Generation 5 CIS */
1857141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MX490 Series", "MX490", MX490_PID, 0, 600, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG),
1858141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E480 Series",  "E480",  E480_PID, 0, 600, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1859141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG3600 Series", "MG3600", MG3600_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1860141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG7700 Series", "MG7700", MG7700_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1861141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG6900 Series", "MG6900", MG6900_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1862141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG6800 Series", "MG6800", MG6800_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1863141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG5700 Series", "MG5700", MG5700_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1864141cc406Sopenharmony_ci
1865141cc406Sopenharmony_ci  /* Latest devices (2016) Generation 5 CIS */
1866141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G3000", "G3000", G3000_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1867141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G2000", "G2000", G2000_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1868141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS9000 Series", "TS9000", TS9000_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1869141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS8000 Series", "TS8000", TS8000_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1870141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS6000 Series", "TS6000", TS6000_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1871141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS5000 Series", "TS5000", TS5000_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1872141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA MG3000 Series", "MG3000", MG3000_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1873141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E470 Series", "E470", E470_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1874141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E410 Series", "E410", E410_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1875141cc406Sopenharmony_ci
1876141cc406Sopenharmony_ci  /* Latest devices (2017) Generation 5 CIS */
1877141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G4000", "G4000", G4000_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1878141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS6100 Series", "TS6100", TS6100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1879141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS5100 Series", "TS5100", TS5100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1880141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS3100 Series", "TS3100", TS3100_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1881141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E3100 Series", "E3100", E3100_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1882141cc406Sopenharmony_ci
1883141cc406Sopenharmony_ci  /* Latest devices (2018) Generation 5 CIS */
1884141cc406Sopenharmony_ci  DEVICE ("Canon MAXIFY MB5400 Series", "MB5400", MB5400_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP | PIXMA_CAP_ADF_JPEG),
1885141cc406Sopenharmony_ci  DEVICE ("Canon MAXIFY MB5100 Series", "MB5100", MB5100_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP | PIXMA_CAP_ADF_JPEG),
1886141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS9100 Series", "TS9100", TS9100_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1887141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR8500 Series", "TR8500", TR8500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG),
1888141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR7500 Series", "TR7500", TR7500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1889141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS9500 Series", "TS9500", TS9500_PID, 0, 1200, 0, 600, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1890141cc406Sopenharmony_ci  DEVICE ("CanoScan LiDE 400", "LIDE400", LIDE400_PID, 300, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_48BIT),
1891141cc406Sopenharmony_ci  DEVICE ("CanoScan LiDE 300", "LIDE300", LIDE300_PID, 300, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1892141cc406Sopenharmony_ci
1893141cc406Sopenharmony_ci  /* Latest devices (2019) Generation 5 CIS */
1894141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS8100 Series", "TS8100", TS8100_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1895141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G2010 Series", "G2010", G2010_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1896141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G3010 Series", "G3010", G3010_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1897141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G4010 Series", "G4010", G4010_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1898141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS9180 Series", "TS9180", TS9180_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1899141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS8180 Series", "TS8180", TS8180_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1900141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS6180 Series", "TS6180", TS6180_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1901141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR8580 Series", "TR8580", TR8580_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1902141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS8130 Series", "TS8130", TS8130_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS),
1903141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS6130 Series", "TS6130", TS6130_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1904141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR8530 Series", "TR8530", TR8530_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1905141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR7530 Series", "TR7530", TR7530_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1906141cc406Sopenharmony_ci  DEVICE ("Canon PIXUS XK50 Series", "XK50", XK50_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1907141cc406Sopenharmony_ci  DEVICE ("Canon PIXUS XK70 Series", "XK70", XK70_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1908141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR4500 Series", "TR4500", TR4500_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG),   /* ToDo: max. scan resolution = 600x1200dpi */
1909141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E4200 Series", "E4200", E4200_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1910141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS6200 Series", "TS6200", TS6200_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1911141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS6280 Series", "TS6280", TS6280_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1912141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS6230 Series", "TS6230", TS6230_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1913141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS8200 Series", "TS8200", TS8200_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1914141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS8280 Series", "TS8280", TS8280_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1915141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS8230 Series", "TS8230", TS8230_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1916141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS9580 Series", "TS9580", TS9580_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1917141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR9530 Series", "TR9530", TR9530_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1918141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G7000 Series", "G7000", G7000_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),      /* ToDo: ADF has legal paper length */
1919141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G6000 Series", "G6000", G6000_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1920141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G6080 Series", "G6080", G6080_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1921141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA GM4000 Series", "GM4000", GM4000_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),   /* ToDo: ADF has legal paper length */
1922141cc406Sopenharmony_ci  DEVICE ("Canon PIXUS XK80 Series", "XK80", XK80_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1923141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS5300 Series", "TS5300", TS5300_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1924141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS5380 Series", "TS5380", TS5380_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1925141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS6300 Series", "TS6300", TS6300_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1926141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS6380 Series", "TS6380", TS6380_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1927141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS7330 Series", "TS7330", TS7330_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1928141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS8380 Series", "TS8380", TS8380_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1929141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS8330 Series", "TS8330", TS8330_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1930141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA XK60 Series", "XK60", XK60_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1931141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS6330 Series", "TS6330", TS6330_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1932141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS3300 Series", "TS3300", TS3300_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1933141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E3300 Series", "E3300", E3300_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1934141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS3400 Series", "TS3400", TS3400_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1935141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E3400 Series", "E3400", E3400_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1936141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR7000 Series", "TR7000", TR7000_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1937141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G2020", "G2020", G2020_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1938141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G3060", "G3060", G3060_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1939141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G2060", "G2060", G2060_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1940141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G3020", "G3020", G3020_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1941141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS7430 Series", "TS7430", TS7430_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1942141cc406Sopenharmony_ci  DEVICE ("Canon PIXUS XK90 Series", "XK90", XK90_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1943141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS8430 Series", "TS8430", TS8430_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1944141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR7600 Series", "TR7600", TR7600_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1945141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR8600 Series", "TR8600", TR8600_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1946141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR8630 Series", "TR8630", TR8630_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1947141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS6400 Series", "TS6400", TS6400_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1948141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS7400 Series", "TS7400", TS7400_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1949141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G7080 Series", "G7080", G7080_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1950141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA GM4080", "GM4080", GM4080_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1951141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS5350i Series", "TS5350i", TS5350i_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1952141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA G600", "G600", G600_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1953141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS3500 Series", "TS3500", TS3500_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1954141cc406Sopenharmony_ci  /* ToDo: max. scan resolution = 600x1200dpi */
1955141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR4600 Series", "TR4600", TR4600_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG),
1956141cc406Sopenharmony_ci  /* ToDo: max. scan resolution = 600x1200dpi */
1957141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TR4700 Series", "TR4700", TR4700_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG),
1958141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA E4500 Series", "E4500", E4500_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1959141cc406Sopenharmony_ci  DEVICE ("Canon PIXUS XK500 Series", "XK500", XK500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1960141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS8530 Series", "TS8530", TS8530_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1961141cc406Sopenharmony_ci  DEVICE ("Canon PIXUS XK100 Series", "XK100", XK100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1962141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS7530 Series", "TS7530", TS7530_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1963141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS7450i Series", "TS7450i", TS7450i_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1964141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA GX6000 Series", "GX6000", GX6000_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1965141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA GX7000 Series", "GX7000", GX7000_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
1966141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS5400 Series", "TS5400", TS5400_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
1967141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS2400 Series", "TS2400", TS2400_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1968141cc406Sopenharmony_ci  DEVICE ("Canon PIXMA TS2600 Series", "TS2600", TS2600_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
1969141cc406Sopenharmony_ci
1970141cc406Sopenharmony_ci  END_OF_DEVICE_LIST
1971141cc406Sopenharmony_ci};
1972