1 /****************************************************************/
2 /* spca50x.c - Gphoto2 library for cameras with sunplus spca50x */
5 /* Copyright © 2002, 2003 Till Adam */
7 /* Author: Till Adam <till@adam-lilienthal.de> */
9 /* Pure digital support: John Maushammer <www.maushammer.com> */
11 /* This library is free software; you can redistribute it */
12 /* and/or modify it under the terms of the GNU Library General */
13 /* Public License as published by the Free Software Foundation; */
14 /* either version 2 of the License, or (at your option) any */
17 /* This library is distributed in the hope that it will be */
18 /* useful, but WITHOUT ANY WARRANTY; without even the implied */
19 /* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
20 /* PURPOSE. See the GNU Library General Public License for */
23 /* You should have received a copy of the GNU Library General */
24 /* Public License along with this library; if not, write to the */
25 /* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
26 /* Boston, MA 02111-1307, USA. */
27 /****************************************************************/
33 #include <gphoto2/gphoto2.h>
34 #include "gphoto2-endian.h"
37 #include "spca50x-registers.h"
38 #include "spca50x-jpeg-header.h"
43 # define _(String) dgettext (GETTEXT_PACKAGE, String)
45 # define N_(String) gettext_noop (String)
47 # define N_(String) (String)
50 # define textdomain(String) (String)
51 # define gettext(String) (String)
52 # define dgettext(Domain,Message) (Message)
53 # define dcgettext(Domain,Message,Type) (Message)
54 # define bindtextdomain(Domain,Directory) (Domain)
55 # define _(String) (String)
56 # define N_(String) (String)
59 #define GP_MODULE "spca50x"
62 spca50x_get_firmware_revision (CameraPrivateLibrary *lib)
65 CHECK (gp_port_usb_msg_read (lib->gpdev, 0x20, 0x0, 0x0,
71 spca50x_detect_storage_type (CameraPrivateLibrary *lib)
78 buf[i] = 0; /* if no data returned, assume no capability */
79 CHECK (gp_port_usb_msg_read (lib->gpdev, 0x28, 0x0000,
83 if (buf[0]) lib->storage_media_mask |= SPCA50X_SDRAM;
84 if (buf[1]) lib->storage_media_mask |= SPCA50X_FLASH;
85 if (buf[2]) lib->storage_media_mask |= SPCA50X_CARD;
86 GP_DEBUG("SPCA50x: has_sdram: 0x%x has_flash 0x%x has_card: 0x%x\n",
87 buf[0], buf[1], buf[2]);
93 spca50x_pd_enable (CameraPrivateLibrary * lib)
98 uint32_t return_value;
100 GP_DEBUG ("Pure digital additional initialization");
101 CHECK (gp_port_usb_msg_read (lib->gpdev, 0x2d, 0x0000, 0x0001,
103 bcd_serial = ((buf[0] & 0x0f) << 28) |
104 ((buf[1] & 0x0f) << 24) |
105 ((buf[2] & 0x0f) << 20) |
106 ((buf[3] & 0x0f) << 16) |
107 ((buf[4] & 0x0f) << 12) |
108 ((buf[5] & 0x0f) << 8) |
109 ((buf[6] & 0x0f) << 4) |
110 ((buf[7] & 0x0f) << 0);
111 GP_DEBUG ("Camera serial number = %08x", bcd_serial);
112 return_value = ~bcd_serial << 2;
113 GP_DEBUG ("return value = %08x", return_value);
114 writebyte = return_value & 0xff;
115 CHECK (gp_port_usb_msg_write (lib->gpdev, 0x2d, 0x0000, 0x0000,
116 (char*)&writebyte, 0x01));
117 writebyte = (return_value >> 8) & 0xff;
118 CHECK (gp_port_usb_msg_write (lib->gpdev, 0x2d, 0x0000, 0x0001,
119 (char*)&writebyte, 0x01));
120 writebyte = (return_value >> 16) & 0xff;
121 CHECK (gp_port_usb_msg_write (lib->gpdev, 0x2d, 0x0000, 0x0002,
122 (char*)&writebyte, 0x01));
123 writebyte = (return_value >> 24) & 0xff;
124 CHECK (gp_port_usb_msg_write (lib->gpdev, 0x2d, 0x0000, 0x0003,
125 (char*)&writebyte, 0x01));
130 spca50x_reset (CameraPrivateLibrary * lib)
132 GP_DEBUG ("* spca50x_reset");
133 if (lib->bridge == BRIDGE_SPCA500) {
134 if (lib->storage_media_mask & SPCA50X_SDRAM) {
135 /* This is not reset but "Change Mode to Idle
136 * (Clear Buffer)" Cant hurt, I guess. */
137 CHECK (gp_port_usb_msg_write
138 (lib->gpdev, 0x02, 0x0000, 0x07, NULL, 0));
140 } else if (lib->fw_rev == 1) {
141 CHECK (gp_port_usb_msg_write
142 (lib->gpdev, 0x02, 0x0000, 0x0003, NULL, 0));
143 } else if (lib->fw_rev == 2) {
144 CHECK (gp_port_usb_msg_write(lib->gpdev, 0, 1,
145 SPCA50X_REG_AutoPbSize, NULL, 0));
146 CHECK (gp_port_usb_msg_write(lib->gpdev, 0, 0,
148 CHECK (gp_port_usb_msg_write(lib->gpdev, 0x1e, 0, 0, NULL, 0));
149 if (lib->bridge == BRIDGE_SPCA504B_PD) {
150 CHECK (spca50x_pd_enable (lib));
159 yuv2rgb (int y, int u, int v, int *_r, int *_g, int *_b)
163 r = (char) y + 128 + 1.402 * (char) v;
164 g = (char) y + 128 - 0.34414 * (char) u - 0.71414 * (char) v;
165 b = (char) y + 128 + 1.772 * (char) u;
188 spca50x_capture (CameraPrivateLibrary * lib)
191 CHECK (gp_port_usb_msg_write
192 (lib->gpdev, 0x06, 0x0000, 0x0003, NULL, 0));
198 create_jpeg_from_data (uint8_t * dst, uint8_t * src, int qIndex, int w,
199 int h, uint8_t format, int o_size, int *size,
200 int omit_huffman_table, int omit_escape)
207 /* copy the header from the template */
208 memcpy (dst, SPCA50xJPGDefaultHeaderPart1,
209 SPCA50X_JPG_DEFAULT_HEADER_PART1_LENGTH);
211 /* modify quantization table */
212 memcpy (dst + 7, SPCA50xQTable[qIndex * 2], 64);
213 memcpy (dst + 72, SPCA50xQTable[qIndex * 2 + 1], 64);
215 dst += SPCA50X_JPG_DEFAULT_HEADER_PART1_LENGTH;
217 /* copy Huffman table */
218 if (!omit_huffman_table) {
219 memcpy (dst, SPCA50xJPGDefaultHeaderPart2,
220 SPCA50X_JPG_DEFAULT_HEADER_PART2_LENGTH);
221 dst += SPCA50X_JPG_DEFAULT_HEADER_PART2_LENGTH;
223 memcpy (dst, SPCA50xJPGDefaultHeaderPart3,
224 SPCA50X_JPG_DEFAULT_HEADER_PART3_LENGTH);
226 /* modify the image width, height */
227 *(dst + 8) = w & 0xFF; /* Image width low byte */
228 *(dst + 7) = w >> 8 & 0xFF; /* Image width high byte */
229 *(dst + 6) = h & 0xFF; /* Image height low byte */
230 *(dst + 5) = h >> 8 & 0xFF; /* Image height high byte */
233 *(dst + 11) = format;
235 /* point to real JPG compress data start position and copy */
236 dst += SPCA50X_JPG_DEFAULT_HEADER_PART3_LENGTH;
238 for (i = 0; i < o_size; i++) {
239 value = *(src + i) & 0xFF;
243 if (value == 0xFF && !omit_escape) {
248 /* Add end of image marker */