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 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <signal.h>
39
40 #include "backend_common.h"
41 #include "backend_sinfonia.h"
42
sinfonia_read_parse(int data_fd,uint32_t model,struct sinfonia_printjob * job)43 int sinfonia_read_parse(int data_fd, uint32_t model,
44 struct sinfonia_printjob *job)
45 {
46 uint32_t hdr[29];
47 int ret, i;
48 uint8_t tmpbuf[4];
49
50 /* Read in header */
51 ret = read(data_fd, hdr, SINFONIA_HDR_LEN);
52 if (ret < 0 || ret != SINFONIA_HDR_LEN) {
53 if (ret == 0)
54 return CUPS_BACKEND_CANCEL;
55 ERROR("Read failed (%d/%d)\n",
56 ret, SINFONIA_HDR_LEN);
57 perror("ERROR: Read failed");
58 return ret;
59 }
60
61 /* Byteswap everything */
62 for (i = 0 ; i < (SINFONIA_HDR_LEN / 4) ; i++) {
63 hdr[i] = le32_to_cpu(hdr[i]);
64 }
65
66 /* Sanity-check headers */
67 if (hdr[0] != SINFONIA_HDR1_LEN ||
68 hdr[4] != SINFONIA_HDR2_LEN ||
69 hdr[22] != SINFONIA_DPI) {
70 ERROR("Unrecognized header data format!\n");
71 return CUPS_BACKEND_CANCEL;
72 }
73 if (hdr[1] != model) {
74 ERROR("job/printer mismatch (%u/%u)!\n", hdr[1], model);
75 return CUPS_BACKEND_CANCEL;
76 }
77
78 if (!hdr[13] || !hdr[14]) {
79 ERROR("Bad job cols/rows!\n");
80 return CUPS_BACKEND_CANCEL;
81 }
82
83 /* Work out data length */
84 job->datalen = hdr[13] * hdr[14] * 3;
85 job->databuf = malloc(job->datalen);
86 if (!job->databuf) {
87 ERROR("Memory allocation failure!\n");
88 return CUPS_BACKEND_RETRY_CURRENT;
89 }
90
91 /* Read in payload data */
92 {
93 uint32_t remain = job->datalen;
94 uint8_t *ptr = job->databuf;
95 do {
96 ret = read(data_fd, ptr, remain);
97 if (ret < 0) {
98 ERROR("Read failed (%d/%u/%d)\n",
99 ret, remain, job->datalen);
100 perror("ERROR: Read failed");
101 free(job->databuf);
102 job->databuf = NULL;
103 return ret;
104 }
105 ptr += ret;
106 remain -= ret;
107 } while (remain);
108 }
109
110 /* Make sure footer is sane too */
111 ret = read(data_fd, tmpbuf, 4);
112 if (ret != 4) {
113 ERROR("Read failed (%d/%d)\n", ret, 4);
114 perror("ERROR: Read failed");
115 free(job->databuf);
116 job->databuf = NULL;
117 return ret;
118 }
119 if (tmpbuf[0] != 0x04 ||
120 tmpbuf[1] != 0x03 ||
121 tmpbuf[2] != 0x02 ||
122 tmpbuf[3] != 0x01) {
123 ERROR("Unrecognized footer data format!\n");
124 free (job->databuf);
125 job->databuf = NULL;
126 return CUPS_BACKEND_CANCEL;
127 }
128
129 /* Fill out job params */
130 job->jp.media = hdr[6];
131 if (hdr[1] != 6245)
132 job->jp.method = hdr[8];
133 if (hdr[1] == 2245 || hdr[1] == 6245)
134 job->jp.quality = hdr[9];
135 if (hdr[1] == 1245 || hdr[1] == 2145)
136 job->jp.oc_mode = hdr[9];
137 else
138 job->jp.oc_mode = hdr[10];
139 if (hdr[1] == 1245)
140 job->jp.mattedepth = hdr[11];
141 if (hdr[1] == 1245)
142 job->jp.dust = hdr[12];
143 job->jp.columns = hdr[13];
144 job->jp.rows = hdr[14];
145 job->jp.copies = hdr[15];
146
147 if (hdr[1] == 2245 || hdr[1] == 6145)
148 job->jp.ext_flags = hdr[28];
149
150 return CUPS_BACKEND_OK;
151 }
152
sinfonia_raw10_read_parse(int data_fd,struct sinfonia_printjob * job)153 int sinfonia_raw10_read_parse(int data_fd, struct sinfonia_printjob *job)
154 {
155 struct sinfonia_printcmd10_hdr hdr;
156 int ret;
157
158 /* Read in header */
159 ret = read(data_fd, &hdr, sizeof(hdr));
160 if (ret < 0 || ret != sizeof(hdr)) {
161 if (ret == 0)
162 return CUPS_BACKEND_CANCEL;
163 ERROR("Read failed (%d/%d/%d)\n",
164 ret, 0, (int)sizeof(hdr));
165 perror("ERROR: Read failed");
166 return CUPS_BACKEND_CANCEL;
167 }
168 /* Validate header */
169 if (le16_to_cpu(hdr.hdr.cmd) != 0x4001 ||
170 le16_to_cpu(hdr.hdr.len) != 10) {
171 ERROR("Unrecognized data format!\n");
172 return CUPS_BACKEND_CANCEL;
173 }
174 job->jp.copies = le16_to_cpu(hdr.copies);
175 job->jp.rows = le16_to_cpu(hdr.rows);
176 job->jp.columns = le16_to_cpu(hdr.columns);
177 job->jp.media = hdr.media;
178 job->jp.oc_mode = hdr.oc_mode;
179 job->jp.method = hdr.method;
180
181 /* Allocate buffer */
182 job->datalen = job->jp.rows * job->jp.columns * 3;
183 job->databuf = malloc(job->datalen);
184 if (!job->databuf) {
185 ERROR("Memory allocation failure!\n");
186 return CUPS_BACKEND_RETRY_CURRENT;
187 }
188
189 {
190 int remain = job->datalen;
191 uint8_t *ptr = job->databuf;
192 do {
193 ret = read(data_fd, ptr, remain);
194 if (ret < 0) {
195 ERROR("Read failed (%d/%d/%d)\n",
196 ret, remain, job->datalen);
197 perror("ERROR: Read failed");
198 return CUPS_BACKEND_CANCEL;
199 }
200 ptr += ret;
201 remain -= ret;
202 } while (remain);
203 }
204
205 return CUPS_BACKEND_OK;
206 }
207
sinfonia_raw18_read_parse(int data_fd,struct sinfonia_printjob * job)208 int sinfonia_raw18_read_parse(int data_fd, struct sinfonia_printjob *job)
209 {
210 struct sinfonia_printcmd18_hdr hdr;
211 int ret;
212
213 /* Read in header */
214 ret = read(data_fd, &hdr, sizeof(hdr));
215 if (ret < 0 || ret != sizeof(hdr)) {
216 if (ret == 0)
217 return CUPS_BACKEND_CANCEL;
218 ERROR("Read failed (%d/%d/%d)\n",
219 ret, 0, (int)sizeof(hdr));
220 perror("ERROR: Read failed");
221 return CUPS_BACKEND_CANCEL;
222 }
223 /* Validate header */
224 if (le16_to_cpu(hdr.hdr.cmd) != SINFONIA_CMD_PRINTJOB ||
225 le16_to_cpu(hdr.hdr.len) != 18) {
226 ERROR("Unrecognized data format!\n");
227 return CUPS_BACKEND_CANCEL;
228 }
229 job->jp.copies = le16_to_cpu(hdr.copies);
230 job->jp.rows = le16_to_cpu(hdr.rows);
231 job->jp.columns = le16_to_cpu(hdr.columns);
232 job->jp.media = hdr.media;
233 job->jp.oc_mode = hdr.oc_mode;
234 job->jp.method = hdr.method;
235
236 /* Allocate buffer */
237 job->datalen = job->jp.rows * job->jp.columns * 3;
238 job->databuf = malloc(job->datalen);
239 if (!job->databuf) {
240 ERROR("Memory allocation failure!\n");
241 return CUPS_BACKEND_RETRY_CURRENT;
242 }
243
244 {
245 int remain = job->datalen;
246 uint8_t *ptr = job->databuf;
247 do {
248 ret = read(data_fd, ptr, remain);
249 if (ret < 0) {
250 ERROR("Read failed (%d/%d/%d)\n",
251 ret, remain, job->datalen);
252 perror("ERROR: Read failed");
253 return CUPS_BACKEND_CANCEL;
254 }
255 ptr += ret;
256 remain -= ret;
257 } while (remain);
258 }
259
260 return CUPS_BACKEND_OK;
261 }
262
sinfonia_raw28_read_parse(int data_fd,struct sinfonia_printjob * job)263 int sinfonia_raw28_read_parse(int data_fd, struct sinfonia_printjob *job)
264 {
265 struct sinfonia_printcmd28_hdr hdr;
266 int ret;
267
268 /* Read in header */
269 ret = read(data_fd, &hdr, sizeof(hdr));
270 if (ret < 0 || ret != sizeof(hdr)) {
271 if (ret == 0)
272 return CUPS_BACKEND_CANCEL;
273 ERROR("Read failed (%d/%d/%d)\n",
274 ret, 0, (int)sizeof(hdr));
275 perror("ERROR: Read failed");
276 return CUPS_BACKEND_CANCEL;
277 }
278 /* Validate header */
279 if (le16_to_cpu(hdr.hdr.cmd) != SINFONIA_CMD_PRINTJOB ||
280 le16_to_cpu(hdr.hdr.len) != 28) {
281 ERROR("Unrecognized data format!\n");
282 return CUPS_BACKEND_CANCEL;
283 }
284 job->jp.copies = le16_to_cpu(hdr.copies);
285 job->jp.rows = le16_to_cpu(hdr.rows);
286 job->jp.columns = le16_to_cpu(hdr.columns);
287 job->jp.media = hdr.media;
288 job->jp.oc_mode = hdr.options & 0x03;
289 job->jp.quality = hdr.options & 0x08;
290 job->jp.method = hdr.method;
291
292 /* Allocate buffer */
293 job->datalen = job->jp.rows * job->jp.columns * 3;
294 job->databuf = malloc(job->datalen);
295 if (!job->databuf) {
296 ERROR("Memory allocation failure!\n");
297 return CUPS_BACKEND_RETRY_CURRENT;
298 }
299
300 {
301 int remain = job->datalen;
302 uint8_t *ptr = job->databuf;
303 do {
304 ret = read(data_fd, ptr, remain);
305 if (ret < 0) {
306 ERROR("Read failed (%d/%d/%d)\n",
307 ret, remain, job->datalen);
308 perror("ERROR: Read failed");
309 return CUPS_BACKEND_CANCEL;
310 }
311 ptr += ret;
312 remain -= ret;
313 } while (remain);
314 }
315
316 return CUPS_BACKEND_OK;
317 }
318
sinfonia_cleanup_job(const void * vjob)319 void sinfonia_cleanup_job(const void *vjob)
320 {
321 const struct sinfonia_printjob *job = vjob;
322
323 if (job->databuf)
324 free(job->databuf);
325
326 free((void*)job);
327 }
328
sinfonia_docmd(struct sinfonia_usbdev * usbh,uint8_t * cmd,int cmdlen,uint8_t * resp,int resplen,int * num)329 int sinfonia_docmd(struct sinfonia_usbdev *usbh,
330 uint8_t *cmd, int cmdlen,
331 uint8_t *resp, int resplen,
332 int *num)
333 {
334 libusb_device_handle *dev = usbh->dev;
335 uint8_t endp_up = usbh->endp_up;
336 uint8_t endp_down = usbh->endp_down;
337 int ret;
338
339 struct sinfonia_cmd_hdr *cmdhdr = (struct sinfonia_cmd_hdr *) cmd;
340 struct sinfonia_status_hdr *resphdr = (struct sinfonia_status_hdr *)resp;
341
342 if ((ret = send_data(dev, endp_down,
343 cmd, cmdlen))) {
344 goto fail;
345 }
346
347 ret = read_data(dev, endp_up,
348 (uint8_t *)resp, resplen, num);
349
350 if (ret < 0)
351 goto fail;
352
353 if (resphdr->result != RESULT_SUCCESS) {
354 INFO("Printer Status: %02x (%s)\n", resphdr->status,
355 sinfonia_status_str(resphdr->status));
356 INFO(" Result: 0x%02x Error: 0x%02x (0x%02x/0x%02x = %s)\n",
357 resphdr->result, resphdr->error, resphdr->printer_major,
358 resphdr->printer_minor, usbh->error_codes(resphdr->printer_major, resphdr->printer_minor));
359 goto fail;
360 }
361
362 return 0;
363 fail:
364 ERROR("Failed to execute %s command\n", sinfonia_cmd_names(cmdhdr->cmd));
365 return ret;
366 }
367
sinfonia_flashled(struct sinfonia_usbdev * usbh)368 int sinfonia_flashled(struct sinfonia_usbdev *usbh)
369 {
370 struct sinfonia_cmd_hdr cmd;
371 struct sinfonia_status_hdr resp;
372 int ret, num = 0;
373
374 cmd.cmd = cpu_to_le16(SINFONIA_CMD_FLASHLED);
375 cmd.len = cpu_to_le16(0);
376
377 if ((ret = sinfonia_docmd(usbh,
378 (uint8_t*)&cmd, sizeof(cmd),
379 (uint8_t*)&resp, sizeof(resp),
380 &num)) < 0) {
381 return ret;
382 }
383
384 return 0;
385 }
386
sinfonia_canceljob(struct sinfonia_usbdev * usbh,int id)387 int sinfonia_canceljob(struct sinfonia_usbdev *usbh, int id)
388 {
389 struct sinfonia_cancel_cmd cmd;
390 struct sinfonia_status_hdr resp;
391 int ret, num = 0;
392
393 cmd.id = id;
394
395 cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_CANCELJOB);
396 cmd.hdr.len = cpu_to_le16(1);
397
398 if ((ret = sinfonia_docmd(usbh,
399 (uint8_t*)&cmd, sizeof(cmd),
400 (uint8_t*)&resp, sizeof(resp),
401 &num)) < 0) {
402 return ret;
403 }
404
405 return 0;
406 }
407
sinfonia_getparam(struct sinfonia_usbdev * usbh,int target,uint32_t * param)408 int sinfonia_getparam(struct sinfonia_usbdev *usbh, int target, uint32_t *param)
409 {
410 struct sinfonia_getparam_cmd cmd;
411 struct sinfonia_getparam_resp resp;
412 int ret, num = 0;
413
414 /* Set up command */
415 cmd.target = target;
416
417 cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_GETPARAM);
418 cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_getparam_cmd)-sizeof(cmd.hdr));
419
420 if ((ret = sinfonia_docmd(usbh,
421 (uint8_t*)&cmd, sizeof(cmd),
422 (uint8_t*)&resp, sizeof(resp),
423 &num)) < 0) {
424 }
425 *param = le32_to_cpu(resp.param);
426
427 return ret;
428 }
429
sinfonia_setparam(struct sinfonia_usbdev * usbh,int target,uint32_t param)430 int sinfonia_setparam(struct sinfonia_usbdev *usbh, int target, uint32_t param)
431 {
432 struct sinfonia_setparam_cmd cmd;
433 struct sinfonia_status_hdr resp;
434 int ret, num = 0;
435
436 /* Set up command */
437 cmd.target = target;
438 cmd.param = cpu_to_le32(param);
439
440 cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_SETPARAM);
441 cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_setparam_cmd)-sizeof(cmd.hdr));
442
443 if ((ret = sinfonia_docmd(usbh,
444 (uint8_t*)&cmd, sizeof(cmd),
445 (uint8_t*)&resp, sizeof(resp),
446 &num)) < 0) {
447 }
448
449 return ret;
450 }
451
sinfonia_getfwinfo(struct sinfonia_usbdev * usbh)452 int sinfonia_getfwinfo(struct sinfonia_usbdev *usbh)
453 {
454 struct sinfonia_fwinfo_cmd cmd;
455 struct sinfonia_fwinfo_resp resp;
456 int num = 0;
457 int i;
458
459 cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_FWINFO);
460 cmd.hdr.len = cpu_to_le16(1);
461
462 resp.hdr.payload_len = 0;
463
464 INFO("FW Information:\n");
465
466 for (i = FWINFO_TARGET_MAIN_BOOT ; i <= FWINFO_TARGET_PRINT_TABLES2 ; i++) {
467 int ret;
468 cmd.target = i;
469
470 if ((ret = sinfonia_docmd(usbh,
471 (uint8_t*)&cmd, sizeof(cmd),
472 (uint8_t*)&resp, sizeof(resp),
473 &num)) < 0) {
474 continue;
475 }
476
477 if (resp.major == 0)
478 continue;
479
480 if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_fwinfo_resp) - sizeof(struct sinfonia_status_hdr)))
481 continue;
482
483 INFO(" %s\t ver %02x.%02x\n", sinfonia_fwinfo_targets(i),
484 resp.major, resp.minor);
485 #if 0
486 INFO(" name: '%s'\n", resp.name);
487 INFO(" type: '%s'\n", resp.type);
488 INFO(" date: '%s'\n", resp.date);
489 INFO(" version: %02x.%02x (CRC %04x)\n", resp.major, resp.minor,
490 le16_to_cpu(resp.checksum));
491 #endif
492 }
493 return 0;
494 }
495
sinfonia_geterrorlog(struct sinfonia_usbdev * usbh)496 int sinfonia_geterrorlog(struct sinfonia_usbdev *usbh)
497 {
498 struct sinfonia_cmd_hdr cmd;
499 struct sinfonia_errorlog_resp resp;
500 int ret, num = 0;
501 int i;
502
503 cmd.cmd = cpu_to_le16(SINFONIA_CMD_ERRORLOG);
504 cmd.len = cpu_to_le16(0);
505
506 resp.hdr.payload_len = 0;
507
508 if ((ret = sinfonia_docmd(usbh,
509 (uint8_t*)&cmd, sizeof(cmd),
510 (uint8_t*)&resp, sizeof(resp),
511 &num)) < 0) {
512 return ret;
513 }
514
515 if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_errorlog_resp) - sizeof(struct sinfonia_status_hdr)))
516 return -2;
517
518 INFO("Stored Error Events: %u entries:\n", resp.count);
519 for (i = 0 ; i < resp.count ; i++) {
520 INFO(" %02d: @ %08u prints : 0x%02x/0x%02x (%s)\n", i,
521 le32_to_cpu(resp.items[i].print_counter),
522 resp.items[i].major, resp.items[i].minor,
523 usbh->error_codes(resp.items[i].major, resp.items[i].minor));
524 }
525 return 0;
526 }
527
sinfonia_resetcurve(struct sinfonia_usbdev * usbh,int target,int id)528 int sinfonia_resetcurve(struct sinfonia_usbdev *usbh, int target, int id)
529 {
530 struct sinfonia_reset_cmd cmd;
531 struct sinfonia_status_hdr resp;
532 int ret, num = 0;
533
534 cmd.target = target;
535 cmd.curveid = id;
536 cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_RESET);
537 cmd.hdr.len = cpu_to_le16(2);
538
539 if ((ret = sinfonia_docmd(usbh,
540 (uint8_t*)&cmd, sizeof(cmd),
541 (uint8_t*)&resp, sizeof(resp),
542 &num)) < 0) {
543 return ret;
544 }
545
546 return 0;
547 }
548
sinfonia_gettonecurve(struct sinfonia_usbdev * usbh,int type,char * fname)549 int sinfonia_gettonecurve(struct sinfonia_usbdev *usbh, int type, char *fname)
550 {
551 struct sinfonia_readtone_cmd cmd;
552 struct sinfonia_readtone_resp resp;
553 int ret, num = 0;
554
555 uint8_t *data;
556 uint16_t curves[TONE_CURVE_SIZE] = { 0 };
557
558 int i,j;
559
560 cmd.target = type;
561 cmd.curveid = TONE_CURVE_ID;
562
563 cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_READTONE);
564 cmd.hdr.len = cpu_to_le16(1);
565
566 resp.hdr.payload_len = 0;
567
568 INFO("Dump %s Tone Curve to '%s'\n", sinfonia_tonecurve_statuses(type), fname);
569
570 if ((ret = sinfonia_docmd(usbh,
571 (uint8_t*)&cmd, sizeof(cmd),
572 (uint8_t*)&resp, sizeof(resp),
573 &num)) < 0) {
574 return ret;
575 }
576
577 if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_readtone_resp) - sizeof(struct sinfonia_status_hdr)))
578 return -2;
579
580 resp.total_size = le16_to_cpu(resp.total_size);
581
582 data = malloc(resp.total_size * 2);
583 if (!data) {
584 ERROR("Memory Allocation Failure!\n");
585 return -1;
586 }
587
588 i = 0;
589 while (i < resp.total_size) {
590 ret = read_data(usbh->dev, usbh->endp_up,
591 data + i,
592 resp.total_size * 2 - i,
593 &num);
594 if (ret < 0)
595 goto done;
596 i += num;
597 }
598
599 i = j = 0;
600 while (i < resp.total_size) {
601 memcpy(curves + j, data + i+2, data[i+1]);
602 j += data[i+1] / 2;
603 i += data[i+1] + 2;
604 }
605
606 /* Open file and write it out */
607 {
608 int tc_fd = open(fname, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
609 if (tc_fd < 0) {
610 ret = -1;
611 goto done;
612 }
613
614 for (i = 0 ; i < TONE_CURVE_SIZE; i++) {
615 /* Byteswap appropriately */
616 curves[i] = cpu_to_be16(le16_to_cpu(curves[i]));
617 }
618 ret = write(tc_fd, curves, TONE_CURVE_SIZE * sizeof(uint16_t));
619 close(tc_fd);
620 }
621
622 done:
623 free(data);
624 return ret;
625 }
626
sinfonia_settonecurve(struct sinfonia_usbdev * usbh,int target,char * fname)627 int sinfonia_settonecurve(struct sinfonia_usbdev *usbh, int target, char *fname)
628 {
629 struct sinfonia_update_cmd cmd;
630 struct sinfonia_status_hdr resp;
631 int ret, num = 0;
632
633 INFO("Set %s Tone Curve from '%s'\n", sinfonia_update_targets(target), fname);
634
635 uint16_t *data = malloc(TONE_CURVE_SIZE * sizeof(uint16_t));
636 if (!data) {
637 ERROR("Memory Allocation Failure!\n");
638 return -1;
639 }
640
641 /* Read in file */
642 if ((ret = dyesub_read_file(fname, data, TONE_CURVE_SIZE * sizeof(uint16_t), NULL))) {
643 ERROR("Failed to read Tone Curve file\n");
644 goto done;
645 }
646
647 /* Byteswap data to local CPU.. */
648 for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
649 data[ret] = be16_to_cpu(data[ret]);
650 }
651
652 /* Set up command */
653 cmd.target = target;
654 cmd.curve_id = TONE_CURVE_ID;
655 cmd.reserved[0] = cmd.reserved[1] = cmd.reserved[2] = 0;
656 cmd.reset = 0;
657 cmd.size = cpu_to_le32(TONE_CURVE_SIZE * sizeof(uint16_t));
658
659 cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_UPDATE);
660 cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_update_cmd)-sizeof(cmd.hdr));
661
662 /* Byteswap data to format printer is expecting.. */
663 for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
664 data[ret] = cpu_to_le16(data[ret]);
665 }
666
667 if ((ret = sinfonia_docmd(usbh,
668 (uint8_t*)&cmd, sizeof(cmd),
669 (uint8_t*)&resp, sizeof(resp),
670 &num)) < 0) {
671 return ret;
672 }
673
674 /* Sent transfer */
675 if ((ret = send_data(usbh->dev, usbh->endp_down,
676 (uint8_t *) data, TONE_CURVE_SIZE * sizeof(uint16_t)))) {
677 goto done;
678 }
679
680 done:
681 free(data);
682
683 return ret;
684 }
685
sinfonia_update_targets(uint8_t v)686 const char *sinfonia_update_targets (uint8_t v) {
687 switch (v) {
688 case UPDATE_TARGET_USER:
689 return "User";
690 case UPDATE_TARGET_CURRENT:
691 return "Current";
692 default:
693 return "Unknown";
694 }
695 }
696
sinfonia_tonecurve_statuses(uint8_t v)697 const char *sinfonia_tonecurve_statuses (uint8_t v)
698 {
699 switch(v) {
700 case 0:
701 return "Initial";
702 case 1:
703 return "UserSet";
704 case 2:
705 return "Current";
706 default:
707 return "Unknown";
708 }
709 }
710
sinfonia_bank_statuses(uint8_t v)711 const char *sinfonia_bank_statuses(uint8_t v)
712 {
713 switch (v) {
714 case BANK_STATUS_FREE:
715 return "Free";
716 case BANK_STATUS_XFER:
717 return "Xfer";
718 case BANK_STATUS_FULL:
719 return "Full";
720 case BANK_STATUS_PRINTING:
721 return "Printing";
722 default:
723 return "Unknown";
724 }
725 }
726
sinfonia_error_str(uint8_t v)727 const char *sinfonia_error_str(uint8_t v) {
728 switch (v) {
729 case ERROR_NONE:
730 return "None";
731 case ERROR_INVALID_PARAM:
732 return "Invalid Command Parameter";
733 case ERROR_MAIN_APP_INACTIVE:
734 return "Main App Inactive";
735 case ERROR_COMMS_TIMEOUT:
736 return "Main Communication Timeout";
737 case ERROR_MAINT_NEEDED:
738 return "Maintenance Needed";
739 case ERROR_BAD_COMMAND:
740 return "Inappropriate Command";
741 case ERROR_PRINTER:
742 return "Printer Error";
743 case ERROR_BUFFER_FULL:
744 return "Buffer Full";
745 default:
746 return "Unknown";
747 }
748 }
749
sinfonia_media_types(uint8_t v)750 const char *sinfonia_media_types(uint8_t v) {
751 switch (v) {
752 case MEDIA_TYPE_UNKNOWN:
753 return "Unknown";
754 case MEDIA_TYPE_PAPER:
755 return "Paper";
756 default:
757 return "Unknown";
758 }
759 }
760
sinfonia_print_methods(uint8_t v)761 const char *sinfonia_print_methods (uint8_t v) {
762 switch (v & 0xf) {
763 case PRINT_METHOD_STD:
764 return "Standard";
765 case PRINT_METHOD_COMBO_2:
766 return "2up";
767 case PRINT_METHOD_COMBO_3:
768 return "3up";
769 case PRINT_METHOD_SPLIT:
770 return "Split";
771 case PRINT_METHOD_DOUBLE:
772 return "Double";
773 default:
774 return "Unknown";
775 }
776 }
777
sinfonia_print_modes(uint8_t v)778 const char *sinfonia_print_modes(uint8_t v) {
779 switch (v) {
780 case PRINT_MODE_NO_OC:
781 return "No Overcoat";
782 case PRINT_MODE_GLOSSY:
783 return "Glossy";
784 case PRINT_MODE_MATTE:
785 return "Matte";
786 default:
787 return "Unknown";
788 }
789 }
790
sinfonia_fwinfo_targets(uint8_t v)791 const char *sinfonia_fwinfo_targets (uint8_t v) {
792 switch (v) {
793 case FWINFO_TARGET_MAIN_BOOT:
794 return "Main Boot ";
795 case FWINFO_TARGET_MAIN_APP:
796 return "Main App ";
797 case FWINFO_TARGET_PRINT_TABLES:
798 case FWINFO_TARGET_PRINT_TABLES2: // Seen on EK70xx
799 return "Print Tables";
800 case FWINFO_TARGET_DSP:
801 return "DSP ";
802 case FWINFO_TARGET_USB:
803 return "USB ";
804 default:
805 return "Unknown ";
806 }
807 }
808
sinfonia_print_codes(uint8_t v,int eightinch)809 const char *sinfonia_print_codes (uint8_t v, int eightinch) {
810 if (eightinch) {
811 switch (v) {
812 case CODE_8x10:
813 return "8x10";
814 case CODE_8x12:
815 case CODE_8x12K:
816 return "8x12";
817 case CODE_8x4:
818 return "8x4";
819 case CODE_8x5:
820 return "8x5";
821 case CODE_8x6:
822 return "8x6";
823 case CODE_8x8:
824 return "8x8";
825 case CODE_8x4_2:
826 return "8x4*2";
827 case CODE_8x5_2:
828 return "8x5*2";
829 case CODE_8x6_2:
830 return "8x6*2";
831 case CODE_8x4_3:
832 return "8x4*3";
833 default:
834 return "Unknown";
835 }
836 }
837
838 switch (v) {
839 case CODE_4x6:
840 return "4x6";
841 case CODE_3_5x5:
842 return "3.5x5";
843 case CODE_5x7:
844 return "5x7";
845 case CODE_6x9:
846 return "6x9";
847 case CODE_6x8:
848 return "6x8";
849 case CODE_2x6:
850 return "2x6";
851 case CODE_6x6:
852 return "6x6";
853 case CODE_89x60mm:
854 return "89x60mm";
855 case CODE_89x59mm:
856 return "89x59mm";
857 case CODE_89x58mm:
858 return "89x58mm";
859 case CODE_89x57mm:
860 return "89x57mm";
861 case CODE_89x56mm:
862 return "89x56mm";
863 case CODE_89x55mm:
864 return "89x55mm";
865 default:
866 return "Unknown";
867 }
868 }
869
sinfonia_status_str(uint8_t v)870 const char *sinfonia_status_str(uint8_t v) {
871 switch (v) {
872 case STATUS_READY:
873 return "Ready";
874 case STATUS_INIT_CPU:
875 return "Initializing CPU";
876 case STATUS_INIT_RIBBON:
877 return "Initializing Ribbon";
878 case STATUS_INIT_PAPER:
879 return "Loading Paper";
880 case STATUS_THERMAL_PROTECT:
881 return "Thermal Protection";
882 case STATUS_USING_PANEL:
883 return "Using Operation Panel";
884 case STATUS_SELF_DIAG:
885 return "Processing Self Diagnosis";
886 case STATUS_DOWNLOADING:
887 return "Processing Download";
888 case STATUS_FEEDING_PAPER:
889 return "Feeding Paper";
890 case STATUS_PRE_HEAT:
891 return "Pre-Heating";
892 case STATUS_PRINT_Y:
893 return "Printing Yellow";
894 case STATUS_BACK_FEED_Y:
895 return "Back-Feeding - Yellow Complete";
896 case STATUS_PRINT_M:
897 return "Printing Magenta";
898 case STATUS_BACK_FEED_M:
899 return "Back-Feeding - Magenta Complete";
900 case STATUS_PRINT_C:
901 return "Printing Cyan";
902 case STATUS_BACK_FEED_C:
903 return "Back-Feeding - Cyan Complete";
904 case STATUS_PRINT_OP:
905 return "Laminating";
906 case STATUS_PAPER_CUT:
907 return "Cutting Paper";
908 case STATUS_PAPER_EJECT:
909 return "Ejecting Paper";
910 case STATUS_BACK_FEED_E:
911 return "Back-Feeding - Ejected";
912 case STATUS_FINISHED:
913 return "Print Finished";
914 case ERROR_PRINTER:
915 return "Printer Error";
916 default:
917 return "Unknown";
918 }
919 }
920
sinfonia_cmd_names(uint16_t v)921 const char *sinfonia_cmd_names(uint16_t v) {
922 switch (le16_to_cpu(v)) {
923 case SINFONIA_CMD_GETSTATUS:
924 return "Get Status";
925 case SINFONIA_CMD_MEDIAINFO:
926 return "Get Media Info";
927 case SINFONIA_CMD_MODELNAME:
928 return "Get Model Name";
929 case SINFONIA_CMD_ERRORLOG:
930 return "Get Error Log";
931 case SINFONIA_CMD_GETPARAM:
932 return "Get Parameter";
933 case SINFONIA_CMD_GETSERIAL:
934 return "Get Serial Number";
935 case SINFONIA_CMD_PRINTSTAT:
936 return "Get Print ID Status";
937 case SINFONIA_CMD_EXTCOUNTER:
938 return "Get Extended Counters";
939 case SINFONIA_CMD_PRINTJOB:
940 return "Print";
941 case SINFONIA_CMD_CANCELJOB:
942 return "Cancel Print";
943 case SINFONIA_CMD_FLASHLED:
944 return "Flash LEDs";
945 case SINFONIA_CMD_RESET:
946 return "Reset";
947 case SINFONIA_CMD_READTONE:
948 return "Read Tone Curve";
949 case SINFONIA_CMD_BUTTON:
950 return "Button Enable";
951 case SINFONIA_CMD_SETPARAM:
952 return "Set Parameter";
953 case SINFONIA_CMD_GETUNIQUE:
954 return "Get Unique String";
955 case SINFONIA_CMD_GETCORR:
956 return "Get Image Correction Parameter";
957 case SINFONIA_CMD_GETEEPROM:
958 return "Get EEPROM Backup Parameter";
959 case SINFONIA_CMD_SETEEPROM:
960 return "Set EEPROM Backup Parameter";
961 case SINFONIA_CMD_SETTIME:
962 return "Time Setting";
963 case SINFONIA_CMD_DIAGNOSTIC:
964 return "Diagnostic";
965 case SINFONIA_CMD_FWINFO:
966 return "Get Firmware Info";
967 case SINFONIA_CMD_UPDATE:
968 return "Update";
969 case SINFONIA_CMD_SETUNIQUE:
970 return "Set Unique String";
971 default:
972 return "Unknown Command";
973 }
974 }
975
kodak6_mediatypes(int type)976 const char *kodak6_mediatypes(int type)
977 {
978 switch(type) {
979 case KODAK6_MEDIA_NONE:
980 return "No media";
981 case KODAK6_MEDIA_6R:
982 case KODAK6_MEDIA_6TR2:
983 case KODAK7_MEDIA_6R:
984 return "Kodak 6R";
985
986 default:
987 return "Unknown";
988 }
989 return "Unknown";
990 }
991
kodak6_dumpmediacommon(int type)992 void kodak6_dumpmediacommon(int type)
993 {
994 switch (type) {
995 case KODAK6_MEDIA_6R:
996 INFO("Media type: 6R (Kodak 197-4096 or equivalent)\n");
997 break;
998 case KODAK6_MEDIA_6TR2:
999 INFO("Media type: 6R (Kodak 396-2941 or equivalent)\n");
1000 break;
1001 case KODAK7_MEDIA_6R:
1002 INFO("Media type: 6R (Kodak 659-9047 or equivalent)\n");
1003 break;
1004 default:
1005 INFO("Media type %02x (unknown, please report!)\n", type);
1006 break;
1007 }
1008 }
1009
1010 /* Below are for S1145 (EK68xx) and S1245 only! */
sinfonia_1x45_status_str(uint8_t status1,uint32_t status2,uint8_t error)1011 const char *sinfonia_1x45_status_str(uint8_t status1, uint32_t status2, uint8_t error)
1012 {
1013 switch(status1) {
1014 case STATE_STATUS1_STANDBY:
1015 return "Standby (Ready)";
1016 case STATE_STATUS1_WAIT:
1017 switch (status2) {
1018 case WAIT_STATUS2_INIT:
1019 return "Wait (Initializing)";
1020 case WAIT_STATUS2_RIBBON:
1021 return "Wait (Ribbon Winding)";
1022 case WAIT_STATUS2_THERMAL:
1023 return "Wait (Thermal Protection)";
1024 case WAIT_STATUS2_OPERATING:
1025 return "Wait (Operating)";
1026 case WAIT_STATUS2_BUSY:
1027 return "Wait (Busy)";
1028 default:
1029 return "Wait (Unknown)";
1030 }
1031 case STATE_STATUS1_ERROR:
1032 switch (status2) {
1033 case ERROR_STATUS2_CTRL_CIRCUIT:
1034 switch (error) {
1035 case CTRL_CIR_ERROR_EEPROM1:
1036 return "Error (EEPROM1)";
1037 case CTRL_CIR_ERROR_EEPROM2:
1038 return "Error (EEPROM2)";
1039 case CTRL_CIR_ERROR_DSP:
1040 return "Error (DSP)";
1041 case CTRL_CIR_ERROR_CRC_MAIN:
1042 return "Error (Main CRC)";
1043 case CTRL_CIR_ERROR_DL_MAIN:
1044 return "Error (Main Download)";
1045 case CTRL_CIR_ERROR_CRC_DSP:
1046 return "Error (DSP CRC)";
1047 case CTRL_CIR_ERROR_DL_DSP:
1048 return "Error (DSP Download)";
1049 case CTRL_CIR_ERROR_ASIC:
1050 return "Error (ASIC)";
1051 case CTRL_CIR_ERROR_DRAM:
1052 return "Error (DRAM)";
1053 case CTRL_CIR_ERROR_DSPCOMM:
1054 return "Error (DSP Communincation)";
1055 default:
1056 return "Error (Unknown Circuit)";
1057 }
1058 case ERROR_STATUS2_MECHANISM_CTRL:
1059 switch (error) {
1060 case MECH_ERROR_HEAD_UP:
1061 return "Error (Head Up Mechanism)";
1062 case MECH_ERROR_HEAD_DOWN:
1063 return "Error (Head Down Mechanism)";
1064 case MECH_ERROR_MAIN_PINCH_UP:
1065 return "Error (Main Pinch Up Mechanism)";
1066 case MECH_ERROR_MAIN_PINCH_DOWN:
1067 return "Error (Main Pinch Down Mechanism)";
1068 case MECH_ERROR_SUB_PINCH_UP:
1069 return "Error (Sub Pinch Up Mechanism)";
1070 case MECH_ERROR_SUB_PINCH_DOWN:
1071 return "Error (Sub Pinch Down Mechanism)";
1072 case MECH_ERROR_FEEDIN_PINCH_UP:
1073 return "Error (Feed-in Pinch Up Mechanism)";
1074 case MECH_ERROR_FEEDIN_PINCH_DOWN:
1075 return "Error (Feed-in Pinch Down Mechanism)";
1076 case MECH_ERROR_FEEDOUT_PINCH_UP:
1077 return "Error (Feed-out Pinch Up Mechanism)";
1078 case MECH_ERROR_FEEDOUT_PINCH_DOWN:
1079 return "Error (Feed-out Pinch Down Mechanism)";
1080 case MECH_ERROR_CUTTER_LR:
1081 return "Error (Left->Right Cutter)";
1082 case MECH_ERROR_CUTTER_RL:
1083 return "Error (Right->Left Cutter)";
1084 default:
1085 return "Error (Unknown Mechanism)";
1086 }
1087 case ERROR_STATUS2_SENSOR:
1088 switch (error) {
1089 case SENSOR_ERROR_CUTTER:
1090 return "Error (Cutter Sensor)";
1091 case SENSOR_ERROR_HEAD_DOWN:
1092 return "Error (Head Down Sensor)";
1093 case SENSOR_ERROR_HEAD_UP:
1094 return "Error (Head Up Sensor)";
1095 case SENSOR_ERROR_MAIN_PINCH_DOWN:
1096 return "Error (Main Pinch Down Sensor)";
1097 case SENSOR_ERROR_MAIN_PINCH_UP:
1098 return "Error (Main Pinch Up Sensor)";
1099 case SENSOR_ERROR_FEED_PINCH_DOWN:
1100 return "Error (Feed Pinch Down Sensor)";
1101 case SENSOR_ERROR_FEED_PINCH_UP:
1102 return "Error (Feed Pinch Up Sensor)";
1103 case SENSOR_ERROR_EXIT_PINCH_DOWN:
1104 return "Error (Exit Pinch Up Sensor)";
1105 case SENSOR_ERROR_EXIT_PINCH_UP:
1106 return "Error (Exit Pinch Up Sensor)";
1107 case SENSOR_ERROR_LEFT_CUTTER:
1108 return "Error (Left Cutter Sensor)";
1109 case SENSOR_ERROR_RIGHT_CUTTER:
1110 return "Error (Right Cutter Sensor)";
1111 case SENSOR_ERROR_CENTER_CUTTER:
1112 return "Error (Center Cutter Sensor)";
1113 case SENSOR_ERROR_UPPER_CUTTER:
1114 return "Error (Upper Cutter Sensor)";
1115 case SENSOR_ERROR_PAPER_FEED_COVER:
1116 return "Error (Paper Feed Cover)";
1117 default:
1118 return "Error (Unknown Sensor)";
1119 }
1120 case ERROR_STATUS2_COVER_OPEN:
1121 switch (error) {
1122 case COVER_OPEN_ERROR_UPPER:
1123 return "Error (Upper Cover Open)";
1124 case COVER_OPEN_ERROR_LOWER:
1125 return "Error (Lower Cover Open)";
1126 default:
1127 return "Error (Unknown Cover Open)";
1128 }
1129 case ERROR_STATUS2_TEMP_SENSOR:
1130 switch (error) {
1131 case TEMP_SENSOR_ERROR_HEAD_HIGH:
1132 return "Error (Head Temperature High)";
1133 case TEMP_SENSOR_ERROR_HEAD_LOW:
1134 return "Error (Head Temperature Low)";
1135 case TEMP_SENSOR_ERROR_ENV_HIGH:
1136 return "Error (Environmental Temperature High)";
1137 case TEMP_SENSOR_ERROR_ENV_LOW:
1138 return "Error (Environmental Temperature Low)";
1139 default:
1140 return "Error (Unknown Temperature)";
1141 }
1142 case ERROR_STATUS2_PAPER_JAM:
1143 return "Error (Paper Jam)";
1144 case ERROR_STATUS2_PAPER_EMPTY:
1145 return "Error (Paper Empty)";
1146 case ERROR_STATUS2_RIBBON_ERR:
1147 return "Error (Ribbon)";
1148 default:
1149 return "Error (Unknown)";
1150 }
1151 default:
1152 return "Unknown!";
1153 }
1154 }
1155