1  /*
2  *   Shinko/Sinfonia Common Code
3  *
4  *   (c) 2019 Solomon Peachy <pizza@shaftnet.org>
5  *
6  *   The latest version of this program can be found at:
7  *
8  *     http://git.shaftnet.org/cgit/selphy_print.git
9  *
10  *   This program is free software; you can redistribute it and/or modify it
11  *   under the terms of the GNU General Public License as published by the Free
12  *   Software Foundation; either version 2 of the License, or (at your option)
13  *   any later version.
14  *
15  *   This program is distributed in the hope that it will be useful, but
16  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18  *   for more details.
19  *
20  *   You should have received a copy of the GNU General Public License
21  *   along with this program; if not, write to the Free Software
22  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23  *
24  *          [http://www.gnu.org/licenses/gpl-2.0.html]
25  *
26  *   SPDX-License-Identifier: GPL-2.0+
27  *
28  */
29 
30 #define LIBSINFONIA_VER "0.08"
31 
32 #define SINFONIA_HDR1_LEN 0x10
33 #define SINFONIA_HDR2_LEN 0x64
34 #define SINFONIA_HDR_LEN (SINFONIA_HDR1_LEN + SINFONIA_HDR2_LEN)
35 #define SINFONIA_DPI 300
36 
37 struct sinfonia_job_param {
38 	uint32_t columns;
39 	uint32_t rows;
40 	uint32_t copies;
41 
42 	uint32_t method;
43 	uint32_t media;
44 	uint32_t oc_mode;
45 
46 	uint32_t quality;
47 
48 	int      mattedepth;
49 	uint32_t dust;
50 
51 	uint32_t ext_flags;
52 };
53 
54 struct sinfonia_printjob {
55 	struct sinfonia_job_param jp;
56 
57 	uint8_t *databuf;
58 	int datalen;
59 	int copies;
60 };
61 
62 int sinfonia_read_parse(int data_fd, uint32_t model,
63 			struct sinfonia_printjob *job);
64 
65 int sinfonia_raw10_read_parse(int data_fd, struct sinfonia_printjob *job);
66 int sinfonia_raw18_read_parse(int data_fd, struct sinfonia_printjob *job);
67 int sinfonia_raw28_read_parse(int data_fd, struct sinfonia_printjob *job);
68 void sinfonia_cleanup_job(const void *vjob);
69 
70 /* Common usb functions */
71 struct sinfonia_usbdev {
72 	struct libusb_device_handle *dev;
73 	uint8_t endp_up;
74 	uint8_t endp_down;
75 	int type;
76 
77 	char const *(*error_codes)(uint8_t major, uint8_t minor);
78 };
79 int sinfonia_docmd(struct sinfonia_usbdev *usbh,
80 		   uint8_t *cmd, int cmdlen,
81 		   uint8_t *resp, int resplen,
82 		   int *num);
83 int sinfonia_flashled(struct sinfonia_usbdev *usbh);
84 int sinfonia_canceljob(struct sinfonia_usbdev *usbh, int id);
85 int sinfonia_getparam(struct sinfonia_usbdev *usbh, int target, uint32_t *param);
86 int sinfonia_setparam(struct sinfonia_usbdev *usbh, int target, uint32_t param);
87 int sinfonia_getfwinfo(struct sinfonia_usbdev *usbh);
88 int sinfonia_geterrorlog(struct sinfonia_usbdev *usbh);
89 int sinfonia_resetcurve(struct sinfonia_usbdev *usbh, int target, int id);
90 int sinfonia_gettonecurve(struct sinfonia_usbdev *usbh, int type, char *fname);
91 int sinfonia_settonecurve(struct sinfonia_usbdev *usbh, int target, char *fname);
92 
93 #define BANK_STATUS_FREE  0x00
94 #define BANK_STATUS_XFER  0x01
95 #define BANK_STATUS_FULL  0x02
96 #define BANK_STATUS_PRINTING  0x12  /* Not on S2145 */
97 
98 const char *sinfonia_bank_statuses(uint8_t v);
99 
100 #define UPDATE_TARGET_USER    0x03
101 #define UPDATE_TARGET_CURRENT 0x04
102 
103 /* Update is three channels, Y, M, C;
104    each is 256 entries of 11-bit data padded to 16-bits.
105    Printer expects LE data.  We use BE data on disk.
106 */
107 #define TONE_CURVE_SIZE 0x600
108 const char *sinfonia_update_targets (uint8_t v);
109 
110 #define TONECURVE_INIT    0x00
111 #define TONECURVE_USER    0x01
112 #define TONECURVE_CURRENT 0x02
113 
114 const char *sinfonia_tonecurve_statuses (uint8_t v);
115 
116 struct sinfonia_error_item {
117 	uint8_t  major;
118 	uint8_t  minor;
119 	uint32_t print_counter;
120 } __attribute__((packed));
121 
122 #define ERROR_NONE              0x00
123 #define ERROR_INVALID_PARAM     0x01
124 #define ERROR_MAIN_APP_INACTIVE 0x02
125 #define ERROR_COMMS_TIMEOUT     0x03
126 #define ERROR_MAINT_NEEDED      0x04
127 #define ERROR_BAD_COMMAND       0x05
128 #define ERROR_PRINTER           0x11
129 #define ERROR_BUFFER_FULL       0x21
130 
131 const char *sinfonia_error_str(uint8_t v);
132 
133 enum {
134 	MEDIA_TYPE_UNKNOWN = 0x00,
135 	MEDIA_TYPE_PAPER = 0x01,
136 };
137 
138 const char *sinfonia_media_types(uint8_t v);
139 
140 #define PRINT_MODE_NO_OC        0x01
141 #define PRINT_MODE_GLOSSY       0x02
142 #define PRINT_MODE_MATTE        0x03
143 const char *sinfonia_print_modes(uint8_t v);
144 
145 #define PRINT_METHOD_STD     0x00
146 #define PRINT_METHOD_COMBO_2 0x02
147 #define PRINT_METHOD_COMBO_3 0x03 // S6245 only
148 #define PRINT_METHOD_SPLIT   0x04
149 #define PRINT_METHOD_DOUBLE  0x08 // S6145 only
150 #define PRINT_METHOD_DISABLE_ERR 0x10 // S6245 only
151 #define PRINT_METHOD_NOTRIM  0x80 // S6145 only
152 
153 const char *sinfonia_print_methods (uint8_t v);
154 
155 #define FWINFO_TARGET_MAIN_BOOT    0x01
156 #define FWINFO_TARGET_MAIN_APP     0x02
157 #define FWINFO_TARGET_PRINT_TABLES 0x03
158 #define FWINFO_TARGET_DSP          0x04
159 #define FWINFO_TARGET_USB          0x06
160 #define FWINFO_TARGET_PRINT_TABLES2 0x07
161 
162 const char *sinfonia_fwinfo_targets (uint8_t v);
163 
164 /* Common command structs */
165 struct sinfonia_cmd_hdr {
166 	uint16_t cmd;
167 	uint16_t len;  /* Not including this header */
168 } __attribute__((packed));
169 
170 struct sinfonia_status_hdr {
171 	uint8_t  result;
172 	uint8_t  error;
173 	uint8_t  printer_major;
174 	uint8_t  printer_minor;
175 	uint8_t  reserved[2];
176 	uint8_t  mode;  /* S6245 and EK605 only, so far */
177 	uint8_t  status;
178 	uint16_t payload_len;
179 } __attribute__((packed));
180 
181 struct sinfonia_cancel_cmd {
182 	struct sinfonia_cmd_hdr hdr;
183 	uint8_t  id;
184 } __attribute__((packed));
185 
186 struct sinfonia_fwinfo_cmd {
187 	struct sinfonia_cmd_hdr hdr;
188 	uint8_t  target;
189 } __attribute__((packed));
190 
191 struct sinfonia_fwinfo_resp {
192 	struct sinfonia_status_hdr hdr;
193 	uint8_t  name[8];
194 	uint8_t  type[16];
195 	uint8_t  date[10];
196 	uint8_t  major;
197 	uint8_t  minor;
198 	uint16_t checksum;
199 } __attribute__((packed));
200 
201 struct sinfonia_errorlog_resp {
202 	struct sinfonia_status_hdr hdr;
203 	uint8_t  count;
204 	struct sinfonia_error_item items[10];  /* Not all necessarily used */
205 } __attribute__((packed));
206 
207 struct sinfonia_mediainfo_item {
208 	uint8_t  code;
209 	uint16_t columns;
210 	uint16_t rows;
211 	uint8_t  type; /* S2145, EK68xx, EK605 only -- MEDIA_TYPE_* */
212 	uint8_t  method; /* PRINT_METHOD_* */
213 	uint8_t  flag;   /* EK68xx only */
214 	uint8_t  reserved[2];
215 } __attribute__((packed));
216 
217 struct sinfonia_setparam_cmd {
218 	struct sinfonia_cmd_hdr hdr;
219 	uint8_t target;
220 	uint32_t param;
221 } __attribute__((packed));
222 
223 struct sinfonia_diagnostic_cmd {
224 	struct sinfonia_cmd_hdr hdr;
225 	uint8_t arg1;
226 	uint8_t arg2;
227 	uint8_t arg3;
228 } __attribute__((packed));
229 
230 struct sinfonia_getparam_cmd {
231 	struct sinfonia_cmd_hdr hdr;
232 	uint8_t target;
233 } __attribute__((packed));
234 
235 struct sinfonia_getparam_resp {
236 	struct sinfonia_status_hdr hdr;
237 	uint32_t param;
238 } __attribute__((packed));
239 
240 struct sinfonia_getprintidstatus_cmd {
241 	struct sinfonia_cmd_hdr hdr;
242 	uint8_t id;
243 } __attribute__((packed));
244 
245 struct sinfonia_getprintidstatus_resp {
246 	struct sinfonia_status_hdr hdr;
247 	uint8_t  id;
248 	uint16_t remaining;
249 	uint16_t finished;
250 	uint16_t specified;
251 	uint16_t status;
252 } __attribute__((packed));
253 
254 #define IDSTATUS_WAITING   0x0000
255 #define IDSTATUS_PRINTING  0x0100
256 #define IDSTATUS_COMPLETED 0x0200
257 #define IDSTATUS_ERROR     0xFFFF
258 
259 struct sinfonia_reset_cmd {
260 	struct sinfonia_cmd_hdr hdr;
261 	uint8_t  target;
262 	uint8_t  curveid;
263 } __attribute__((packed));
264 
265 #define RESET_PRINTER       0x03
266 #define RESET_TONE_CURVE    0x04
267 
268 #define TONE_CURVE_ID       0x01
269 
270 struct sinfonia_readtone_cmd {
271 	struct sinfonia_cmd_hdr hdr;
272 	uint8_t  target;
273 	uint8_t  curveid;
274 } __attribute__((packed));
275 
276 #define READ_TONE_CURVE_USER 0x01
277 #define READ_TONE_CURVE_CURR 0x02
278 
279 struct sinfonia_readtone_resp {
280 	struct sinfonia_status_hdr hdr;
281 	uint16_t total_size;
282 } __attribute__((packed));
283 
284 struct sinfonia_update_cmd {
285 	struct sinfonia_cmd_hdr hdr;
286 	uint8_t  target;
287 	uint8_t  curve_id;
288 	uint8_t  reset; // ??
289 	uint8_t  reserved[3];
290 	uint32_t size;
291 } __attribute__((packed));
292 
293 struct sinfonia_getserial_resp {
294 	struct sinfonia_status_hdr hdr;
295 	uint8_t  data[8];
296 } __attribute__((packed));
297 
298 struct sinfonia_getextcounter_resp {
299 	struct sinfonia_status_hdr hdr;
300 	uint32_t lifetime_distance;  /* Inches */
301 	uint32_t maint_distance;
302 	uint32_t head_distance;
303 	uint8_t  reserved[32];
304 } __attribute__((packed));
305 
306 struct sinfonia_seteeprom_cmd {
307 	struct sinfonia_cmd_hdr hdr;
308 	uint8_t data[256]; /* Maxlen */
309 } __attribute__((packed));
310 
311 struct sinfonia_printcmd10_hdr {
312 	struct sinfonia_cmd_hdr hdr;
313 	uint8_t  jobid;
314 	uint16_t copies;
315 	uint16_t columns;
316 	uint16_t rows;
317 	uint8_t  media;
318 	uint8_t  oc_mode;
319 	uint8_t  method;
320 } __attribute__((packed));
321 
322 struct sinfonia_printcmd18_hdr {
323 	struct sinfonia_cmd_hdr hdr;
324 	uint8_t  jobid;
325 	uint16_t copies;
326 	uint16_t columns;
327 	uint16_t rows;
328 	uint8_t  reserved[8]; // columns and rows repeated, then nulls
329 	uint8_t  oc_mode;
330 	uint8_t  method;
331 	uint8_t  media; // reserved?
332 } __attribute__((packed));
333 
334 struct sinfonia_printcmd28_hdr {
335 	struct sinfonia_cmd_hdr hdr;
336 	uint8_t  jobid;
337 	uint16_t copies;
338 	uint16_t columns;
339 	uint16_t rows;
340 	uint8_t  media;
341 	uint8_t  reserved[7];
342 	uint8_t  options;
343 	uint8_t  method;
344 	uint8_t  reserved2[11];
345 } __attribute__((packed));
346 
347 #define CODE_4x6     0x00
348 #define CODE_3_5x5   0x01
349 #define CODE_5x7     0x03
350 #define CODE_6x9     0x05
351 #define CODE_6x8     0x06
352 #define CODE_2x6     0x07
353 #define CODE_6x6     0x08
354 
355 #define CODE_8x10    0x10
356 #define CODE_8x12    0x11
357 #define CODE_8x4     0x20
358 #define CODE_8x5     0x21
359 #define CODE_8x6     0x22
360 #define CODE_8x8     0x23
361 #define CODE_8x4_2   0x30
362 #define CODE_8x5_2   0x31
363 #define CODE_8x6_2   0x32
364 #define CODE_8x4_3   0x40
365 
366 #define CODE_8x12K   0x02  /* Kodak 8810 */
367 
368 
369 #define CODE_89x60mm 0x10
370 #define CODE_89x59mm 0x11
371 #define CODE_89x58mm 0x12
372 #define CODE_89x57mm 0x13
373 #define CODE_89x56mm 0x14
374 #define CODE_89x55mm 0x15
375 
376 const char *sinfonia_print_codes (uint8_t v, int eightinch);
377 
378 #define STATUS_READY            0x00
379 #define STATUS_INIT_CPU         0x31
380 #define STATUS_INIT_RIBBON      0x32
381 #define STATUS_INIT_PAPER       0x33
382 #define STATUS_THERMAL_PROTECT  0x34
383 #define STATUS_USING_PANEL      0x35
384 #define STATUS_SELF_DIAG        0x36
385 #define STATUS_DOWNLOADING      0x37
386 
387 #define STATUS_FEEDING_PAPER    0x61
388 #define STATUS_PRE_HEAT         0x62
389 #define STATUS_PRINT_Y          0x63
390 #define STATUS_BACK_FEED_Y      0x64
391 #define STATUS_PRINT_M          0x65
392 #define STATUS_BACK_FEED_M      0x66
393 #define STATUS_PRINT_C          0x67
394 #define STATUS_BACK_FEED_C      0x68
395 #define STATUS_PRINT_OP         0x69
396 #define STATUS_PAPER_CUT        0x6A
397 #define STATUS_PAPER_EJECT      0x6B
398 #define STATUS_BACK_FEED_E      0x6C
399 #define STATUS_FINISHED         0x6D
400 
401 const char *sinfonia_status_str(uint8_t v);
402 
403 #define SINFONIA_CMD_GETSTATUS  0x0001
404 #define SINFONIA_CMD_MEDIAINFO  0x0002
405 #define SINFONIA_CMD_MODELNAME  0x0003 // 2145 only
406 #define SINFONIA_CMD_ERRORLOG   0x0004
407 #define SINFONIA_CMD_GETPARAM   0x0005 // !2145
408 #define SINFONIA_CMD_GETSERIAL  0x0006 // !2145
409 #define SINFONIA_CMD_PRINTSTAT  0x0007 // !2145
410 #define SINFONIA_CMD_EXTCOUNTER 0x0008 // !2145
411 
412 #define SINFONIA_CMD_MEMORYBANK 0x000A // Brava 21 only?
413 
414 #define SINFONIA_CMD_PRINTJOB   0x4001
415 #define SINFONIA_CMD_CANCELJOB  0x4002
416 #define SINFONIA_CMD_FLASHLED   0x4003
417 #define SINFONIA_CMD_RESET      0x4004
418 #define SINFONIA_CMD_READTONE   0x4005
419 #define SINFONIA_CMD_BUTTON     0x4006 // 2145 only
420 #define SINFONIA_CMD_SETPARAM   0x4007
421 
422 #define SINFONIA_CMD_GETUNIQUE  0x8003 // 2145 only
423 
424 #define SINFONIA_CMD_GETCORR    0x400D
425 #define SINFONIA_CMD_GETEEPROM  0x400E
426 #define SINFONIA_CMD_SETEEPROM  0x400F
427 #define SINFONIA_CMD_SETTIME    0x4011 // 6245 only
428 
429 #define SINFONIA_CMD_DIAGNOSTIC 0xC001 // ??
430 #define SINFONIA_CMD_FWINFO     0xC003
431 #define SINFONIA_CMD_UPDATE     0xC004
432 #define SINFONIA_CMD_SETUNIQUE  0xC007 // 2145 only
433 
434 const char *sinfonia_cmd_names(uint16_t v);
435 
436 //#define KODAK6_MEDIA_5R      // 189-9160
437 #define KODAK6_MEDIA_6R   0x0b // 197-4096  [ Also: 101-0867, 141-9597, 659-9054, 169-6418, DNP-900-060 ]
438 #define KODAK6_MEDIA_UNK  0x03 // ??? reported but unknown
439 #define KODAK6_MEDIA_6TR2 0x2c // 396-2941
440 //#define KODAK6_MEDIA_5FR2    // 6900-compatible
441 //#define KODAK6_MEDIA_6FR2    // 6900-compatible, 102-5925
442 #define KODAK6_MEDIA_NONE 0x00
443 //#define KODAK7_MEDIA_5R      // 164-9011 137-0600
444 #define KODAK7_MEDIA_6R   0x29 // 659-9047 166-1925 396-2966 846-2004 103-7688 DNP-900-070 -- ALSO FUJI R68-D2P570 16578944
445 //#define KODAK7_MEDIA_6TA2
446 //#define KODAK7_MEDIA_5TA2
447 
448 const char *kodak6_mediatypes(int type);
449 void kodak6_dumpmediacommon(int type);
450 
451 #define RESULT_SUCCESS 0x01
452 #define RESULT_FAIL    0x02
453 
454 /* ********** Below are for the old S1145 (EK68xx) and S1245 only! */
455 
456 enum {
457 	CMD_CODE_OK = 1,
458 	CMD_CODE_BAD = 2,
459 };
460 
461 enum {
462         STATUS_PRINTING = 1,
463         STATUS_IDLE = 2,
464 };
465 
466 enum {
467         STATE_STATUS1_STANDBY = 1,
468         STATE_STATUS1_ERROR = 2,
469         STATE_STATUS1_WAIT = 3,
470 };
471 
472 #define STATE_STANDBY_STATUS2 0x0
473 
474 enum {
475         WAIT_STATUS2_INIT = 0,
476         WAIT_STATUS2_RIBBON = 1,
477         WAIT_STATUS2_THERMAL = 2,
478         WAIT_STATUS2_OPERATING = 3,
479         WAIT_STATUS2_BUSY = 4,
480 };
481 
482 #define ERROR_STATUS2_CTRL_CIRCUIT   (0x80000000)
483 #define ERROR_STATUS2_MECHANISM_CTRL (0x40000000)
484 #define ERROR_STATUS2_SENSOR         (0x00002000)
485 #define ERROR_STATUS2_COVER_OPEN     (0x00001000)
486 #define ERROR_STATUS2_TEMP_SENSOR    (0x00000200)
487 #define ERROR_STATUS2_PAPER_JAM      (0x00000100)
488 #define ERROR_STATUS2_PAPER_EMPTY    (0x00000040)
489 #define ERROR_STATUS2_RIBBON_ERR     (0x00000010)
490 
491 enum {
492         CTRL_CIR_ERROR_EEPROM1  = 0x01,
493         CTRL_CIR_ERROR_EEPROM2  = 0x02,
494         CTRL_CIR_ERROR_DSP      = 0x04,
495         CTRL_CIR_ERROR_CRC_MAIN = 0x06,
496         CTRL_CIR_ERROR_DL_MAIN  = 0x07,
497         CTRL_CIR_ERROR_CRC_DSP  = 0x08,
498         CTRL_CIR_ERROR_DL_DSP   = 0x09,
499         CTRL_CIR_ERROR_ASIC     = 0x0a,
500         CTRL_CIR_ERROR_DRAM     = 0x0b,
501         CTRL_CIR_ERROR_DSPCOMM  = 0x29,
502 };
503 
504 enum {
505         MECH_ERROR_HEAD_UP            = 0x01,
506         MECH_ERROR_HEAD_DOWN          = 0x02,
507         MECH_ERROR_MAIN_PINCH_UP      = 0x03,
508         MECH_ERROR_MAIN_PINCH_DOWN    = 0x04,
509         MECH_ERROR_SUB_PINCH_UP       = 0x05,
510         MECH_ERROR_SUB_PINCH_DOWN     = 0x06,
511         MECH_ERROR_FEEDIN_PINCH_UP    = 0x07,
512         MECH_ERROR_FEEDIN_PINCH_DOWN  = 0x08,
513         MECH_ERROR_FEEDOUT_PINCH_UP   = 0x09,
514         MECH_ERROR_FEEDOUT_PINCH_DOWN = 0x0a,
515         MECH_ERROR_CUTTER_LR          = 0x0b,
516         MECH_ERROR_CUTTER_RL          = 0x0c,
517 };
518 
519 enum {
520         SENSOR_ERROR_CUTTER           = 0x05,
521         SENSOR_ERROR_HEAD_DOWN        = 0x09,
522         SENSOR_ERROR_HEAD_UP          = 0x0a,
523         SENSOR_ERROR_MAIN_PINCH_DOWN  = 0x0b,
524         SENSOR_ERROR_MAIN_PINCH_UP    = 0x0c,
525         SENSOR_ERROR_FEED_PINCH_DOWN  = 0x0d,
526         SENSOR_ERROR_FEED_PINCH_UP    = 0x0e,
527         SENSOR_ERROR_EXIT_PINCH_DOWN  = 0x0f,
528         SENSOR_ERROR_EXIT_PINCH_UP    = 0x10,
529         SENSOR_ERROR_LEFT_CUTTER      = 0x11,
530         SENSOR_ERROR_RIGHT_CUTTER     = 0x12,
531         SENSOR_ERROR_CENTER_CUTTER    = 0x13,
532         SENSOR_ERROR_UPPER_CUTTER     = 0x14,
533         SENSOR_ERROR_PAPER_FEED_COVER = 0x15,
534 };
535 
536 enum {
537         TEMP_SENSOR_ERROR_HEAD_HIGH = 0x01,
538         TEMP_SENSOR_ERROR_HEAD_LOW  = 0x02,
539         TEMP_SENSOR_ERROR_ENV_HIGH  = 0x03,
540         TEMP_SENSOR_ERROR_ENV_LOW   = 0x04,
541 };
542 
543 enum {
544         COVER_OPEN_ERROR_UPPER = 0x01,
545         COVER_OPEN_ERROR_LOWER = 0x02,
546 };
547 
548 enum {
549         PAPER_EMPTY_ERROR = 0x00,
550 };
551 
552 enum {
553         RIBBON_ERROR = 0x00,
554 };
555 
556 enum {
557         CURVE_TABLE_STATUS_INITIAL = 0x00,
558         CURVE_TABLE_STATUS_USERSET = 0x01,
559         CURVE_TABLE_STATUS_CURRENT = 0x02,
560 };
561 
562 const char *sinfonia_1x45_status_str(uint8_t status1, uint32_t status2, uint8_t error);
563