aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cpia2
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2006-02-26 22:09:05 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-02-26 22:09:05 -0500
commitab33d5071de7a33616842882c11b5eb52a6c26a1 (patch)
tree5484a1a0d671e7191a47a1b51d5e1ae67fc8916f /drivers/media/video/cpia2
parentf05cce863fa399dd79c5aa3896d608b8b86d8030 (diff)
V4L/DVB (3376): Add cpia2 camera support
There has been a CPIA2 driver out of kernel for a long time and it has been pretty clean for some time too. This is an import of the sourceforge driver which has been stripped of - 2.4 back compatibility - 2.4 old style MJPEG ioctls A couple of functions have been made static and the docs have been repackaged into Documentation/video4linux. The rvmalloc/free functions now match the cpia driver again. Other than that this is the code as is. Tested on x86-64 with a QX5 microscope. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/cpia2')
-rw-r--r--drivers/media/video/cpia2/Makefile3
-rw-r--r--drivers/media/video/cpia2/cpia2.h497
-rw-r--r--drivers/media/video/cpia2/cpia2_core.c2525
-rw-r--r--drivers/media/video/cpia2/cpia2_registers.h476
-rw-r--r--drivers/media/video/cpia2/cpia2_usb.c907
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c2104
-rw-r--r--drivers/media/video/cpia2/cpia2dev.h50
-rw-r--r--drivers/media/video/cpia2/cpia2patch.h233
8 files changed, 6795 insertions, 0 deletions
diff --git a/drivers/media/video/cpia2/Makefile b/drivers/media/video/cpia2/Makefile
new file mode 100644
index 000000000000..828cf1b1df86
--- /dev/null
+++ b/drivers/media/video/cpia2/Makefile
@@ -0,0 +1,3 @@
1cpia2-objs := cpia2_v4l.o cpia2_usb.o cpia2_core.o
2
3obj-$(CONFIG_VIDEO_CPIA2) += cpia2.o
diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h
new file mode 100644
index 000000000000..95d3afa94a3d
--- /dev/null
+++ b/drivers/media/video/cpia2/cpia2.h
@@ -0,0 +1,497 @@
1/****************************************************************************
2 *
3 * Filename: cpia2.h
4 *
5 * Copyright 2001, STMicrolectronics, Inc.
6 *
7 * Contact: steve.miller@st.com
8 *
9 * Description:
10 * This is a USB driver for CPiA2 based video cameras.
11 *
12 * This driver is modelled on the cpia usb driver by
13 * Jochen Scharrlach and Johannes Erdfeldt.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 ****************************************************************************/
30
31#ifndef __CPIA2_H__
32#define __CPIA2_H__
33
34#include <linux/version.h>
35#include <linux/videodev.h>
36#include <linux/usb.h>
37#include <linux/poll.h>
38
39#include "cpia2dev.h"
40#include "cpia2_registers.h"
41
42/* define for verbose debug output */
43//#define _CPIA2_DEBUG_
44
45#define CPIA2_MAJ_VER 2
46#define CPIA2_MIN_VER 0
47#define CPIA2_PATCH_VER 0
48
49/***
50 * Image defines
51 ***/
52#ifndef true
53#define true 1
54#define false 0
55#endif
56
57/* Misc constants */
58#define ALLOW_CORRUPT 0 /* Causes collater to discard checksum */
59
60/* USB Transfer mode */
61#define XFER_ISOC 0
62#define XFER_BULK 1
63
64/* USB Alternates */
65#define USBIF_CMDONLY 0
66#define USBIF_BULK 1
67#define USBIF_ISO_1 2 /* 128 bytes/ms */
68#define USBIF_ISO_2 3 /* 384 bytes/ms */
69#define USBIF_ISO_3 4 /* 640 bytes/ms */
70#define USBIF_ISO_4 5 /* 768 bytes/ms */
71#define USBIF_ISO_5 6 /* 896 bytes/ms */
72#define USBIF_ISO_6 7 /* 1023 bytes/ms */
73
74/* Flicker Modes */
75#define NEVER_FLICKER 0
76#define ANTI_FLICKER_ON 1
77#define FLICKER_60 60
78#define FLICKER_50 50
79
80/* Debug flags */
81#define DEBUG_NONE 0
82#define DEBUG_REG 0x00000001
83#define DEBUG_DUMP_PATCH 0x00000002
84#define DEBUG_DUMP_REGS 0x00000004
85
86/***
87 * Video frame sizes
88 ***/
89enum {
90 VIDEOSIZE_VGA = 0, /* 640x480 */
91 VIDEOSIZE_CIF, /* 352x288 */
92 VIDEOSIZE_QVGA, /* 320x240 */
93 VIDEOSIZE_QCIF, /* 176x144 */
94 VIDEOSIZE_288_216,
95 VIDEOSIZE_256_192,
96 VIDEOSIZE_224_168,
97 VIDEOSIZE_192_144,
98};
99
100#define STV_IMAGE_CIF_ROWS 288
101#define STV_IMAGE_CIF_COLS 352
102
103#define STV_IMAGE_QCIF_ROWS 144
104#define STV_IMAGE_QCIF_COLS 176
105
106#define STV_IMAGE_VGA_ROWS 480
107#define STV_IMAGE_VGA_COLS 640
108
109#define STV_IMAGE_QVGA_ROWS 240
110#define STV_IMAGE_QVGA_COLS 320
111
112#define JPEG_MARKER_COM (1<<6) /* Comment segment */
113
114/***
115 * Enums
116 ***/
117/* Sensor types available with cpia2 asics */
118enum sensors {
119 CPIA2_SENSOR_410,
120 CPIA2_SENSOR_500
121};
122
123/* Asic types available in the CPiA2 architecture */
124#define CPIA2_ASIC_672 0x67
125
126/* Device types (stv672, stv676, etc) */
127#define DEVICE_STV_672 0x0001
128#define DEVICE_STV_676 0x0002
129
130enum frame_status {
131 FRAME_EMPTY,
132 FRAME_READING, /* In the process of being grabbed into */
133 FRAME_READY, /* Ready to be read */
134 FRAME_ERROR,
135};
136
137/***
138 * Register access (for USB request byte)
139 ***/
140enum {
141 CAMERAACCESS_SYSTEM = 0,
142 CAMERAACCESS_VC,
143 CAMERAACCESS_VP,
144 CAMERAACCESS_IDATA
145};
146
147#define CAMERAACCESS_TYPE_BLOCK 0x00
148#define CAMERAACCESS_TYPE_RANDOM 0x04
149#define CAMERAACCESS_TYPE_MASK 0x08
150#define CAMERAACCESS_TYPE_REPEAT 0x0C
151
152#define TRANSFER_READ 0
153#define TRANSFER_WRITE 1
154
155#define DEFAULT_ALT USBIF_ISO_6
156#define DEFAULT_BRIGHTNESS 0x46
157#define DEFAULT_CONTRAST 0x93
158#define DEFAULT_SATURATION 0x7f
159#define DEFAULT_TARGET_KB 0x30
160
161/* Power state */
162#define HI_POWER_MODE CPIA2_SYSTEM_CONTROL_HIGH_POWER
163#define LO_POWER_MODE CPIA2_SYSTEM_CONTROL_LOW_POWER
164
165
166/********
167 * Commands
168 *******/
169enum {
170 CPIA2_CMD_NONE = 0,
171 CPIA2_CMD_GET_VERSION,
172 CPIA2_CMD_GET_PNP_ID,
173 CPIA2_CMD_GET_ASIC_TYPE,
174 CPIA2_CMD_GET_SENSOR,
175 CPIA2_CMD_GET_VP_DEVICE,
176 CPIA2_CMD_GET_VP_BRIGHTNESS,
177 CPIA2_CMD_SET_VP_BRIGHTNESS,
178 CPIA2_CMD_GET_CONTRAST,
179 CPIA2_CMD_SET_CONTRAST,
180 CPIA2_CMD_GET_VP_SATURATION,
181 CPIA2_CMD_SET_VP_SATURATION,
182 CPIA2_CMD_GET_VP_GPIO_DIRECTION,
183 CPIA2_CMD_SET_VP_GPIO_DIRECTION,
184 CPIA2_CMD_GET_VP_GPIO_DATA,
185 CPIA2_CMD_SET_VP_GPIO_DATA,
186 CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION,
187 CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
188 CPIA2_CMD_GET_VC_MP_GPIO_DATA,
189 CPIA2_CMD_SET_VC_MP_GPIO_DATA,
190 CPIA2_CMD_ENABLE_PACKET_CTRL,
191 CPIA2_CMD_GET_FLICKER_MODES,
192 CPIA2_CMD_SET_FLICKER_MODES,
193 CPIA2_CMD_RESET_FIFO, /* clear fifo and enable stream block */
194 CPIA2_CMD_SET_HI_POWER,
195 CPIA2_CMD_SET_LOW_POWER,
196 CPIA2_CMD_CLEAR_V2W_ERR,
197 CPIA2_CMD_SET_USER_MODE,
198 CPIA2_CMD_GET_USER_MODE,
199 CPIA2_CMD_FRAMERATE_REQ,
200 CPIA2_CMD_SET_COMPRESSION_STATE,
201 CPIA2_CMD_GET_WAKEUP,
202 CPIA2_CMD_SET_WAKEUP,
203 CPIA2_CMD_GET_PW_CONTROL,
204 CPIA2_CMD_SET_PW_CONTROL,
205 CPIA2_CMD_GET_SYSTEM_CTRL,
206 CPIA2_CMD_SET_SYSTEM_CTRL,
207 CPIA2_CMD_GET_VP_SYSTEM_STATE,
208 CPIA2_CMD_GET_VP_SYSTEM_CTRL,
209 CPIA2_CMD_SET_VP_SYSTEM_CTRL,
210 CPIA2_CMD_GET_VP_EXP_MODES,
211 CPIA2_CMD_SET_VP_EXP_MODES,
212 CPIA2_CMD_GET_DEVICE_CONFIG,
213 CPIA2_CMD_SET_DEVICE_CONFIG,
214 CPIA2_CMD_SET_SERIAL_ADDR,
215 CPIA2_CMD_SET_SENSOR_CR1,
216 CPIA2_CMD_GET_VC_CONTROL,
217 CPIA2_CMD_SET_VC_CONTROL,
218 CPIA2_CMD_SET_TARGET_KB,
219 CPIA2_CMD_SET_DEF_JPEG_OPT,
220 CPIA2_CMD_REHASH_VP4,
221 CPIA2_CMD_GET_USER_EFFECTS,
222 CPIA2_CMD_SET_USER_EFFECTS
223};
224
225enum user_cmd {
226 COMMAND_NONE = 0x00000001,
227 COMMAND_SET_FPS = 0x00000002,
228 COMMAND_SET_COLOR_PARAMS = 0x00000004,
229 COMMAND_GET_COLOR_PARAMS = 0x00000008,
230 COMMAND_SET_FORMAT = 0x00000010, /* size, etc */
231 COMMAND_SET_FLICKER = 0x00000020
232};
233
234/***
235 * Some defines specific to the 676 chip
236 ***/
237#define CAMACC_CIF 0x01
238#define CAMACC_VGA 0x02
239#define CAMACC_QCIF 0x04
240#define CAMACC_QVGA 0x08
241
242
243struct cpia2_register {
244 u8 index;
245 u8 value;
246};
247
248struct cpia2_reg_mask {
249 u8 index;
250 u8 and_mask;
251 u8 or_mask;
252 u8 fill;
253};
254
255struct cpia2_command {
256 u32 command;
257 u8 req_mode; /* (Block or random) | registerBank */
258 u8 reg_count;
259 u8 direction;
260 u8 start;
261 union reg_types {
262 struct cpia2_register registers[32];
263 struct cpia2_reg_mask masks[16];
264 u8 block_data[64];
265 u8 *patch_data; /* points to function defined block */
266 } buffer;
267};
268
269struct camera_params {
270 struct {
271 u8 firmware_revision_hi; /* For system register set (bank 0) */
272 u8 firmware_revision_lo;
273 u8 asic_id; /* Video Compressor set (bank 1) */
274 u8 asic_rev;
275 u8 vp_device_hi; /* Video Processor set (bank 2) */
276 u8 vp_device_lo;
277 u8 sensor_flags;
278 u8 sensor_rev;
279 } version;
280
281 struct {
282 u32 device_type; /* enumerated from vendor/product ids.
283 * Currently, either STV_672 or STV_676 */
284 u16 vendor;
285 u16 product;
286 u16 device_revision;
287 } pnp_id;
288
289 struct {
290 u8 brightness; /* CPIA2_VP_EXPOSURE_TARGET */
291 u8 contrast; /* Note: this is CPIA2_VP_YRANGE */
292 u8 saturation; /* CPIA2_VP_SATURATION */
293 } color_params;
294
295 struct {
296 u8 cam_register;
297 u8 flicker_mode_req; /* 1 if flicker on, else never flicker */
298 int mains_frequency;
299 } flicker_control;
300
301 struct {
302 u8 jpeg_options;
303 u8 creep_period;
304 u8 user_squeeze;
305 u8 inhibit_htables;
306 } compression;
307
308 struct {
309 u8 ohsize; /* output image size */
310 u8 ovsize;
311 u8 hcrop; /* cropping start_pos/4 */
312 u8 vcrop;
313 u8 hphase; /* scaling registers */
314 u8 vphase;
315 u8 hispan;
316 u8 vispan;
317 u8 hicrop;
318 u8 vicrop;
319 u8 hifraction;
320 u8 vifraction;
321 } image_size;
322
323 struct {
324 int width; /* actual window width */
325 int height; /* actual window height */
326 } roi;
327
328 struct {
329 u8 video_mode;
330 u8 frame_rate;
331 u8 video_size; /* Not a register, just a convenience for cropped sizes */
332 u8 gpio_direction;
333 u8 gpio_data;
334 u8 system_ctrl;
335 u8 system_state;
336 u8 lowlight_boost; /* Bool: 0 = off, 1 = on */
337 u8 device_config;
338 u8 exposure_modes;
339 u8 user_effects;
340 } vp_params;
341
342 struct {
343 u8 pw_control;
344 u8 wakeup;
345 u8 vc_control;
346 u8 vc_mp_direction;
347 u8 vc_mp_data;
348 u8 target_kb;
349 } vc_params;
350
351 struct {
352 u8 power_mode;
353 u8 system_ctrl;
354 u8 stream_mode; /* This is the current alternate for usb drivers */
355 u8 allow_corrupt;
356 } camera_state;
357};
358
359#define NUM_SBUF 2
360
361struct cpia2_sbuf {
362 char *data;
363 struct urb *urb;
364};
365
366struct framebuf {
367 struct timeval timestamp;
368 unsigned long seq;
369 int num;
370 int length;
371 int max_length;
372 volatile enum frame_status status;
373 u8 *data;
374 struct framebuf *next;
375};
376
377struct cpia2_fh {
378 enum v4l2_priority prio;
379 u8 mmapped;
380};
381
382struct camera_data {
383 /* locks */
384 struct semaphore busy_lock; /* guard against SMP multithreading */
385 struct v4l2_prio_state prio;
386
387 /* camera status */
388 volatile int present; /* Is the camera still present? */
389 int open_count; /* # of process that have camera open */
390 int first_image_seen;
391 u8 mains_freq; /* for flicker control */
392 enum sensors sensor_type;
393 u8 flush;
394 u8 mmapped;
395 int streaming; /* 0 = no, 1 = yes */
396 int xfer_mode; /* XFER_BULK or XFER_ISOC */
397 struct camera_params params; /* camera settings */
398
399 /* v4l */
400 int video_size; /* VIDEO_SIZE_ */
401 struct video_device *vdev; /* v4l videodev */
402 struct video_picture vp; /* v4l camera settings */
403 struct video_window vw; /* v4l capture area */
404 __u32 pixelformat; /* Format fourcc */
405
406 /* USB */
407 struct usb_device *dev;
408 unsigned char iface;
409 unsigned int cur_alt;
410 unsigned int old_alt;
411 struct cpia2_sbuf sbuf[NUM_SBUF]; /* Double buffering */
412
413 wait_queue_head_t wq_stream;
414
415 /* Buffering */
416 u32 frame_size;
417 int num_frames;
418 unsigned long frame_count;
419 u8 *frame_buffer; /* frame buffer data */
420 struct framebuf *buffers;
421 struct framebuf * volatile curbuff;
422 struct framebuf *workbuff;
423
424 /* MJPEG Extension */
425 int APPn; /* Number of APP segment to be written, must be 0..15 */
426 int APP_len; /* Length of data in JPEG APPn segment */
427 char APP_data[60]; /* Data in the JPEG APPn segment. */
428
429 int COM_len; /* Length of data in JPEG COM segment */
430 char COM_data[60]; /* Data in JPEG COM segment */
431};
432
433/* v4l */
434int cpia2_register_camera(struct camera_data *cam);
435void cpia2_unregister_camera(struct camera_data *cam);
436
437/* core */
438int cpia2_reset_camera(struct camera_data *cam);
439int cpia2_set_low_power(struct camera_data *cam);
440void cpia2_dbg_dump_registers(struct camera_data *cam);
441int cpia2_match_video_size(int width, int height);
442void cpia2_set_camera_state(struct camera_data *cam);
443void cpia2_save_camera_state(struct camera_data *cam);
444void cpia2_set_color_params(struct camera_data *cam);
445void cpia2_set_brightness(struct camera_data *cam, unsigned char value);
446void cpia2_set_contrast(struct camera_data *cam, unsigned char value);
447void cpia2_set_saturation(struct camera_data *cam, unsigned char value);
448int cpia2_set_flicker_mode(struct camera_data *cam, int mode);
449void cpia2_set_format(struct camera_data *cam);
450int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd);
451int cpia2_do_command(struct camera_data *cam,
452 unsigned int command,
453 unsigned char direction, unsigned char param);
454struct camera_data *cpia2_init_camera_struct(void);
455int cpia2_init_camera(struct camera_data *cam);
456int cpia2_allocate_buffers(struct camera_data *cam);
457void cpia2_free_buffers(struct camera_data *cam);
458long cpia2_read(struct camera_data *cam,
459 char *buf, unsigned long count, int noblock);
460unsigned int cpia2_poll(struct camera_data *cam,
461 struct file *filp, poll_table *wait);
462int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma);
463void cpia2_set_property_flip(struct camera_data *cam, int prop_val);
464void cpia2_set_property_mirror(struct camera_data *cam, int prop_val);
465int cpia2_set_target_kb(struct camera_data *cam, unsigned char value);
466int cpia2_set_gpio(struct camera_data *cam, unsigned char setting);
467int cpia2_set_fps(struct camera_data *cam, int framerate);
468
469/* usb */
470int cpia2_usb_init(void);
471void cpia2_usb_cleanup(void);
472int cpia2_usb_transfer_cmd(struct camera_data *cam, void *registers,
473 u8 request, u8 start, u8 count, u8 direction);
474int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate);
475int cpia2_usb_stream_stop(struct camera_data *cam);
476int cpia2_usb_stream_pause(struct camera_data *cam);
477int cpia2_usb_stream_resume(struct camera_data *cam);
478int cpia2_usb_change_streaming_alternate(struct camera_data *cam,
479 unsigned int alt);
480
481
482/* ----------------------- debug functions ---------------------- */
483#ifdef _CPIA2_DEBUG_
484#define ALOG(lev, fmt, args...) printk(lev "%s:%d %s(): " fmt, __FILE__, __LINE__, __func__, ## args)
485#define LOG(fmt, args...) ALOG(KERN_INFO, fmt, ## args)
486#define ERR(fmt, args...) ALOG(KERN_ERR, fmt, ## args)
487#define DBG(fmt, args...) ALOG(KERN_DEBUG, fmt, ## args)
488#else
489#define ALOG(fmt,args...) printk(fmt,##args)
490#define LOG(fmt,args...) ALOG(KERN_INFO "cpia2: "fmt,##args)
491#define ERR(fmt,args...) ALOG(KERN_ERR "cpia2: "fmt,##args)
492#define DBG(fmn,args...) do {} while(0)
493#endif
494/* No function or lineno, for shorter lines */
495#define KINFO(fmt, args...) printk(KERN_INFO fmt,##args)
496
497#endif
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c
new file mode 100644
index 000000000000..5dfb242d5b8c
--- /dev/null
+++ b/drivers/media/video/cpia2/cpia2_core.c
@@ -0,0 +1,2525 @@
1/****************************************************************************
2 *
3 * Filename: cpia2_core.c
4 *
5 * Copyright 2001, STMicrolectronics, Inc.
6 * Contact: steve.miller@st.com
7 *
8 * Description:
9 * This is a USB driver for CPia2 based video cameras.
10 * The infrastructure of this driver is based on the cpia usb driver by
11 * Jochen Scharrlach and Johannes Erdfeldt.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 * Stripped of 2.4 stuff ready for main kernel submit by
28 * Alan Cox <alan@redhat.com>
29 *
30 ****************************************************************************/
31
32#include "cpia2.h"
33
34#include <linux/slab.h>
35#include <linux/vmalloc.h>
36
37//#define _CPIA2_DEBUG_
38
39#include "cpia2patch.h"
40
41#ifdef _CPIA2_DEBUG_
42
43static const char *block_name[] = {
44 "System",
45 "VC",
46 "VP",
47 "IDATA"
48};
49#endif
50
51static unsigned int debugs_on = 0;//DEBUG_REG;
52
53
54/******************************************************************************
55 *
56 * Forward Declarations
57 *
58 *****************************************************************************/
59static int apply_vp_patch(struct camera_data *cam);
60static int set_default_user_mode(struct camera_data *cam);
61static int set_vw_size(struct camera_data *cam, int size);
62static int configure_sensor(struct camera_data *cam,
63 int reqwidth, int reqheight);
64static int config_sensor_410(struct camera_data *cam,
65 int reqwidth, int reqheight);
66static int config_sensor_500(struct camera_data *cam,
67 int reqwidth, int reqheight);
68static int set_all_properties(struct camera_data *cam);
69static void get_color_params(struct camera_data *cam);
70static void wake_system(struct camera_data *cam);
71static void set_lowlight_boost(struct camera_data *cam);
72static void reset_camera_struct(struct camera_data *cam);
73static int cpia2_set_high_power(struct camera_data *cam);
74
75/* Here we want the physical address of the memory.
76 * This is used when initializing the contents of the
77 * area and marking the pages as reserved.
78 */
79static inline unsigned long kvirt_to_pa(unsigned long adr)
80{
81 unsigned long kva, ret;
82
83 kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
84 kva |= adr & (PAGE_SIZE-1); /* restore the offset */
85 ret = __pa(kva);
86 return ret;
87}
88
89static void *rvmalloc(unsigned long size)
90{
91 void *mem;
92 unsigned long adr;
93
94 /* Round it off to PAGE_SIZE */
95 size = PAGE_ALIGN(size);
96
97 mem = vmalloc_32(size);
98 if (!mem)
99 return NULL;
100
101 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
102 adr = (unsigned long) mem;
103
104 while ((long)size > 0) {
105 SetPageReserved(vmalloc_to_page((void *)adr));
106 adr += PAGE_SIZE;
107 size -= PAGE_SIZE;
108 }
109 return mem;
110}
111
112static void rvfree(void *mem, unsigned long size)
113{
114 unsigned long adr;
115
116 if (!mem)
117 return;
118
119 size = PAGE_ALIGN(size);
120
121 adr = (unsigned long) mem;
122 while ((long)size > 0) {
123 ClearPageReserved(vmalloc_to_page((void *)adr));
124 adr += PAGE_SIZE;
125 size -= PAGE_SIZE;
126 }
127 vfree(mem);
128}
129
130/******************************************************************************
131 *
132 * cpia2_do_command
133 *
134 * Send an arbitrary command to the camera. For commands that read from
135 * the camera, copy the buffers into the proper param structures.
136 *****************************************************************************/
137int cpia2_do_command(struct camera_data *cam,
138 u32 command, u8 direction, u8 param)
139{
140 int retval = 0;
141 struct cpia2_command cmd;
142 unsigned int device = cam->params.pnp_id.device_type;
143
144 cmd.command = command;
145 cmd.reg_count = 2; /* default */
146 cmd.direction = direction;
147
148 /***
149 * Set up the command.
150 ***/
151 switch (command) {
152 case CPIA2_CMD_GET_VERSION:
153 cmd.req_mode =
154 CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
155 cmd.start = CPIA2_SYSTEM_DEVICE_HI;
156 break;
157 case CPIA2_CMD_GET_PNP_ID:
158 cmd.req_mode =
159 CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
160 cmd.reg_count = 8;
161 cmd.start = CPIA2_SYSTEM_DESCRIP_VID_HI;
162 break;
163 case CPIA2_CMD_GET_ASIC_TYPE:
164 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
165 cmd.start = CPIA2_VC_ASIC_ID;
166 break;
167 case CPIA2_CMD_GET_SENSOR:
168 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
169 cmd.start = CPIA2_VP_SENSOR_FLAGS;
170 break;
171 case CPIA2_CMD_GET_VP_DEVICE:
172 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
173 cmd.start = CPIA2_VP_DEVICEH;
174 break;
175 case CPIA2_CMD_SET_VP_BRIGHTNESS:
176 cmd.buffer.block_data[0] = param; /* Then fall through */
177 case CPIA2_CMD_GET_VP_BRIGHTNESS:
178 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
179 cmd.reg_count = 1;
180 if (device == DEVICE_STV_672)
181 cmd.start = CPIA2_VP4_EXPOSURE_TARGET;
182 else
183 cmd.start = CPIA2_VP5_EXPOSURE_TARGET;
184 break;
185 case CPIA2_CMD_SET_CONTRAST:
186 cmd.buffer.block_data[0] = param; /* Then fall through */
187 case CPIA2_CMD_GET_CONTRAST:
188 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
189 cmd.reg_count = 1;
190 cmd.start = CPIA2_VP_YRANGE;
191 break;
192 case CPIA2_CMD_SET_VP_SATURATION:
193 cmd.buffer.block_data[0] = param; /* Then fall through */
194 case CPIA2_CMD_GET_VP_SATURATION:
195 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
196 cmd.reg_count = 1;
197 if (device == DEVICE_STV_672)
198 cmd.start = CPIA2_VP_SATURATION;
199 else
200 cmd.start = CPIA2_VP5_MCUVSATURATION;
201 break;
202 case CPIA2_CMD_SET_VP_GPIO_DATA:
203 cmd.buffer.block_data[0] = param; /* Then fall through */
204 case CPIA2_CMD_GET_VP_GPIO_DATA:
205 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
206 cmd.reg_count = 1;
207 cmd.start = CPIA2_VP_GPIO_DATA;
208 break;
209 case CPIA2_CMD_SET_VP_GPIO_DIRECTION:
210 cmd.buffer.block_data[0] = param; /* Then fall through */
211 case CPIA2_CMD_GET_VP_GPIO_DIRECTION:
212 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
213 cmd.reg_count = 1;
214 cmd.start = CPIA2_VP_GPIO_DIRECTION;
215 break;
216 case CPIA2_CMD_SET_VC_MP_GPIO_DATA:
217 cmd.buffer.block_data[0] = param; /* Then fall through */
218 case CPIA2_CMD_GET_VC_MP_GPIO_DATA:
219 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
220 cmd.reg_count = 1;
221 cmd.start = CPIA2_VC_MP_DATA;
222 break;
223 case CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION:
224 cmd.buffer.block_data[0] = param; /* Then fall through */
225 case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION:
226 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
227 cmd.reg_count = 1;
228 cmd.start = CPIA2_VC_MP_DIR;
229 break;
230 case CPIA2_CMD_ENABLE_PACKET_CTRL:
231 cmd.req_mode =
232 CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
233 cmd.start = CPIA2_SYSTEM_INT_PACKET_CTRL;
234 cmd.reg_count = 1;
235 cmd.buffer.block_data[0] = param;
236 break;
237 case CPIA2_CMD_SET_FLICKER_MODES:
238 cmd.buffer.block_data[0] = param; /* Then fall through */
239 case CPIA2_CMD_GET_FLICKER_MODES:
240 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
241 cmd.reg_count = 1;
242 cmd.start = CPIA2_VP_FLICKER_MODES;
243 break;
244 case CPIA2_CMD_RESET_FIFO: /* clear fifo and enable stream block */
245 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
246 cmd.reg_count = 2;
247 cmd.start = 0;
248 cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL;
249 cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC |
250 CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT;
251 cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL;
252 cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC |
253 CPIA2_VC_ST_CTRL_DST_USB |
254 CPIA2_VC_ST_CTRL_EOF_DETECT |
255 CPIA2_VC_ST_CTRL_FIFO_ENABLE;
256 break;
257 case CPIA2_CMD_SET_HI_POWER:
258 cmd.req_mode =
259 CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM;
260 cmd.reg_count = 2;
261 cmd.buffer.registers[0].index =
262 CPIA2_SYSTEM_SYSTEM_CONTROL;
263 cmd.buffer.registers[1].index =
264 CPIA2_SYSTEM_SYSTEM_CONTROL;
265 cmd.buffer.registers[0].value = CPIA2_SYSTEM_CONTROL_CLEAR_ERR;
266 cmd.buffer.registers[1].value =
267 CPIA2_SYSTEM_CONTROL_HIGH_POWER;
268 break;
269 case CPIA2_CMD_SET_LOW_POWER:
270 cmd.req_mode =
271 CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
272 cmd.reg_count = 1;
273 cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL;
274 cmd.buffer.block_data[0] = 0;
275 break;
276 case CPIA2_CMD_CLEAR_V2W_ERR:
277 cmd.req_mode =
278 CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
279 cmd.reg_count = 1;
280 cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL;
281 cmd.buffer.block_data[0] = CPIA2_SYSTEM_CONTROL_CLEAR_ERR;
282 break;
283 case CPIA2_CMD_SET_USER_MODE: /* Then fall through */
284 cmd.buffer.block_data[0] = param;
285 case CPIA2_CMD_GET_USER_MODE:
286 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
287 cmd.reg_count = 1;
288 if (device == DEVICE_STV_672)
289 cmd.start = CPIA2_VP4_USER_MODE;
290 else
291 cmd.start = CPIA2_VP5_USER_MODE;
292 break;
293 case CPIA2_CMD_FRAMERATE_REQ:
294 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
295 cmd.reg_count = 1;
296 if (device == DEVICE_STV_672)
297 cmd.start = CPIA2_VP4_FRAMERATE_REQUEST;
298 else
299 cmd.start = CPIA2_VP5_FRAMERATE_REQUEST;
300 cmd.buffer.block_data[0] = param;
301 break;
302 case CPIA2_CMD_SET_WAKEUP:
303 cmd.buffer.block_data[0] = param; /* Then fall through */
304 case CPIA2_CMD_GET_WAKEUP:
305 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
306 cmd.reg_count = 1;
307 cmd.start = CPIA2_VC_WAKEUP;
308 break;
309 case CPIA2_CMD_SET_PW_CONTROL:
310 cmd.buffer.block_data[0] = param; /* Then fall through */
311 case CPIA2_CMD_GET_PW_CONTROL:
312 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
313 cmd.reg_count = 1;
314 cmd.start = CPIA2_VC_PW_CTRL;
315 break;
316 case CPIA2_CMD_GET_VP_SYSTEM_STATE:
317 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
318 cmd.reg_count = 1;
319 cmd.start = CPIA2_VP_SYSTEMSTATE;
320 break;
321 case CPIA2_CMD_SET_SYSTEM_CTRL:
322 cmd.buffer.block_data[0] = param; /* Then fall through */
323 case CPIA2_CMD_GET_SYSTEM_CTRL:
324 cmd.req_mode =
325 CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
326 cmd.reg_count = 1;
327 cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL;
328 break;
329 case CPIA2_CMD_SET_VP_SYSTEM_CTRL:
330 cmd.buffer.block_data[0] = param; /* Then fall through */
331 case CPIA2_CMD_GET_VP_SYSTEM_CTRL:
332 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
333 cmd.reg_count = 1;
334 cmd.start = CPIA2_VP_SYSTEMCTRL;
335 break;
336 case CPIA2_CMD_SET_VP_EXP_MODES:
337 cmd.buffer.block_data[0] = param; /* Then fall through */
338 case CPIA2_CMD_GET_VP_EXP_MODES:
339 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
340 cmd.reg_count = 1;
341 cmd.start = CPIA2_VP_EXPOSURE_MODES;
342 break;
343 case CPIA2_CMD_SET_DEVICE_CONFIG:
344 cmd.buffer.block_data[0] = param; /* Then fall through */
345 case CPIA2_CMD_GET_DEVICE_CONFIG:
346 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
347 cmd.reg_count = 1;
348 cmd.start = CPIA2_VP_DEVICE_CONFIG;
349 break;
350 case CPIA2_CMD_SET_SERIAL_ADDR:
351 cmd.buffer.block_data[0] = param;
352 cmd.req_mode =
353 CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
354 cmd.reg_count = 1;
355 cmd.start = CPIA2_SYSTEM_VP_SERIAL_ADDR;
356 break;
357 case CPIA2_CMD_SET_SENSOR_CR1:
358 cmd.buffer.block_data[0] = param;
359 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
360 cmd.reg_count = 1;
361 cmd.start = CPIA2_SENSOR_CR1;
362 break;
363 case CPIA2_CMD_SET_VC_CONTROL:
364 cmd.buffer.block_data[0] = param; /* Then fall through */
365 case CPIA2_CMD_GET_VC_CONTROL:
366 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
367 cmd.reg_count = 1;
368 cmd.start = CPIA2_VC_VC_CTRL;
369 break;
370 case CPIA2_CMD_SET_TARGET_KB:
371 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
372 cmd.reg_count = 1;
373 cmd.buffer.registers[0].index = CPIA2_VC_VC_TARGET_KB;
374 cmd.buffer.registers[0].value = param;
375 break;
376 case CPIA2_CMD_SET_DEF_JPEG_OPT:
377 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
378 cmd.reg_count = 4;
379 cmd.buffer.registers[0].index = CPIA2_VC_VC_JPEG_OPT;
380 cmd.buffer.registers[0].value =
381 CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE;
382 cmd.buffer.registers[1].index = CPIA2_VC_VC_USER_SQUEEZE;
383 cmd.buffer.registers[1].value = 20;
384 cmd.buffer.registers[2].index = CPIA2_VC_VC_CREEP_PERIOD;
385 cmd.buffer.registers[2].value = 2;
386 cmd.buffer.registers[3].index = CPIA2_VC_VC_JPEG_OPT;
387 cmd.buffer.registers[3].value = CPIA2_VC_VC_JPEG_OPT_DEFAULT;
388 break;
389 case CPIA2_CMD_REHASH_VP4:
390 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
391 cmd.reg_count = 1;
392 cmd.start = CPIA2_VP_REHASH_VALUES;
393 cmd.buffer.block_data[0] = param;
394 break;
395 case CPIA2_CMD_SET_USER_EFFECTS: /* Note: Be careful with this as
396 this register can also affect
397 flicker modes */
398 cmd.buffer.block_data[0] = param; /* Then fall through */
399 case CPIA2_CMD_GET_USER_EFFECTS:
400 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
401 cmd.reg_count = 1;
402 if (device == DEVICE_STV_672)
403 cmd.start = CPIA2_VP4_USER_EFFECTS;
404 else
405 cmd.start = CPIA2_VP5_USER_EFFECTS;
406 break;
407 default:
408 LOG("DoCommand received invalid command\n");
409 return -EINVAL;
410 }
411
412 retval = cpia2_send_command(cam, &cmd);
413 if (retval) {
414 return retval;
415 }
416
417 /***
418 * Now copy any results from a read into the appropriate param struct.
419 ***/
420 switch (command) {
421 case CPIA2_CMD_GET_VERSION:
422 cam->params.version.firmware_revision_hi =
423 cmd.buffer.block_data[0];
424 cam->params.version.firmware_revision_lo =
425 cmd.buffer.block_data[1];
426 break;
427 case CPIA2_CMD_GET_PNP_ID:
428 cam->params.pnp_id.vendor = (cmd.buffer.block_data[0] << 8) |
429 cmd.buffer.block_data[1];
430 cam->params.pnp_id.product = (cmd.buffer.block_data[2] << 8) |
431 cmd.buffer.block_data[3];
432 cam->params.pnp_id.device_revision =
433 (cmd.buffer.block_data[4] << 8) |
434 cmd.buffer.block_data[5];
435 if (cam->params.pnp_id.vendor == 0x553) {
436 if (cam->params.pnp_id.product == 0x100) {
437 cam->params.pnp_id.device_type = DEVICE_STV_672;
438 } else if (cam->params.pnp_id.product == 0x140 ||
439 cam->params.pnp_id.product == 0x151) {
440 cam->params.pnp_id.device_type = DEVICE_STV_676;
441 }
442 }
443 break;
444 case CPIA2_CMD_GET_ASIC_TYPE:
445 cam->params.version.asic_id = cmd.buffer.block_data[0];
446 cam->params.version.asic_rev = cmd.buffer.block_data[1];
447 break;
448 case CPIA2_CMD_GET_SENSOR:
449 cam->params.version.sensor_flags = cmd.buffer.block_data[0];
450 cam->params.version.sensor_rev = cmd.buffer.block_data[1];
451 break;
452 case CPIA2_CMD_GET_VP_DEVICE:
453 cam->params.version.vp_device_hi = cmd.buffer.block_data[0];
454 cam->params.version.vp_device_lo = cmd.buffer.block_data[1];
455 break;
456 case CPIA2_CMD_GET_VP_BRIGHTNESS:
457 cam->params.color_params.brightness = cmd.buffer.block_data[0];
458 break;
459 case CPIA2_CMD_GET_CONTRAST:
460 cam->params.color_params.contrast = cmd.buffer.block_data[0];
461 break;
462 case CPIA2_CMD_GET_VP_SATURATION:
463 cam->params.color_params.saturation = cmd.buffer.block_data[0];
464 break;
465 case CPIA2_CMD_GET_VP_GPIO_DATA:
466 cam->params.vp_params.gpio_data = cmd.buffer.block_data[0];
467 break;
468 case CPIA2_CMD_GET_VP_GPIO_DIRECTION:
469 cam->params.vp_params.gpio_direction = cmd.buffer.block_data[0];
470 break;
471 case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION:
472 cam->params.vc_params.vc_mp_direction =cmd.buffer.block_data[0];
473 break;
474 case CPIA2_CMD_GET_VC_MP_GPIO_DATA:
475 cam->params.vc_params.vc_mp_data = cmd.buffer.block_data[0];
476 break;
477 case CPIA2_CMD_GET_FLICKER_MODES:
478 cam->params.flicker_control.cam_register =
479 cmd.buffer.block_data[0];
480 break;
481 case CPIA2_CMD_GET_WAKEUP:
482 cam->params.vc_params.wakeup = cmd.buffer.block_data[0];
483 break;
484 case CPIA2_CMD_GET_PW_CONTROL:
485 cam->params.vc_params.pw_control = cmd.buffer.block_data[0];
486 break;
487 case CPIA2_CMD_GET_SYSTEM_CTRL:
488 cam->params.camera_state.system_ctrl = cmd.buffer.block_data[0];
489 break;
490 case CPIA2_CMD_GET_VP_SYSTEM_STATE:
491 cam->params.vp_params.system_state = cmd.buffer.block_data[0];
492 break;
493 case CPIA2_CMD_GET_VP_SYSTEM_CTRL:
494 cam->params.vp_params.system_ctrl = cmd.buffer.block_data[0];
495 break;
496 case CPIA2_CMD_GET_VP_EXP_MODES:
497 cam->params.vp_params.exposure_modes = cmd.buffer.block_data[0];
498 break;
499 case CPIA2_CMD_GET_DEVICE_CONFIG:
500 cam->params.vp_params.device_config = cmd.buffer.block_data[0];
501 break;
502 case CPIA2_CMD_GET_VC_CONTROL:
503 cam->params.vc_params.vc_control = cmd.buffer.block_data[0];
504 break;
505 case CPIA2_CMD_GET_USER_MODE:
506 cam->params.vp_params.video_mode = cmd.buffer.block_data[0];
507 break;
508 case CPIA2_CMD_GET_USER_EFFECTS:
509 cam->params.vp_params.user_effects = cmd.buffer.block_data[0];
510 break;
511 default:
512 break;
513 }
514 return retval;
515}
516
517/******************************************************************************
518 *
519 * cpia2_send_command
520 *
521 *****************************************************************************/
522int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd)
523{
524 u8 count;
525 u8 start;
526 u8 block_index;
527 u8 *buffer;
528 int retval;
529 const char* dir;
530
531 if (cmd->direction == TRANSFER_WRITE) {
532 dir = "Write";
533 } else {
534 dir = "Read";
535 }
536
537 block_index = cmd->req_mode & 0x03;
538
539 switch (cmd->req_mode & 0x0c) {
540 case CAMERAACCESS_TYPE_RANDOM:
541 count = cmd->reg_count * sizeof(struct cpia2_register);
542 start = 0;
543 buffer = (u8 *) & cmd->buffer;
544 if (debugs_on & DEBUG_REG)
545 DBG("%s Random: Register block %s\n", dir,
546 block_name[block_index]);
547 break;
548 case CAMERAACCESS_TYPE_BLOCK:
549 count = cmd->reg_count;
550 start = cmd->start;
551 buffer = cmd->buffer.block_data;
552 if (debugs_on & DEBUG_REG)
553 DBG("%s Block: Register block %s\n", dir,
554 block_name[block_index]);
555 break;
556 case CAMERAACCESS_TYPE_MASK:
557 count = cmd->reg_count * sizeof(struct cpia2_reg_mask);
558 start = 0;
559 buffer = (u8 *) & cmd->buffer;
560 if (debugs_on & DEBUG_REG)
561 DBG("%s Mask: Register block %s\n", dir,
562 block_name[block_index]);
563 break;
564 case CAMERAACCESS_TYPE_REPEAT: /* For patch blocks only */
565 count = cmd->reg_count;
566 start = cmd->start;
567 buffer = cmd->buffer.block_data;
568 if (debugs_on & DEBUG_REG)
569 DBG("%s Repeat: Register block %s\n", dir,
570 block_name[block_index]);
571 break;
572 default:
573 LOG("%s: invalid request mode\n",__FUNCTION__);
574 return -EINVAL;
575 }
576
577 retval = cpia2_usb_transfer_cmd(cam,
578 buffer,
579 cmd->req_mode,
580 start, count, cmd->direction);
581#ifdef _CPIA2_DEBUG_
582 if (debugs_on & DEBUG_REG) {
583 int i;
584 for (i = 0; i < cmd->reg_count; i++) {
585 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_BLOCK)
586 KINFO("%s Block: [0x%02X] = 0x%02X\n",
587 dir, start + i, buffer[i]);
588 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_RANDOM)
589 KINFO("%s Random: [0x%02X] = 0x%02X\n",
590 dir, cmd->buffer.registers[i].index,
591 cmd->buffer.registers[i].value);
592 }
593 }
594#endif
595
596 return retval;
597};
598
599/*************
600 * Functions to implement camera functionality
601 *************/
602/******************************************************************************
603 *
604 * cpia2_get_version_info
605 *
606 *****************************************************************************/
607static void cpia2_get_version_info(struct camera_data *cam)
608{
609 cpia2_do_command(cam, CPIA2_CMD_GET_VERSION, TRANSFER_READ, 0);
610 cpia2_do_command(cam, CPIA2_CMD_GET_PNP_ID, TRANSFER_READ, 0);
611 cpia2_do_command(cam, CPIA2_CMD_GET_ASIC_TYPE, TRANSFER_READ, 0);
612 cpia2_do_command(cam, CPIA2_CMD_GET_SENSOR, TRANSFER_READ, 0);
613 cpia2_do_command(cam, CPIA2_CMD_GET_VP_DEVICE, TRANSFER_READ, 0);
614}
615
616/******************************************************************************
617 *
618 * cpia2_reset_camera
619 *
620 * Called at least during the open process, sets up initial params.
621 *****************************************************************************/
622int cpia2_reset_camera(struct camera_data *cam)
623{
624 u8 tmp_reg;
625 int retval = 0;
626 int i;
627 struct cpia2_command cmd;
628
629 /***
630 * VC setup
631 ***/
632 retval = configure_sensor(cam,
633 cam->params.roi.width,
634 cam->params.roi.height);
635 if (retval < 0) {
636 ERR("Couldn't configure sensor, error=%d\n", retval);
637 return retval;
638 }
639
640 /* Clear FIFO and route/enable stream block */
641 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
642 cmd.direction = TRANSFER_WRITE;
643 cmd.reg_count = 2;
644 cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL;
645 cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC |
646 CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT;
647 cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL;
648 cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC |
649 CPIA2_VC_ST_CTRL_DST_USB |
650 CPIA2_VC_ST_CTRL_EOF_DETECT | CPIA2_VC_ST_CTRL_FIFO_ENABLE;
651
652 cpia2_send_command(cam, &cmd);
653
654 cpia2_set_high_power(cam);
655
656 if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
657 /* Enable button notification */
658 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM;
659 cmd.buffer.registers[0].index = CPIA2_SYSTEM_INT_PACKET_CTRL;
660 cmd.buffer.registers[0].value =
661 CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX;
662 cmd.reg_count = 1;
663 cpia2_send_command(cam, &cmd);
664 }
665
666 current->state = TASK_INTERRUPTIBLE;
667 schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */
668
669 if (cam->params.pnp_id.device_type == DEVICE_STV_672)
670 retval = apply_vp_patch(cam);
671
672 /* wait for vp to go to sleep */
673 current->state = TASK_INTERRUPTIBLE;
674 schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */
675
676 /***
677 * If this is a 676, apply VP5 fixes before we start streaming
678 ***/
679 if (cam->params.pnp_id.device_type == DEVICE_STV_676) {
680 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
681
682 /* The following writes improve the picture */
683 cmd.buffer.registers[0].index = CPIA2_VP5_MYBLACK_LEVEL;
684 cmd.buffer.registers[0].value = 0; /* reduce from the default
685 * rec 601 pedestal of 16 */
686 cmd.buffer.registers[1].index = CPIA2_VP5_MCYRANGE;
687 cmd.buffer.registers[1].value = 0x92; /* increase from 100% to
688 * (256/256 - 31) to fill
689 * available range */
690 cmd.buffer.registers[2].index = CPIA2_VP5_MYCEILING;
691 cmd.buffer.registers[2].value = 0xFF; /* Increase from the
692 * default rec 601 ceiling
693 * of 240 */
694 cmd.buffer.registers[3].index = CPIA2_VP5_MCUVSATURATION;
695 cmd.buffer.registers[3].value = 0xFF; /* Increase from the rec
696 * 601 100% level (128)
697 * to 145-192 */
698 cmd.buffer.registers[4].index = CPIA2_VP5_ANTIFLKRSETUP;
699 cmd.buffer.registers[4].value = 0x80; /* Inhibit the
700 * anti-flicker */
701
702 /* The following 4 writes are a fix to allow QVGA to work at 30 fps */
703 cmd.buffer.registers[5].index = CPIA2_VP_RAM_ADDR_H;
704 cmd.buffer.registers[5].value = 0x01;
705 cmd.buffer.registers[6].index = CPIA2_VP_RAM_ADDR_L;
706 cmd.buffer.registers[6].value = 0xE3;
707 cmd.buffer.registers[7].index = CPIA2_VP_RAM_DATA;
708 cmd.buffer.registers[7].value = 0x02;
709 cmd.buffer.registers[8].index = CPIA2_VP_RAM_DATA;
710 cmd.buffer.registers[8].value = 0xFC;
711
712 cmd.direction = TRANSFER_WRITE;
713 cmd.reg_count = 9;
714
715 cpia2_send_command(cam, &cmd);
716 }
717
718 /* Activate all settings and start the data stream */
719 /* Set user mode */
720 set_default_user_mode(cam);
721
722 /* Give VP time to wake up */
723 current->state = TASK_INTERRUPTIBLE;
724 schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */
725
726 set_all_properties(cam);
727
728 cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0);
729 DBG("After SetAllProperties(cam), user mode is 0x%0X\n",
730 cam->params.vp_params.video_mode);
731
732 /***
733 * Set audio regulator off. This and the code to set the compresison
734 * state are too complex to form a CPIA2_CMD_, and seem to be somewhat
735 * intertwined. This stuff came straight from the windows driver.
736 ***/
737 /* Turn AutoExposure off in VP and enable the serial bridge to the sensor */
738 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0);
739 tmp_reg = cam->params.vp_params.system_ctrl;
740 cmd.buffer.registers[0].value = tmp_reg &
741 (tmp_reg & (CPIA2_VP_SYSTEMCTRL_HK_CONTROL ^ 0xFF));
742
743 cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0);
744 cmd.buffer.registers[1].value = cam->params.vp_params.device_config |
745 CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE;
746 cmd.buffer.registers[0].index = CPIA2_VP_SYSTEMCTRL;
747 cmd.buffer.registers[1].index = CPIA2_VP_DEVICE_CONFIG;
748 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
749 cmd.reg_count = 2;
750 cmd.direction = TRANSFER_WRITE;
751 cmd.start = 0;
752 cpia2_send_command(cam, &cmd);
753
754 /* Set the correct I2C address in the CPiA-2 system register */
755 cpia2_do_command(cam,
756 CPIA2_CMD_SET_SERIAL_ADDR,
757 TRANSFER_WRITE,
758 CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR);
759
760 /* Now have sensor access - set bit to turn the audio regulator off */
761 cpia2_do_command(cam,
762 CPIA2_CMD_SET_SENSOR_CR1,
763 TRANSFER_WRITE, CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR);
764
765 /* Set the correct I2C address in the CPiA-2 system register */
766 if (cam->params.pnp_id.device_type == DEVICE_STV_672)
767 cpia2_do_command(cam,
768 CPIA2_CMD_SET_SERIAL_ADDR,
769 TRANSFER_WRITE,
770 CPIA2_SYSTEM_VP_SERIAL_ADDR_VP); // 0x88
771 else
772 cpia2_do_command(cam,
773 CPIA2_CMD_SET_SERIAL_ADDR,
774 TRANSFER_WRITE,
775 CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP); // 0x8a
776
777 /* increase signal drive strength */
778 if (cam->params.pnp_id.device_type == DEVICE_STV_676)
779 cpia2_do_command(cam,
780 CPIA2_CMD_SET_VP_EXP_MODES,
781 TRANSFER_WRITE,
782 CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP);
783
784 /* Start autoexposure */
785 cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0);
786 cmd.buffer.registers[0].value = cam->params.vp_params.device_config &
787 (CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE ^ 0xFF);
788
789 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0);
790 cmd.buffer.registers[1].value =
791 cam->params.vp_params.system_ctrl | CPIA2_VP_SYSTEMCTRL_HK_CONTROL;
792
793 cmd.buffer.registers[0].index = CPIA2_VP_DEVICE_CONFIG;
794 cmd.buffer.registers[1].index = CPIA2_VP_SYSTEMCTRL;
795 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
796 cmd.reg_count = 2;
797 cmd.direction = TRANSFER_WRITE;
798
799 cpia2_send_command(cam, &cmd);
800
801 /* Set compression state */
802 cpia2_do_command(cam, CPIA2_CMD_GET_VC_CONTROL, TRANSFER_READ, 0);
803 if (cam->params.compression.inhibit_htables) {
804 tmp_reg = cam->params.vc_params.vc_control |
805 CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES;
806 } else {
807 tmp_reg = cam->params.vc_params.vc_control &
808 ~CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES;
809 }
810 cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg);
811
812 /* Set target size (kb) on vc */
813 cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB,
814 TRANSFER_WRITE, cam->params.vc_params.target_kb);
815
816 /* Wiggle VC Reset */
817 /***
818 * First read and wait a bit.
819 ***/
820 for (i = 0; i < 50; i++) {
821 cpia2_do_command(cam, CPIA2_CMD_GET_PW_CONTROL,
822 TRANSFER_READ, 0);
823 }
824
825 tmp_reg = cam->params.vc_params.pw_control;
826 tmp_reg &= ~CPIA2_VC_PW_CTRL_VC_RESET_N;
827
828 cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg);
829
830 tmp_reg |= CPIA2_VC_PW_CTRL_VC_RESET_N;
831 cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg);
832
833 cpia2_do_command(cam, CPIA2_CMD_SET_DEF_JPEG_OPT, TRANSFER_WRITE, 0);
834
835 cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0);
836 DBG("After VC RESET, user mode is 0x%0X\n",
837 cam->params.vp_params.video_mode);
838
839 return retval;
840}
841
842/******************************************************************************
843 *
844 * cpia2_set_high_power
845 *
846 *****************************************************************************/
847static int cpia2_set_high_power(struct camera_data *cam)
848{
849 int i;
850 for (i = 0; i <= 50; i++) {
851 /* Read system status */
852 cpia2_do_command(cam,CPIA2_CMD_GET_SYSTEM_CTRL,TRANSFER_READ,0);
853
854 /* If there is an error, clear it */
855 if(cam->params.camera_state.system_ctrl &
856 CPIA2_SYSTEM_CONTROL_V2W_ERR)
857 cpia2_do_command(cam, CPIA2_CMD_CLEAR_V2W_ERR,
858 TRANSFER_WRITE, 0);
859
860 /* Try to set high power mode */
861 cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL,
862 TRANSFER_WRITE, 1);
863
864 /* Try to read something in VP to check if everything is awake */
865 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_STATE,
866 TRANSFER_READ, 0);
867 if (cam->params.vp_params.system_state &
868 CPIA2_VP_SYSTEMSTATE_HK_ALIVE) {
869 break;
870 } else if (i == 50) {
871 cam->params.camera_state.power_mode = LO_POWER_MODE;
872 ERR("Camera did not wake up\n");
873 return -EIO;
874 }
875 }
876
877 DBG("System now in high power state\n");
878 cam->params.camera_state.power_mode = HI_POWER_MODE;
879 return 0;
880}
881
882/******************************************************************************
883 *
884 * cpia2_set_low_power
885 *
886 *****************************************************************************/
887int cpia2_set_low_power(struct camera_data *cam)
888{
889 cam->params.camera_state.power_mode = LO_POWER_MODE;
890 cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL, TRANSFER_WRITE, 0);
891 return 0;
892}
893
894/******************************************************************************
895 *
896 * apply_vp_patch
897 *
898 *****************************************************************************/
899static int apply_vp_patch(struct camera_data *cam)
900{
901 int i, j;
902 struct cpia2_command cmd;
903
904 cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP;
905 cmd.direction = TRANSFER_WRITE;
906
907 for (i = 0; i < PATCH_DATA_SIZE; i++) {
908 for (j = 0; j < patch_data[i].count; j++) {
909 cmd.buffer.block_data[j] = patch_data[i].data[j];
910 }
911
912 cmd.start = patch_data[i].reg;
913 cmd.reg_count = patch_data[i].count;
914 cpia2_send_command(cam, &cmd);
915 }
916
917 return 0;
918}
919
920/******************************************************************************
921 *
922 * set_default_user_mode
923 *
924 *****************************************************************************/
925static int set_default_user_mode(struct camera_data *cam)
926{
927 unsigned char user_mode;
928 unsigned char frame_rate;
929 int width = cam->params.roi.width;
930 int height = cam->params.roi.height;
931
932 switch (cam->params.version.sensor_flags) {
933 case CPIA2_VP_SENSOR_FLAGS_404:
934 case CPIA2_VP_SENSOR_FLAGS_407:
935 case CPIA2_VP_SENSOR_FLAGS_409:
936 case CPIA2_VP_SENSOR_FLAGS_410:
937 if ((width > STV_IMAGE_QCIF_COLS)
938 || (height > STV_IMAGE_QCIF_ROWS)) {
939 user_mode = CPIA2_VP_USER_MODE_CIF;
940 } else {
941 user_mode = CPIA2_VP_USER_MODE_QCIFDS;
942 }
943 frame_rate = CPIA2_VP_FRAMERATE_30;
944 break;
945 case CPIA2_VP_SENSOR_FLAGS_500:
946 if ((width > STV_IMAGE_CIF_COLS)
947 || (height > STV_IMAGE_CIF_ROWS)) {
948 user_mode = CPIA2_VP_USER_MODE_VGA;
949 } else {
950 user_mode = CPIA2_VP_USER_MODE_QVGADS;
951 }
952 if (cam->params.pnp_id.device_type == DEVICE_STV_672)
953 frame_rate = CPIA2_VP_FRAMERATE_15;
954 else
955 frame_rate = CPIA2_VP_FRAMERATE_30;
956 break;
957 default:
958 LOG("%s: Invalid sensor flag value 0x%0X\n",__FUNCTION__,
959 cam->params.version.sensor_flags);
960 return -EINVAL;
961 }
962
963 DBG("Sensor flag = 0x%0x, user mode = 0x%0x, frame rate = 0x%X\n",
964 cam->params.version.sensor_flags, user_mode, frame_rate);
965 cpia2_do_command(cam, CPIA2_CMD_SET_USER_MODE, TRANSFER_WRITE,
966 user_mode);
967 if(cam->params.vp_params.frame_rate > 0 &&
968 frame_rate > cam->params.vp_params.frame_rate)
969 frame_rate = cam->params.vp_params.frame_rate;
970
971 cpia2_set_fps(cam, frame_rate);
972
973// if (cam->params.pnp_id.device_type == DEVICE_STV_676)
974// cpia2_do_command(cam,
975// CPIA2_CMD_SET_VP_SYSTEM_CTRL,
976// TRANSFER_WRITE,
977// CPIA2_VP_SYSTEMCTRL_HK_CONTROL |
978// CPIA2_VP_SYSTEMCTRL_POWER_CONTROL);
979
980 return 0;
981}
982
983/******************************************************************************
984 *
985 * cpia2_match_video_size
986 *
987 * return the best match, where 'best' is as always
988 * the largest that is not bigger than what is requested.
989 *****************************************************************************/
990int cpia2_match_video_size(int width, int height)
991{
992 if (width >= STV_IMAGE_VGA_COLS && height >= STV_IMAGE_VGA_ROWS)
993 return VIDEOSIZE_VGA;
994
995 if (width >= STV_IMAGE_CIF_COLS && height >= STV_IMAGE_CIF_ROWS)
996 return VIDEOSIZE_CIF;
997
998 if (width >= STV_IMAGE_QVGA_COLS && height >= STV_IMAGE_QVGA_ROWS)
999 return VIDEOSIZE_QVGA;
1000
1001 if (width >= 288 && height >= 216)
1002 return VIDEOSIZE_288_216;
1003
1004 if (width >= 256 && height >= 192)
1005 return VIDEOSIZE_256_192;
1006
1007 if (width >= 224 && height >= 168)
1008 return VIDEOSIZE_224_168;
1009
1010 if (width >= 192 && height >= 144)
1011 return VIDEOSIZE_192_144;
1012
1013 if (width >= STV_IMAGE_QCIF_COLS && height >= STV_IMAGE_QCIF_ROWS)
1014 return VIDEOSIZE_QCIF;
1015
1016 return -1;
1017}
1018
1019/******************************************************************************
1020 *
1021 * SetVideoSize
1022 *
1023 *****************************************************************************/
1024static int set_vw_size(struct camera_data *cam, int size)
1025{
1026 int retval = 0;
1027
1028 cam->params.vp_params.video_size = size;
1029
1030 switch (size) {
1031 case VIDEOSIZE_VGA:
1032 DBG("Setting size to VGA\n");
1033 cam->params.roi.width = STV_IMAGE_VGA_COLS;
1034 cam->params.roi.height = STV_IMAGE_VGA_ROWS;
1035 cam->vw.width = STV_IMAGE_VGA_COLS;
1036 cam->vw.height = STV_IMAGE_VGA_ROWS;
1037 break;
1038 case VIDEOSIZE_CIF:
1039 DBG("Setting size to CIF\n");
1040 cam->params.roi.width = STV_IMAGE_CIF_COLS;
1041 cam->params.roi.height = STV_IMAGE_CIF_ROWS;
1042 cam->vw.width = STV_IMAGE_CIF_COLS;
1043 cam->vw.height = STV_IMAGE_CIF_ROWS;
1044 break;
1045 case VIDEOSIZE_QVGA:
1046 DBG("Setting size to QVGA\n");
1047 cam->params.roi.width = STV_IMAGE_QVGA_COLS;
1048 cam->params.roi.height = STV_IMAGE_QVGA_ROWS;
1049 cam->vw.width = STV_IMAGE_QVGA_COLS;
1050 cam->vw.height = STV_IMAGE_QVGA_ROWS;
1051 break;
1052 case VIDEOSIZE_288_216:
1053 cam->params.roi.width = 288;
1054 cam->params.roi.height = 216;
1055 cam->vw.width = 288;
1056 cam->vw.height = 216;
1057 break;
1058 case VIDEOSIZE_256_192:
1059 cam->vw.width = 256;
1060 cam->vw.height = 192;
1061 cam->params.roi.width = 256;
1062 cam->params.roi.height = 192;
1063 break;
1064 case VIDEOSIZE_224_168:
1065 cam->vw.width = 224;
1066 cam->vw.height = 168;
1067 cam->params.roi.width = 224;
1068 cam->params.roi.height = 168;
1069 break;
1070 case VIDEOSIZE_192_144:
1071 cam->vw.width = 192;
1072 cam->vw.height = 144;
1073 cam->params.roi.width = 192;
1074 cam->params.roi.height = 144;
1075 break;
1076 case VIDEOSIZE_QCIF:
1077 DBG("Setting size to QCIF\n");
1078 cam->params.roi.width = STV_IMAGE_QCIF_COLS;
1079 cam->params.roi.height = STV_IMAGE_QCIF_ROWS;
1080 cam->vw.width = STV_IMAGE_QCIF_COLS;
1081 cam->vw.height = STV_IMAGE_QCIF_ROWS;
1082 break;
1083 default:
1084 retval = -EINVAL;
1085 }
1086 return retval;
1087}
1088
1089/******************************************************************************
1090 *
1091 * configure_sensor
1092 *
1093 *****************************************************************************/
1094static int configure_sensor(struct camera_data *cam,
1095 int req_width, int req_height)
1096{
1097 int retval;
1098
1099 switch (cam->params.version.sensor_flags) {
1100 case CPIA2_VP_SENSOR_FLAGS_404:
1101 case CPIA2_VP_SENSOR_FLAGS_407:
1102 case CPIA2_VP_SENSOR_FLAGS_409:
1103 case CPIA2_VP_SENSOR_FLAGS_410:
1104 retval = config_sensor_410(cam, req_width, req_height);
1105 break;
1106 case CPIA2_VP_SENSOR_FLAGS_500:
1107 retval = config_sensor_500(cam, req_width, req_height);
1108 break;
1109 default:
1110 return -EINVAL;
1111 }
1112
1113 return retval;
1114}
1115
1116/******************************************************************************
1117 *
1118 * config_sensor_410
1119 *
1120 *****************************************************************************/
1121static int config_sensor_410(struct camera_data *cam,
1122 int req_width, int req_height)
1123{
1124 struct cpia2_command cmd;
1125 int i = 0;
1126 int image_size;
1127 int image_type;
1128 int width = req_width;
1129 int height = req_height;
1130
1131 /***
1132 * Make sure size doesn't exceed CIF.
1133 ***/
1134 if (width > STV_IMAGE_CIF_COLS)
1135 width = STV_IMAGE_CIF_COLS;
1136 if (height > STV_IMAGE_CIF_ROWS)
1137 height = STV_IMAGE_CIF_ROWS;
1138
1139 image_size = cpia2_match_video_size(width, height);
1140
1141 DBG("Config 410: width = %d, height = %d\n", width, height);
1142 DBG("Image size returned is %d\n", image_size);
1143 if (image_size >= 0) {
1144 set_vw_size(cam, image_size);
1145 width = cam->params.roi.width;
1146 height = cam->params.roi.height;
1147
1148 DBG("After set_vw_size(), width = %d, height = %d\n",
1149 width, height);
1150 if (width <= 176 && height <= 144) {
1151 DBG("image type = VIDEOSIZE_QCIF\n");
1152 image_type = VIDEOSIZE_QCIF;
1153 }
1154 else if (width <= 320 && height <= 240) {
1155 DBG("image type = VIDEOSIZE_QVGA\n");
1156 image_type = VIDEOSIZE_QVGA;
1157 }
1158 else {
1159 DBG("image type = VIDEOSIZE_CIF\n");
1160 image_type = VIDEOSIZE_CIF;
1161 }
1162 } else {
1163 ERR("ConfigSensor410 failed\n");
1164 return -EINVAL;
1165 }
1166
1167 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
1168 cmd.direction = TRANSFER_WRITE;
1169
1170 /* VC Format */
1171 cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT;
1172 if (image_type == VIDEOSIZE_CIF) {
1173 cmd.buffer.registers[i++].value =
1174 (u8) (CPIA2_VC_VC_FORMAT_UFIRST |
1175 CPIA2_VC_VC_FORMAT_SHORTLINE);
1176 } else {
1177 cmd.buffer.registers[i++].value =
1178 (u8) CPIA2_VC_VC_FORMAT_UFIRST;
1179 }
1180
1181 /* VC Clocks */
1182 cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS;
1183 if (image_type == VIDEOSIZE_QCIF) {
1184 if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
1185 cmd.buffer.registers[i++].value=
1186 (u8)(CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 |
1187 CPIA2_VC_VC_672_CLOCKS_SCALING |
1188 CPIA2_VC_VC_CLOCKS_LOGDIV2);
1189 DBG("VC_Clocks (0xc4) should be B\n");
1190 }
1191 else {
1192 cmd.buffer.registers[i++].value=
1193 (u8)(CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 |
1194 CPIA2_VC_VC_CLOCKS_LOGDIV2);
1195 }
1196 } else {
1197 if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
1198 cmd.buffer.registers[i++].value =
1199 (u8) (CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 |
1200 CPIA2_VC_VC_CLOCKS_LOGDIV0);
1201 }
1202 else {
1203 cmd.buffer.registers[i++].value =
1204 (u8) (CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 |
1205 CPIA2_VC_VC_676_CLOCKS_SCALING |
1206 CPIA2_VC_VC_CLOCKS_LOGDIV0);
1207 }
1208 }
1209 DBG("VC_Clocks (0xc4) = 0x%0X\n", cmd.buffer.registers[i-1].value);
1210
1211 /* Input reqWidth from VC */
1212 cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO;
1213 if (image_type == VIDEOSIZE_QCIF)
1214 cmd.buffer.registers[i++].value =
1215 (u8) (STV_IMAGE_QCIF_COLS / 4);
1216 else
1217 cmd.buffer.registers[i++].value =
1218 (u8) (STV_IMAGE_CIF_COLS / 4);
1219
1220 /* Timings */
1221 cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI;
1222 if (image_type == VIDEOSIZE_QCIF)
1223 cmd.buffer.registers[i++].value = (u8) 0;
1224 else
1225 cmd.buffer.registers[i++].value = (u8) 1;
1226
1227 cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO;
1228 if (image_type == VIDEOSIZE_QCIF)
1229 cmd.buffer.registers[i++].value = (u8) 208;
1230 else
1231 cmd.buffer.registers[i++].value = (u8) 160;
1232
1233 cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI;
1234 if (image_type == VIDEOSIZE_QCIF)
1235 cmd.buffer.registers[i++].value = (u8) 0;
1236 else
1237 cmd.buffer.registers[i++].value = (u8) 1;
1238
1239 cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO;
1240 if (image_type == VIDEOSIZE_QCIF)
1241 cmd.buffer.registers[i++].value = (u8) 160;
1242 else
1243 cmd.buffer.registers[i++].value = (u8) 64;
1244
1245 /* Output Image Size */
1246 cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE;
1247 cmd.buffer.registers[i++].value = cam->params.roi.width / 4;
1248
1249 cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE;
1250 cmd.buffer.registers[i++].value = cam->params.roi.height / 4;
1251
1252 /* Cropping */
1253 cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP;
1254 if (image_type == VIDEOSIZE_QCIF)
1255 cmd.buffer.registers[i++].value =
1256 (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2);
1257 else
1258 cmd.buffer.registers[i++].value =
1259 (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2);
1260
1261 cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP;
1262 if (image_type == VIDEOSIZE_QCIF)
1263 cmd.buffer.registers[i++].value =
1264 (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2);
1265 else
1266 cmd.buffer.registers[i++].value =
1267 (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2);
1268
1269 /* Scaling registers (defaults) */
1270 cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE;
1271 cmd.buffer.registers[i++].value = (u8) 0;
1272
1273 cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE;
1274 cmd.buffer.registers[i++].value = (u8) 0;
1275
1276 cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN;
1277 cmd.buffer.registers[i++].value = (u8) 31;
1278
1279 cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN;
1280 cmd.buffer.registers[i++].value = (u8) 31;
1281
1282 cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP;
1283 cmd.buffer.registers[i++].value = (u8) 0;
1284
1285 cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP;
1286 cmd.buffer.registers[i++].value = (u8) 0;
1287
1288 cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT;
1289 cmd.buffer.registers[i++].value = (u8) 0x81; /* = 8/1 = 8 (HIBYTE/LOBYTE) */
1290
1291 cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT;
1292 cmd.buffer.registers[i++].value = (u8) 0x81; /* = 8/1 = 8 (HIBYTE/LOBYTE) */
1293
1294 cmd.reg_count = i;
1295
1296 cpia2_send_command(cam, &cmd);
1297
1298 return i;
1299}
1300
1301
1302/******************************************************************************
1303 *
1304 * config_sensor_500(cam)
1305 *
1306 *****************************************************************************/
1307static int config_sensor_500(struct camera_data *cam,
1308 int req_width, int req_height)
1309{
1310 struct cpia2_command cmd;
1311 int i = 0;
1312 int image_size = VIDEOSIZE_CIF;
1313 int image_type = VIDEOSIZE_VGA;
1314 int width = req_width;
1315 int height = req_height;
1316 unsigned int device = cam->params.pnp_id.device_type;
1317
1318 image_size = cpia2_match_video_size(width, height);
1319
1320 if (width > STV_IMAGE_CIF_COLS || height > STV_IMAGE_CIF_ROWS)
1321 image_type = VIDEOSIZE_VGA;
1322 else if (width > STV_IMAGE_QVGA_COLS || height > STV_IMAGE_QVGA_ROWS)
1323 image_type = VIDEOSIZE_CIF;
1324 else if (width > STV_IMAGE_QCIF_COLS || height > STV_IMAGE_QCIF_ROWS)
1325 image_type = VIDEOSIZE_QVGA;
1326 else
1327 image_type = VIDEOSIZE_QCIF;
1328
1329 if (image_size >= 0) {
1330 set_vw_size(cam, image_size);
1331 width = cam->params.roi.width;
1332 height = cam->params.roi.height;
1333 } else {
1334 ERR("ConfigSensor500 failed\n");
1335 return -EINVAL;
1336 }
1337
1338 DBG("image_size = %d, width = %d, height = %d, type = %d\n",
1339 image_size, width, height, image_type);
1340
1341 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
1342 cmd.direction = TRANSFER_WRITE;
1343 i = 0;
1344
1345 /* VC Format */
1346 cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT;
1347 cmd.buffer.registers[i].value = (u8) CPIA2_VC_VC_FORMAT_UFIRST;
1348 if (image_type == VIDEOSIZE_QCIF)
1349 cmd.buffer.registers[i].value |= (u8) CPIA2_VC_VC_FORMAT_DECIMATING;
1350 i++;
1351
1352 /* VC Clocks */
1353 cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS;
1354 if (device == DEVICE_STV_672) {
1355 if (image_type == VIDEOSIZE_VGA)
1356 cmd.buffer.registers[i].value =
1357 (u8)CPIA2_VC_VC_CLOCKS_LOGDIV1;
1358 else
1359 cmd.buffer.registers[i].value =
1360 (u8)(CPIA2_VC_VC_672_CLOCKS_SCALING |
1361 CPIA2_VC_VC_CLOCKS_LOGDIV3);
1362 } else {
1363 if (image_type == VIDEOSIZE_VGA)
1364 cmd.buffer.registers[i].value =
1365 (u8)CPIA2_VC_VC_CLOCKS_LOGDIV0;
1366 else
1367 cmd.buffer.registers[i].value =
1368 (u8)(CPIA2_VC_VC_676_CLOCKS_SCALING |
1369 CPIA2_VC_VC_CLOCKS_LOGDIV2);
1370 }
1371 i++;
1372
1373 DBG("VC_CLOCKS = 0x%X\n", cmd.buffer.registers[i-1].value);
1374
1375 /* Input width from VP */
1376 cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO;
1377 if (image_type == VIDEOSIZE_VGA)
1378 cmd.buffer.registers[i].value =
1379 (u8) (STV_IMAGE_VGA_COLS / 4);
1380 else
1381 cmd.buffer.registers[i].value =
1382 (u8) (STV_IMAGE_QVGA_COLS / 4);
1383 i++;
1384 DBG("Input width = %d\n", cmd.buffer.registers[i-1].value);
1385
1386 /* Timings */
1387 cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI;
1388 if (image_type == VIDEOSIZE_VGA)
1389 cmd.buffer.registers[i++].value = (u8) 2;
1390 else
1391 cmd.buffer.registers[i++].value = (u8) 1;
1392
1393 cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO;
1394 if (image_type == VIDEOSIZE_VGA)
1395 cmd.buffer.registers[i++].value = (u8) 250;
1396 else if (image_type == VIDEOSIZE_QVGA)
1397 cmd.buffer.registers[i++].value = (u8) 125;
1398 else
1399 cmd.buffer.registers[i++].value = (u8) 160;
1400
1401 cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI;
1402 if (image_type == VIDEOSIZE_VGA)
1403 cmd.buffer.registers[i++].value = (u8) 2;
1404 else
1405 cmd.buffer.registers[i++].value = (u8) 1;
1406
1407 cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO;
1408 if (image_type == VIDEOSIZE_VGA)
1409 cmd.buffer.registers[i++].value = (u8) 12;
1410 else if (image_type == VIDEOSIZE_QVGA)
1411 cmd.buffer.registers[i++].value = (u8) 64;
1412 else
1413 cmd.buffer.registers[i++].value = (u8) 6;
1414
1415 /* Output Image Size */
1416 cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE;
1417 if (image_type == VIDEOSIZE_QCIF)
1418 cmd.buffer.registers[i++].value = STV_IMAGE_CIF_COLS / 4;
1419 else
1420 cmd.buffer.registers[i++].value = width / 4;
1421
1422 cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE;
1423 if (image_type == VIDEOSIZE_QCIF)
1424 cmd.buffer.registers[i++].value = STV_IMAGE_CIF_ROWS / 4;
1425 else
1426 cmd.buffer.registers[i++].value = height / 4;
1427
1428 /* Cropping */
1429 cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP;
1430 if (image_type == VIDEOSIZE_VGA)
1431 cmd.buffer.registers[i++].value =
1432 (u8) (((STV_IMAGE_VGA_COLS / 4) - (width / 4)) / 2);
1433 else if (image_type == VIDEOSIZE_QVGA)
1434 cmd.buffer.registers[i++].value =
1435 (u8) (((STV_IMAGE_QVGA_COLS / 4) - (width / 4)) / 2);
1436 else if (image_type == VIDEOSIZE_CIF)
1437 cmd.buffer.registers[i++].value =
1438 (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2);
1439 else /*if (image_type == VIDEOSIZE_QCIF)*/
1440 cmd.buffer.registers[i++].value =
1441 (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2);
1442
1443 cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP;
1444 if (image_type == VIDEOSIZE_VGA)
1445 cmd.buffer.registers[i++].value =
1446 (u8) (((STV_IMAGE_VGA_ROWS / 4) - (height / 4)) / 2);
1447 else if (image_type == VIDEOSIZE_QVGA)
1448 cmd.buffer.registers[i++].value =
1449 (u8) (((STV_IMAGE_QVGA_ROWS / 4) - (height / 4)) / 2);
1450 else if (image_type == VIDEOSIZE_CIF)
1451 cmd.buffer.registers[i++].value =
1452 (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2);
1453 else /*if (image_type == VIDEOSIZE_QCIF)*/
1454 cmd.buffer.registers[i++].value =
1455 (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2);
1456
1457 /* Scaling registers (defaults) */
1458 cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE;
1459 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1460 cmd.buffer.registers[i++].value = (u8) 36;
1461 else
1462 cmd.buffer.registers[i++].value = (u8) 0;
1463
1464 cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE;
1465 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1466 cmd.buffer.registers[i++].value = (u8) 32;
1467 else
1468 cmd.buffer.registers[i++].value = (u8) 0;
1469
1470 cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN;
1471 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1472 cmd.buffer.registers[i++].value = (u8) 26;
1473 else
1474 cmd.buffer.registers[i++].value = (u8) 31;
1475
1476 cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN;
1477 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1478 cmd.buffer.registers[i++].value = (u8) 21;
1479 else
1480 cmd.buffer.registers[i++].value = (u8) 31;
1481
1482 cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP;
1483 cmd.buffer.registers[i++].value = (u8) 0;
1484
1485 cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP;
1486 cmd.buffer.registers[i++].value = (u8) 0;
1487
1488 cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT;
1489 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1490 cmd.buffer.registers[i++].value = (u8) 0x2B; /* 2/11 */
1491 else
1492 cmd.buffer.registers[i++].value = (u8) 0x81; /* 8/1 */
1493
1494 cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT;
1495 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1496 cmd.buffer.registers[i++].value = (u8) 0x13; /* 1/3 */
1497 else
1498 cmd.buffer.registers[i++].value = (u8) 0x81; /* 8/1 */
1499
1500 cmd.reg_count = i;
1501
1502 cpia2_send_command(cam, &cmd);
1503
1504 return i;
1505}
1506
1507
1508/******************************************************************************
1509 *
1510 * setallproperties
1511 *
1512 * This sets all user changeable properties to the values in cam->params.
1513 *****************************************************************************/
1514int set_all_properties(struct camera_data *cam)
1515{
1516 /**
1517 * Don't set target_kb here, it will be set later.
1518 * framerate and user_mode were already set (set_default_user_mode).
1519 **/
1520
1521 cpia2_set_color_params(cam);
1522
1523 cpia2_usb_change_streaming_alternate(cam,
1524 cam->params.camera_state.stream_mode);
1525
1526 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
1527 cam->params.vp_params.user_effects);
1528
1529 cpia2_set_flicker_mode(cam,
1530 cam->params.flicker_control.flicker_mode_req);
1531
1532 cpia2_do_command(cam,
1533 CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
1534 TRANSFER_WRITE, cam->params.vp_params.gpio_direction);
1535 cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, TRANSFER_WRITE,
1536 cam->params.vp_params.gpio_data);
1537
1538 wake_system(cam);
1539
1540 set_lowlight_boost(cam);
1541
1542 return 0;
1543}
1544
1545/******************************************************************************
1546 *
1547 * cpia2_save_camera_state
1548 *
1549 *****************************************************************************/
1550void cpia2_save_camera_state(struct camera_data *cam)
1551{
1552 get_color_params(cam);
1553 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
1554 cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, TRANSFER_READ,
1555 0);
1556 cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DATA, TRANSFER_READ, 0);
1557 /* Don't get framerate or target_kb. Trust the values we already have */
1558}
1559
1560/******************************************************************************
1561 *
1562 * get_color_params
1563 *
1564 *****************************************************************************/
1565void get_color_params(struct camera_data *cam)
1566{
1567 cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, TRANSFER_READ, 0);
1568 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, TRANSFER_READ, 0);
1569 cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST, TRANSFER_READ, 0);
1570}
1571
1572/******************************************************************************
1573 *
1574 * cpia2_set_color_params
1575 *
1576 *****************************************************************************/
1577void cpia2_set_color_params(struct camera_data *cam)
1578{
1579 DBG("Setting color params\n");
1580 cpia2_set_brightness(cam, cam->params.color_params.brightness);
1581 cpia2_set_contrast(cam, cam->params.color_params.contrast);
1582 cpia2_set_saturation(cam, cam->params.color_params.saturation);
1583}
1584
1585/******************************************************************************
1586 *
1587 * cpia2_set_flicker_mode
1588 *
1589 *****************************************************************************/
1590int cpia2_set_flicker_mode(struct camera_data *cam, int mode)
1591{
1592 unsigned char cam_reg;
1593 int err = 0;
1594
1595 if(cam->params.pnp_id.device_type != DEVICE_STV_672)
1596 return -EINVAL;
1597
1598 /* Set the appropriate bits in FLICKER_MODES, preserving the rest */
1599 if((err = cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES,
1600 TRANSFER_READ, 0)))
1601 return err;
1602 cam_reg = cam->params.flicker_control.cam_register;
1603
1604 switch(mode) {
1605 case NEVER_FLICKER:
1606 cam_reg |= CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
1607 cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ;
1608 break;
1609 case FLICKER_60:
1610 cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
1611 cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ;
1612 break;
1613 case FLICKER_50:
1614 cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
1615 cam_reg |= CPIA2_VP_FLICKER_MODES_50HZ;
1616 break;
1617 default:
1618 return -EINVAL;
1619 }
1620
1621 if((err = cpia2_do_command(cam, CPIA2_CMD_SET_FLICKER_MODES,
1622 TRANSFER_WRITE, cam_reg)))
1623 return err;
1624
1625 /* Set the appropriate bits in EXP_MODES, preserving the rest */
1626 if((err = cpia2_do_command(cam, CPIA2_CMD_GET_VP_EXP_MODES,
1627 TRANSFER_READ, 0)))
1628 return err;
1629 cam_reg = cam->params.vp_params.exposure_modes;
1630
1631 if (mode == NEVER_FLICKER) {
1632 cam_reg |= CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER;
1633 } else {
1634 cam_reg &= ~CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER;
1635 }
1636
1637 if((err = cpia2_do_command(cam, CPIA2_CMD_SET_VP_EXP_MODES,
1638 TRANSFER_WRITE, cam_reg)))
1639 return err;
1640
1641 if((err = cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4,
1642 TRANSFER_WRITE, 1)))
1643 return err;
1644
1645 switch(mode) {
1646 case NEVER_FLICKER:
1647 cam->params.flicker_control.flicker_mode_req = mode;
1648 break;
1649 case FLICKER_60:
1650 cam->params.flicker_control.flicker_mode_req = mode;
1651 cam->params.flicker_control.mains_frequency = 60;
1652 break;
1653 case FLICKER_50:
1654 cam->params.flicker_control.flicker_mode_req = mode;
1655 cam->params.flicker_control.mains_frequency = 50;
1656 break;
1657 default:
1658 err = -EINVAL;
1659 }
1660
1661 return err;
1662}
1663
1664/******************************************************************************
1665 *
1666 * cpia2_set_property_flip
1667 *
1668 *****************************************************************************/
1669void cpia2_set_property_flip(struct camera_data *cam, int prop_val)
1670{
1671 unsigned char cam_reg;
1672
1673 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
1674 cam_reg = cam->params.vp_params.user_effects;
1675
1676 if (prop_val)
1677 {
1678 cam_reg |= CPIA2_VP_USER_EFFECTS_FLIP;
1679 }
1680 else
1681 {
1682 cam_reg &= ~CPIA2_VP_USER_EFFECTS_FLIP;
1683 }
1684 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
1685 cam_reg);
1686}
1687
1688/******************************************************************************
1689 *
1690 * cpia2_set_property_mirror
1691 *
1692 *****************************************************************************/
1693void cpia2_set_property_mirror(struct camera_data *cam, int prop_val)
1694{
1695 unsigned char cam_reg;
1696
1697 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
1698 cam_reg = cam->params.vp_params.user_effects;
1699
1700 if (prop_val)
1701 {
1702 cam_reg |= CPIA2_VP_USER_EFFECTS_MIRROR;
1703 }
1704 else
1705 {
1706 cam_reg &= ~CPIA2_VP_USER_EFFECTS_MIRROR;
1707 }
1708 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
1709 cam_reg);
1710}
1711
1712/******************************************************************************
1713 *
1714 * set_target_kb
1715 *
1716 * The new Target KB is set in cam->params.vc_params.target_kb and
1717 * activates on reset.
1718 *****************************************************************************/
1719
1720int cpia2_set_target_kb(struct camera_data *cam, unsigned char value)
1721{
1722 DBG("Requested target_kb = %d\n", value);
1723 if (value != cam->params.vc_params.target_kb) {
1724
1725 cpia2_usb_stream_pause(cam);
1726
1727 /* reset camera for new target_kb */
1728 cam->params.vc_params.target_kb = value;
1729 cpia2_reset_camera(cam);
1730
1731 cpia2_usb_stream_resume(cam);
1732 }
1733
1734 return 0;
1735}
1736
1737/******************************************************************************
1738 *
1739 * cpia2_set_gpio
1740 *
1741 *****************************************************************************/
1742int cpia2_set_gpio(struct camera_data *cam, unsigned char setting)
1743{
1744 int ret;
1745
1746 /* Set the microport direction (register 0x90, should be defined
1747 * already) to 1 (user output), and set the microport data (0x91) to
1748 * the value in the ioctl argument.
1749 */
1750
1751 ret = cpia2_do_command(cam,
1752 CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
1753 CPIA2_VC_MP_DIR_OUTPUT,
1754 255);
1755 if (ret < 0)
1756 return ret;
1757 cam->params.vp_params.gpio_direction = 255;
1758
1759 ret = cpia2_do_command(cam,
1760 CPIA2_CMD_SET_VC_MP_GPIO_DATA,
1761 CPIA2_VC_MP_DIR_OUTPUT,
1762 setting);
1763 if (ret < 0)
1764 return ret;
1765 cam->params.vp_params.gpio_data = setting;
1766
1767 return 0;
1768}
1769
1770/******************************************************************************
1771 *
1772 * cpia2_set_fps
1773 *
1774 *****************************************************************************/
1775int cpia2_set_fps(struct camera_data *cam, int framerate)
1776{
1777 int retval;
1778
1779 switch(framerate) {
1780 case CPIA2_VP_FRAMERATE_30:
1781 case CPIA2_VP_FRAMERATE_25:
1782 if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
1783 cam->params.version.sensor_flags ==
1784 CPIA2_VP_SENSOR_FLAGS_500) {
1785 return -EINVAL;
1786 }
1787 /* Fall through */
1788 case CPIA2_VP_FRAMERATE_15:
1789 case CPIA2_VP_FRAMERATE_12_5:
1790 case CPIA2_VP_FRAMERATE_7_5:
1791 case CPIA2_VP_FRAMERATE_6_25:
1792 break;
1793 default:
1794 return -EINVAL;
1795 }
1796
1797 if (cam->params.pnp_id.device_type == DEVICE_STV_672 &&
1798 framerate == CPIA2_VP_FRAMERATE_15)
1799 framerate = 0; /* Work around bug in VP4 */
1800
1801 retval = cpia2_do_command(cam,
1802 CPIA2_CMD_FRAMERATE_REQ,
1803 TRANSFER_WRITE,
1804 framerate);
1805
1806 if(retval == 0)
1807 cam->params.vp_params.frame_rate = framerate;
1808
1809 return retval;
1810}
1811
1812/******************************************************************************
1813 *
1814 * cpia2_set_brightness
1815 *
1816 *****************************************************************************/
1817void cpia2_set_brightness(struct camera_data *cam, unsigned char value)
1818{
1819 /***
1820 * Don't let the register be set to zero - bug in VP4 - flash of full
1821 * brightness
1822 ***/
1823 if (cam->params.pnp_id.device_type == DEVICE_STV_672 && value == 0)
1824 value++;
1825 DBG("Setting brightness to %d (0x%0x)\n", value, value);
1826 cpia2_do_command(cam,CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE,value);
1827}
1828
1829/******************************************************************************
1830 *
1831 * cpia2_set_contrast
1832 *
1833 *****************************************************************************/
1834void cpia2_set_contrast(struct camera_data *cam, unsigned char value)
1835{
1836 DBG("Setting contrast to %d (0x%0x)\n", value, value);
1837 cam->params.color_params.contrast = value;
1838 cpia2_do_command(cam, CPIA2_CMD_SET_CONTRAST, TRANSFER_WRITE, value);
1839}
1840
1841/******************************************************************************
1842 *
1843 * cpia2_set_saturation
1844 *
1845 *****************************************************************************/
1846void cpia2_set_saturation(struct camera_data *cam, unsigned char value)
1847{
1848 DBG("Setting saturation to %d (0x%0x)\n", value, value);
1849 cam->params.color_params.saturation = value;
1850 cpia2_do_command(cam,CPIA2_CMD_SET_VP_SATURATION, TRANSFER_WRITE,value);
1851}
1852
1853/******************************************************************************
1854 *
1855 * wake_system
1856 *
1857 *****************************************************************************/
1858void wake_system(struct camera_data *cam)
1859{
1860 cpia2_do_command(cam, CPIA2_CMD_SET_WAKEUP, TRANSFER_WRITE, 0);
1861}
1862
1863/******************************************************************************
1864 *
1865 * set_lowlight_boost
1866 *
1867 * Valid for STV500 sensor only
1868 *****************************************************************************/
1869void set_lowlight_boost(struct camera_data *cam)
1870{
1871 struct cpia2_command cmd;
1872
1873 if (cam->params.pnp_id.device_type != DEVICE_STV_672 ||
1874 cam->params.version.sensor_flags != CPIA2_VP_SENSOR_FLAGS_500)
1875 return;
1876
1877 cmd.direction = TRANSFER_WRITE;
1878 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
1879 cmd.reg_count = 3;
1880 cmd.start = CPIA2_VP_RAM_ADDR_H;
1881
1882 cmd.buffer.block_data[0] = 0; /* High byte of address to write to */
1883 cmd.buffer.block_data[1] = 0x59; /* Low byte of address to write to */
1884 cmd.buffer.block_data[2] = 0; /* High byte of data to write */
1885
1886 cpia2_send_command(cam, &cmd);
1887
1888 if (cam->params.vp_params.lowlight_boost) {
1889 cmd.buffer.block_data[0] = 0x02; /* Low byte data to write */
1890 } else {
1891 cmd.buffer.block_data[0] = 0x06;
1892 }
1893 cmd.start = CPIA2_VP_RAM_DATA;
1894 cmd.reg_count = 1;
1895 cpia2_send_command(cam, &cmd);
1896
1897 /* Rehash the VP4 values */
1898 cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4, TRANSFER_WRITE, 1);
1899}
1900
1901/******************************************************************************
1902 *
1903 * cpia2_set_format
1904 *
1905 * Assumes that new size is already set in param struct.
1906 *****************************************************************************/
1907void cpia2_set_format(struct camera_data *cam)
1908{
1909 cam->flush = true;
1910
1911 cpia2_usb_stream_pause(cam);
1912
1913 /* reset camera to new size */
1914 cpia2_set_low_power(cam);
1915 cpia2_reset_camera(cam);
1916 cam->flush = false;
1917
1918 cpia2_dbg_dump_registers(cam);
1919
1920 cpia2_usb_stream_resume(cam);
1921}
1922
1923/******************************************************************************
1924 *
1925 * cpia2_dbg_dump_registers
1926 *
1927 *****************************************************************************/
1928void cpia2_dbg_dump_registers(struct camera_data *cam)
1929{
1930#ifdef _CPIA2_DEBUG_
1931 struct cpia2_command cmd;
1932
1933 if (!(debugs_on & DEBUG_DUMP_REGS))
1934 return;
1935
1936 cmd.direction = TRANSFER_READ;
1937
1938 /* Start with bank 0 (SYSTEM) */
1939 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
1940 cmd.reg_count = 3;
1941 cmd.start = 0;
1942 cpia2_send_command(cam, &cmd);
1943 printk(KERN_DEBUG "System Device Hi = 0x%X\n",
1944 cmd.buffer.block_data[0]);
1945 printk(KERN_DEBUG "System Device Lo = 0x%X\n",
1946 cmd.buffer.block_data[1]);
1947 printk(KERN_DEBUG "System_system control = 0x%X\n",
1948 cmd.buffer.block_data[2]);
1949
1950 /* Bank 1 (VC) */
1951 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
1952 cmd.reg_count = 4;
1953 cmd.start = 0x80;
1954 cpia2_send_command(cam, &cmd);
1955 printk(KERN_DEBUG "ASIC_ID = 0x%X\n",
1956 cmd.buffer.block_data[0]);
1957 printk(KERN_DEBUG "ASIC_REV = 0x%X\n",
1958 cmd.buffer.block_data[1]);
1959 printk(KERN_DEBUG "PW_CONTRL = 0x%X\n",
1960 cmd.buffer.block_data[2]);
1961 printk(KERN_DEBUG "WAKEUP = 0x%X\n",
1962 cmd.buffer.block_data[3]);
1963
1964 cmd.start = 0xA0; /* ST_CTRL */
1965 cmd.reg_count = 1;
1966 cpia2_send_command(cam, &cmd);
1967 printk(KERN_DEBUG "Stream ctrl = 0x%X\n",
1968 cmd.buffer.block_data[0]);
1969
1970 cmd.start = 0xA4; /* Stream status */
1971 cpia2_send_command(cam, &cmd);
1972 printk(KERN_DEBUG "Stream status = 0x%X\n",
1973 cmd.buffer.block_data[0]);
1974
1975 cmd.start = 0xA8; /* USB status */
1976 cmd.reg_count = 3;
1977 cpia2_send_command(cam, &cmd);
1978 printk(KERN_DEBUG "USB_CTRL = 0x%X\n",
1979 cmd.buffer.block_data[0]);
1980 printk(KERN_DEBUG "USB_STRM = 0x%X\n",
1981 cmd.buffer.block_data[1]);
1982 printk(KERN_DEBUG "USB_STATUS = 0x%X\n",
1983 cmd.buffer.block_data[2]);
1984
1985 cmd.start = 0xAF; /* USB settings */
1986 cmd.reg_count = 1;
1987 cpia2_send_command(cam, &cmd);
1988 printk(KERN_DEBUG "USB settings = 0x%X\n",
1989 cmd.buffer.block_data[0]);
1990
1991 cmd.start = 0xC0; /* VC stuff */
1992 cmd.reg_count = 26;
1993 cpia2_send_command(cam, &cmd);
1994 printk(KERN_DEBUG "VC Control = 0x%0X\n",
1995 cmd.buffer.block_data[0]);
1996 printk(KERN_DEBUG "VC Format = 0x%0X\n",
1997 cmd.buffer.block_data[3]);
1998 printk(KERN_DEBUG "VC Clocks = 0x%0X\n",
1999 cmd.buffer.block_data[4]);
2000 printk(KERN_DEBUG "VC IHSize = 0x%0X\n",
2001 cmd.buffer.block_data[5]);
2002 printk(KERN_DEBUG "VC Xlim Hi = 0x%0X\n",
2003 cmd.buffer.block_data[6]);
2004 printk(KERN_DEBUG "VC XLim Lo = 0x%0X\n",
2005 cmd.buffer.block_data[7]);
2006 printk(KERN_DEBUG "VC YLim Hi = 0x%0X\n",
2007 cmd.buffer.block_data[8]);
2008 printk(KERN_DEBUG "VC YLim Lo = 0x%0X\n",
2009 cmd.buffer.block_data[9]);
2010 printk(KERN_DEBUG "VC OHSize = 0x%0X\n",
2011 cmd.buffer.block_data[10]);
2012 printk(KERN_DEBUG "VC OVSize = 0x%0X\n",
2013 cmd.buffer.block_data[11]);
2014 printk(KERN_DEBUG "VC HCrop = 0x%0X\n",
2015 cmd.buffer.block_data[12]);
2016 printk(KERN_DEBUG "VC VCrop = 0x%0X\n",
2017 cmd.buffer.block_data[13]);
2018 printk(KERN_DEBUG "VC HPhase = 0x%0X\n",
2019 cmd.buffer.block_data[14]);
2020 printk(KERN_DEBUG "VC VPhase = 0x%0X\n",
2021 cmd.buffer.block_data[15]);
2022 printk(KERN_DEBUG "VC HIspan = 0x%0X\n",
2023 cmd.buffer.block_data[16]);
2024 printk(KERN_DEBUG "VC VIspan = 0x%0X\n",
2025 cmd.buffer.block_data[17]);
2026 printk(KERN_DEBUG "VC HiCrop = 0x%0X\n",
2027 cmd.buffer.block_data[18]);
2028 printk(KERN_DEBUG "VC ViCrop = 0x%0X\n",
2029 cmd.buffer.block_data[19]);
2030 printk(KERN_DEBUG "VC HiFract = 0x%0X\n",
2031 cmd.buffer.block_data[20]);
2032 printk(KERN_DEBUG "VC ViFract = 0x%0X\n",
2033 cmd.buffer.block_data[21]);
2034 printk(KERN_DEBUG "VC JPeg Opt = 0x%0X\n",
2035 cmd.buffer.block_data[22]);
2036 printk(KERN_DEBUG "VC Creep Per = 0x%0X\n",
2037 cmd.buffer.block_data[23]);
2038 printk(KERN_DEBUG "VC User Sq. = 0x%0X\n",
2039 cmd.buffer.block_data[24]);
2040 printk(KERN_DEBUG "VC Target KB = 0x%0X\n",
2041 cmd.buffer.block_data[25]);
2042
2043 /*** VP ***/
2044 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
2045 cmd.reg_count = 14;
2046 cmd.start = 0;
2047 cpia2_send_command(cam, &cmd);
2048
2049 printk(KERN_DEBUG "VP Dev Hi = 0x%0X\n",
2050 cmd.buffer.block_data[0]);
2051 printk(KERN_DEBUG "VP Dev Lo = 0x%0X\n",
2052 cmd.buffer.block_data[1]);
2053 printk(KERN_DEBUG "VP Sys State = 0x%0X\n",
2054 cmd.buffer.block_data[2]);
2055 printk(KERN_DEBUG "VP Sys Ctrl = 0x%0X\n",
2056 cmd.buffer.block_data[3]);
2057 printk(KERN_DEBUG "VP Sensor flg = 0x%0X\n",
2058 cmd.buffer.block_data[5]);
2059 printk(KERN_DEBUG "VP Sensor Rev = 0x%0X\n",
2060 cmd.buffer.block_data[6]);
2061 printk(KERN_DEBUG "VP Dev Config = 0x%0X\n",
2062 cmd.buffer.block_data[7]);
2063 printk(KERN_DEBUG "VP GPIO_DIR = 0x%0X\n",
2064 cmd.buffer.block_data[8]);
2065 printk(KERN_DEBUG "VP GPIO_DATA = 0x%0X\n",
2066 cmd.buffer.block_data[9]);
2067 printk(KERN_DEBUG "VP Ram ADDR H = 0x%0X\n",
2068 cmd.buffer.block_data[10]);
2069 printk(KERN_DEBUG "VP Ram ADDR L = 0x%0X\n",
2070 cmd.buffer.block_data[11]);
2071 printk(KERN_DEBUG "VP RAM Data = 0x%0X\n",
2072 cmd.buffer.block_data[12]);
2073 printk(KERN_DEBUG "Do Call = 0x%0X\n",
2074 cmd.buffer.block_data[13]);
2075
2076 if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
2077 cmd.reg_count = 9;
2078 cmd.start = 0x0E;
2079 cpia2_send_command(cam, &cmd);
2080 printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n",
2081 cmd.buffer.block_data[0]);
2082 printk(KERN_DEBUG "VP Patch Rev = 0x%0X\n",
2083 cmd.buffer.block_data[1]);
2084 printk(KERN_DEBUG "VP Vid Mode = 0x%0X\n",
2085 cmd.buffer.block_data[2]);
2086 printk(KERN_DEBUG "VP Framerate = 0x%0X\n",
2087 cmd.buffer.block_data[3]);
2088 printk(KERN_DEBUG "VP UserEffect = 0x%0X\n",
2089 cmd.buffer.block_data[4]);
2090 printk(KERN_DEBUG "VP White Bal = 0x%0X\n",
2091 cmd.buffer.block_data[5]);
2092 printk(KERN_DEBUG "VP WB thresh = 0x%0X\n",
2093 cmd.buffer.block_data[6]);
2094 printk(KERN_DEBUG "VP Exp Modes = 0x%0X\n",
2095 cmd.buffer.block_data[7]);
2096 printk(KERN_DEBUG "VP Exp Target = 0x%0X\n",
2097 cmd.buffer.block_data[8]);
2098
2099 cmd.reg_count = 1;
2100 cmd.start = 0x1B;
2101 cpia2_send_command(cam, &cmd);
2102 printk(KERN_DEBUG "VP FlickerMds = 0x%0X\n",
2103 cmd.buffer.block_data[0]);
2104 } else {
2105 cmd.reg_count = 8 ;
2106 cmd.start = 0x0E;
2107 cpia2_send_command(cam, &cmd);
2108 printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n",
2109 cmd.buffer.block_data[0]);
2110 printk(KERN_DEBUG "VP Patch Rev = 0x%0X\n",
2111 cmd.buffer.block_data[1]);
2112 printk(KERN_DEBUG "VP Vid Mode = 0x%0X\n",
2113 cmd.buffer.block_data[5]);
2114 printk(KERN_DEBUG "VP Framerate = 0x%0X\n",
2115 cmd.buffer.block_data[6]);
2116 printk(KERN_DEBUG "VP UserEffect = 0x%0X\n",
2117 cmd.buffer.block_data[7]);
2118
2119 cmd.reg_count = 1;
2120 cmd.start = CPIA2_VP5_EXPOSURE_TARGET;
2121 cpia2_send_command(cam, &cmd);
2122 printk(KERN_DEBUG "VP5 Exp Target= 0x%0X\n",
2123 cmd.buffer.block_data[0]);
2124
2125 cmd.reg_count = 4;
2126 cmd.start = 0x3A;
2127 cpia2_send_command(cam, &cmd);
2128 printk(KERN_DEBUG "VP5 MY Black = 0x%0X\n",
2129 cmd.buffer.block_data[0]);
2130 printk(KERN_DEBUG "VP5 MCY Range = 0x%0X\n",
2131 cmd.buffer.block_data[1]);
2132 printk(KERN_DEBUG "VP5 MYCEILING = 0x%0X\n",
2133 cmd.buffer.block_data[2]);
2134 printk(KERN_DEBUG "VP5 MCUV Sat = 0x%0X\n",
2135 cmd.buffer.block_data[3]);
2136 }
2137#endif
2138}
2139
2140/******************************************************************************
2141 *
2142 * reset_camera_struct
2143 *
2144 * Sets all values to the defaults
2145 *****************************************************************************/
2146void reset_camera_struct(struct camera_data *cam)
2147{
2148 /***
2149 * The following parameter values are the defaults from the register map.
2150 ***/
2151 cam->params.color_params.brightness = DEFAULT_BRIGHTNESS;
2152 cam->params.color_params.contrast = DEFAULT_CONTRAST;
2153 cam->params.color_params.saturation = DEFAULT_SATURATION;
2154 cam->params.vp_params.lowlight_boost = 0;
2155
2156 /* FlickerModes */
2157 cam->params.flicker_control.flicker_mode_req = NEVER_FLICKER;
2158 cam->params.flicker_control.mains_frequency = 60;
2159
2160 /* jpeg params */
2161 cam->params.compression.jpeg_options = CPIA2_VC_VC_JPEG_OPT_DEFAULT;
2162 cam->params.compression.creep_period = 2;
2163 cam->params.compression.user_squeeze = 20;
2164 cam->params.compression.inhibit_htables = false;
2165
2166 /* gpio params */
2167 cam->params.vp_params.gpio_direction = 0; /* write, the default safe mode */
2168 cam->params.vp_params.gpio_data = 0;
2169
2170 /* Target kb params */
2171 cam->params.vc_params.target_kb = DEFAULT_TARGET_KB;
2172
2173 /***
2174 * Set Sensor FPS as fast as possible.
2175 ***/
2176 if(cam->params.pnp_id.device_type == DEVICE_STV_672) {
2177 if(cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500)
2178 cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_15;
2179 else
2180 cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30;
2181 } else {
2182 cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30;
2183 }
2184
2185 /***
2186 * Set default video mode as large as possible :
2187 * for vga sensor set to vga, for cif sensor set to CIF.
2188 ***/
2189 if (cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500) {
2190 cam->sensor_type = CPIA2_SENSOR_500;
2191 cam->video_size = VIDEOSIZE_VGA;
2192 cam->params.roi.width = STV_IMAGE_VGA_COLS;
2193 cam->params.roi.height = STV_IMAGE_VGA_ROWS;
2194 } else {
2195 cam->sensor_type = CPIA2_SENSOR_410;
2196 cam->video_size = VIDEOSIZE_CIF;
2197 cam->params.roi.width = STV_IMAGE_CIF_COLS;
2198 cam->params.roi.height = STV_IMAGE_CIF_ROWS;
2199 }
2200
2201 /***
2202 * Fill in the v4l structures. video_cap is filled in inside the VIDIOCCAP
2203 * Ioctl. Here, just do the window and picture stucts.
2204 ***/
2205 cam->vp.palette = (u16) VIDEO_PALETTE_RGB24; /* Is this right? */
2206 cam->vp.brightness = (u16) cam->params.color_params.brightness * 256;
2207 cam->vp.colour = (u16) cam->params.color_params.saturation * 256;
2208 cam->vp.contrast = (u16) cam->params.color_params.contrast * 256;
2209
2210 cam->vw.x = 0;
2211 cam->vw.y = 0;
2212 cam->vw.width = cam->params.roi.width;
2213 cam->vw.height = cam->params.roi.height;
2214 cam->vw.flags = 0;
2215 cam->vw.clipcount = 0;
2216
2217 return;
2218}
2219
2220/******************************************************************************
2221 *
2222 * cpia2_init_camera_struct
2223 *
2224 * Initializes camera struct, does not call reset to fill in defaults.
2225 *****************************************************************************/
2226struct camera_data *cpia2_init_camera_struct(void)
2227{
2228 struct camera_data *cam;
2229
2230 cam = kmalloc(sizeof(*cam), GFP_KERNEL);
2231
2232 if (!cam) {
2233 ERR("couldn't kmalloc cpia2 struct\n");
2234 return NULL;
2235 }
2236
2237 /* Default everything to 0 */
2238 memset(cam, 0, sizeof(struct camera_data));
2239
2240 cam->present = 1;
2241 init_MUTEX(&cam->busy_lock);
2242 init_waitqueue_head(&cam->wq_stream);
2243
2244 return cam;
2245}
2246
2247/******************************************************************************
2248 *
2249 * cpia2_init_camera
2250 *
2251 * Initializes camera.
2252 *****************************************************************************/
2253int cpia2_init_camera(struct camera_data *cam)
2254{
2255 DBG("Start\n");
2256
2257 cam->mmapped = false;
2258
2259 /* Get sensor and asic types before reset. */
2260 cpia2_set_high_power(cam);
2261 cpia2_get_version_info(cam);
2262 if (cam->params.version.asic_id != CPIA2_ASIC_672) {
2263 ERR("Device IO error (asicID has incorrect value of 0x%X\n",
2264 cam->params.version.asic_id);
2265 return -ENODEV;
2266 }
2267
2268 /* Set GPIO direction and data to a safe state. */
2269 cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
2270 TRANSFER_WRITE, 0);
2271 cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA,
2272 TRANSFER_WRITE, 0);
2273
2274 /* resetting struct requires version info for sensor and asic types */
2275 reset_camera_struct(cam);
2276
2277 cpia2_set_low_power(cam);
2278
2279 DBG("End\n");
2280
2281 return 0;
2282}
2283
2284/******************************************************************************
2285 *
2286 * cpia2_allocate_buffers
2287 *
2288 *****************************************************************************/
2289int cpia2_allocate_buffers(struct camera_data *cam)
2290{
2291 int i;
2292
2293 if(!cam->buffers) {
2294 u32 size = cam->num_frames*sizeof(struct framebuf);
2295 cam->buffers = kmalloc(size, GFP_KERNEL);
2296 if(!cam->buffers) {
2297 ERR("couldn't kmalloc frame buffer structures\n");
2298 return -ENOMEM;
2299 }
2300 }
2301
2302 if(!cam->frame_buffer) {
2303 cam->frame_buffer = rvmalloc(cam->frame_size*cam->num_frames);
2304 if (!cam->frame_buffer) {
2305 ERR("couldn't vmalloc frame buffer data area\n");
2306 kfree(cam->buffers);
2307 cam->buffers = NULL;
2308 return -ENOMEM;
2309 }
2310 }
2311
2312 for(i=0; i<cam->num_frames-1; ++i) {
2313 cam->buffers[i].next = &cam->buffers[i+1];
2314 cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size;
2315 cam->buffers[i].status = FRAME_EMPTY;
2316 cam->buffers[i].length = 0;
2317 cam->buffers[i].max_length = 0;
2318 cam->buffers[i].num = i;
2319 }
2320 cam->buffers[i].next = cam->buffers;
2321 cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size;
2322 cam->buffers[i].status = FRAME_EMPTY;
2323 cam->buffers[i].length = 0;
2324 cam->buffers[i].max_length = 0;
2325 cam->buffers[i].num = i;
2326 cam->curbuff = cam->buffers;
2327 cam->workbuff = cam->curbuff->next;
2328 DBG("buffers=%p, curbuff=%p, workbuff=%p\n", cam->buffers, cam->curbuff,
2329 cam->workbuff);
2330 return 0;
2331}
2332
2333/******************************************************************************
2334 *
2335 * cpia2_free_buffers
2336 *
2337 *****************************************************************************/
2338void cpia2_free_buffers(struct camera_data *cam)
2339{
2340 if(cam->buffers) {
2341 kfree(cam->buffers);
2342 cam->buffers = NULL;
2343 }
2344 if(cam->frame_buffer) {
2345 rvfree(cam->frame_buffer, cam->frame_size*cam->num_frames);
2346 cam->frame_buffer = NULL;
2347 }
2348}
2349
2350/******************************************************************************
2351 *
2352 * cpia2_read
2353 *
2354 *****************************************************************************/
2355long cpia2_read(struct camera_data *cam,
2356 char __user *buf, unsigned long count, int noblock)
2357{
2358 struct framebuf *frame;
2359 if (!count) {
2360 return 0;
2361 }
2362
2363 if (!buf) {
2364 ERR("%s: buffer NULL\n",__FUNCTION__);
2365 return -EINVAL;
2366 }
2367
2368 if (!cam) {
2369 ERR("%s: Internal error, camera_data NULL!\n",__FUNCTION__);
2370 return -EINVAL;
2371 }
2372
2373 /* make this _really_ smp and multithread-safe */
2374 if (down_interruptible(&cam->busy_lock))
2375 return -ERESTARTSYS;
2376
2377 if (!cam->present) {
2378 LOG("%s: camera removed\n",__FUNCTION__);
2379 up(&cam->busy_lock);
2380 return 0; /* EOF */
2381 }
2382
2383 if(!cam->streaming) {
2384 /* Start streaming */
2385 cpia2_usb_stream_start(cam,
2386 cam->params.camera_state.stream_mode);
2387 }
2388
2389 /* Copy cam->curbuff in case it changes while we're processing */
2390 frame = cam->curbuff;
2391 if (noblock && frame->status != FRAME_READY) {
2392 up(&cam->busy_lock);
2393 return -EAGAIN;
2394 }
2395
2396 if(frame->status != FRAME_READY) {
2397 up(&cam->busy_lock);
2398 wait_event_interruptible(cam->wq_stream,
2399 !cam->present ||
2400 (frame = cam->curbuff)->status == FRAME_READY);
2401 if (signal_pending(current))
2402 return -ERESTARTSYS;
2403 /* make this _really_ smp and multithread-safe */
2404 if (down_interruptible(&cam->busy_lock)) {
2405 return -ERESTARTSYS;
2406 }
2407 if(!cam->present) {
2408 up(&cam->busy_lock);
2409 return 0;
2410 }
2411 }
2412
2413 /* copy data to user space */
2414 if (frame->length > count) {
2415 up(&cam->busy_lock);
2416 return -EFAULT;
2417 }
2418 if (copy_to_user(buf, frame->data, frame->length)) {
2419 up(&cam->busy_lock);
2420 return -EFAULT;
2421 }
2422
2423 count = frame->length;
2424
2425 frame->status = FRAME_EMPTY;
2426
2427 up(&cam->busy_lock);
2428 return count;
2429}
2430
2431/******************************************************************************
2432 *
2433 * cpia2_poll
2434 *
2435 *****************************************************************************/
2436unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
2437 poll_table *wait)
2438{
2439 unsigned int status=0;
2440
2441 if(!cam) {
2442 ERR("%s: Internal error, camera_data not found!\n",__FUNCTION__);
2443 return POLLERR;
2444 }
2445
2446 down(&cam->busy_lock);
2447
2448 if(!cam->present) {
2449 up(&cam->busy_lock);
2450 return POLLHUP;
2451 }
2452
2453 if(!cam->streaming) {
2454 /* Start streaming */
2455 cpia2_usb_stream_start(cam,
2456 cam->params.camera_state.stream_mode);
2457 }
2458
2459 up(&cam->busy_lock);
2460 poll_wait(filp, &cam->wq_stream, wait);
2461 down(&cam->busy_lock);
2462
2463 if(!cam->present)
2464 status = POLLHUP;
2465 else if(cam->curbuff->status == FRAME_READY)
2466 status = POLLIN | POLLRDNORM;
2467
2468 up(&cam->busy_lock);
2469 return status;
2470}
2471
2472/******************************************************************************
2473 *
2474 * cpia2_remap_buffer
2475 *
2476 *****************************************************************************/
2477int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
2478{
2479 const char *adr = (const char *)vma->vm_start;
2480 unsigned long size = vma->vm_end-vma->vm_start;
2481 unsigned long start_offset = vma->vm_pgoff << PAGE_SHIFT;
2482 unsigned long start = (unsigned long) adr;
2483 unsigned long page, pos;
2484
2485 if (!cam)
2486 return -ENODEV;
2487
2488 DBG("mmap offset:%ld size:%ld\n", start_offset, size);
2489
2490 /* make this _really_ smp-safe */
2491 if (down_interruptible(&cam->busy_lock))
2492 return -ERESTARTSYS;
2493
2494 if (!cam->present) {
2495 up(&cam->busy_lock);
2496 return -ENODEV;
2497 }
2498
2499 if (size > cam->frame_size*cam->num_frames ||
2500 (start_offset % cam->frame_size) != 0 ||
2501 (start_offset+size > cam->frame_size*cam->num_frames)) {
2502 up(&cam->busy_lock);
2503 return -EINVAL;
2504 }
2505
2506 pos = ((unsigned long) (cam->frame_buffer)) + start_offset;
2507 while (size > 0) {
2508 page = kvirt_to_pa(pos);
2509 if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) {
2510 up(&cam->busy_lock);
2511 return -EAGAIN;
2512 }
2513 start += PAGE_SIZE;
2514 pos += PAGE_SIZE;
2515 if (size > PAGE_SIZE)
2516 size -= PAGE_SIZE;
2517 else
2518 size = 0;
2519 }
2520
2521 cam->mmapped = true;
2522 up(&cam->busy_lock);
2523 return 0;
2524}
2525
diff --git a/drivers/media/video/cpia2/cpia2_registers.h b/drivers/media/video/cpia2/cpia2_registers.h
new file mode 100644
index 000000000000..3bbec514a967
--- /dev/null
+++ b/drivers/media/video/cpia2/cpia2_registers.h
@@ -0,0 +1,476 @@
1/****************************************************************************
2 *
3 * Filename: cpia2registers.h
4 *
5 * Copyright 2001, STMicrolectronics, Inc.
6 *
7 * Description:
8 * Definitions for the CPia2 register set
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License 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., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 ****************************************************************************/
25
26#ifndef CPIA2_REGISTER_HEADER
27#define CPIA2_REGISTER_HEADER
28
29/***
30 * System register set (Bank 0)
31 ***/
32#define CPIA2_SYSTEM_DEVICE_HI 0x00
33#define CPIA2_SYSTEM_DEVICE_LO 0x01
34
35#define CPIA2_SYSTEM_SYSTEM_CONTROL 0x02
36#define CPIA2_SYSTEM_CONTROL_LOW_POWER 0x00
37#define CPIA2_SYSTEM_CONTROL_HIGH_POWER 0x01
38#define CPIA2_SYSTEM_CONTROL_SUSPEND 0x02
39#define CPIA2_SYSTEM_CONTROL_V2W_ERR 0x10
40#define CPIA2_SYSTEM_CONTROL_RB_ERR 0x10
41#define CPIA2_SYSTEM_CONTROL_CLEAR_ERR 0x80
42
43#define CPIA2_SYSTEM_INT_PACKET_CTRL 0x04
44#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX 0x01
45#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_EOF 0x02
46#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_INT1 0x04
47
48#define CPIA2_SYSTEM_CACHE_CTRL 0x05
49#define CPIA2_SYSTEM_CACHE_CTRL_CACHE_RESET 0x01
50#define CPIA2_SYSTEM_CACHE_CTRL_CACHE_FLUSH 0x02
51
52#define CPIA2_SYSTEM_SERIAL_CTRL 0x06
53#define CPIA2_SYSTEM_SERIAL_CTRL_NULL_CMD 0x00
54#define CPIA2_SYSTEM_SERIAL_CTRL_START_CMD 0x01
55#define CPIA2_SYSTEM_SERIAL_CTRL_STOP_CMD 0x02
56#define CPIA2_SYSTEM_SERIAL_CTRL_WRITE_CMD 0x03
57#define CPIA2_SYSTEM_SERIAL_CTRL_READ_ACK_CMD 0x04
58#define CPIA2_SYSTEM_SERIAL_CTRL_READ_NACK_CMD 0x05
59
60#define CPIA2_SYSTEM_SERIAL_DATA 0x07
61
62#define CPIA2_SYSTEM_VP_SERIAL_ADDR 0x08
63
64/***
65 * I2C addresses for various devices in CPiA2
66 ***/
67#define CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR 0x20
68#define CPIA2_SYSTEM_VP_SERIAL_ADDR_VP 0x88
69#define CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP 0x8A
70
71#define CPIA2_SYSTEM_SPARE_REG1 0x09
72#define CPIA2_SYSTEM_SPARE_REG2 0x0A
73#define CPIA2_SYSTEM_SPARE_REG3 0x0B
74
75#define CPIA2_SYSTEM_MC_PORT_0 0x0C
76#define CPIA2_SYSTEM_MC_PORT_1 0x0D
77#define CPIA2_SYSTEM_MC_PORT_2 0x0E
78#define CPIA2_SYSTEM_MC_PORT_3 0x0F
79
80#define CPIA2_SYSTEM_STATUS_PKT 0x20
81#define CPIA2_SYSTEM_STATUS_PKT_END 0x27
82
83#define CPIA2_SYSTEM_DESCRIP_VID_HI 0x30
84#define CPIA2_SYSTEM_DESCRIP_VID_LO 0x31
85#define CPIA2_SYSTEM_DESCRIP_PID_HI 0x32
86#define CPIA2_SYSTEM_DESCRIP_PID_LO 0x33
87
88#define CPIA2_SYSTEM_FW_VERSION_HI 0x34
89#define CPIA2_SYSTEM_FW_VERSION_LO 0x35
90
91#define CPIA2_SYSTEM_CACHE_START_INDEX 0x80
92#define CPIA2_SYSTEM_CACHE_MAX_WRITES 0x10
93
94/***
95 * VC register set (Bank 1)
96 ***/
97#define CPIA2_VC_ASIC_ID 0x80
98
99#define CPIA2_VC_ASIC_REV 0x81
100
101#define CPIA2_VC_PW_CTRL 0x82
102#define CPIA2_VC_PW_CTRL_COLDSTART 0x01
103#define CPIA2_VC_PW_CTRL_CP_CLK_EN 0x02
104#define CPIA2_VC_PW_CTRL_VP_RESET_N 0x04
105#define CPIA2_VC_PW_CTRL_VC_CLK_EN 0x08
106#define CPIA2_VC_PW_CTRL_VC_RESET_N 0x10
107#define CPIA2_VC_PW_CTRL_GOTO_SUSPEND 0x20
108#define CPIA2_VC_PW_CTRL_UDC_SUSPEND 0x40
109#define CPIA2_VC_PW_CTRL_PWR_DOWN 0x80
110
111#define CPIA2_VC_WAKEUP 0x83
112#define CPIA2_VC_WAKEUP_SW_ENABLE 0x01
113#define CPIA2_VC_WAKEUP_XX_ENABLE 0x02
114#define CPIA2_VC_WAKEUP_SW_ATWAKEUP 0x04
115#define CPIA2_VC_WAKEUP_XX_ATWAKEUP 0x08
116
117#define CPIA2_VC_CLOCK_CTRL 0x84
118#define CPIA2_VC_CLOCK_CTRL_TESTUP72 0x01
119
120#define CPIA2_VC_INT_ENABLE 0x88
121#define CPIA2_VC_INT_ENABLE_XX_IE 0x01
122#define CPIA2_VC_INT_ENABLE_SW_IE 0x02
123#define CPIA2_VC_INT_ENABLE_VC_IE 0x04
124#define CPIA2_VC_INT_ENABLE_USBDATA_IE 0x08
125#define CPIA2_VC_INT_ENABLE_USBSETUP_IE 0x10
126#define CPIA2_VC_INT_ENABLE_USBCFG_IE 0x20
127
128#define CPIA2_VC_INT_FLAG 0x89
129#define CPIA2_VC_INT_ENABLE_XX_FLAG 0x01
130#define CPIA2_VC_INT_ENABLE_SW_FLAG 0x02
131#define CPIA2_VC_INT_ENABLE_VC_FLAG 0x04
132#define CPIA2_VC_INT_ENABLE_USBDATA_FLAG 0x08
133#define CPIA2_VC_INT_ENABLE_USBSETUP_FLAG 0x10
134#define CPIA2_VC_INT_ENABLE_USBCFG_FLAG 0x20
135#define CPIA2_VC_INT_ENABLE_SET_RESET_BIT 0x80
136
137#define CPIA2_VC_INT_STATE 0x8A
138#define CPIA2_VC_INT_STATE_XX_STATE 0x01
139#define CPIA2_VC_INT_STATE_SW_STATE 0x02
140
141#define CPIA2_VC_MP_DIR 0x90
142#define CPIA2_VC_MP_DIR_INPUT 0x00
143#define CPIA2_VC_MP_DIR_OUTPUT 0x01
144
145#define CPIA2_VC_MP_DATA 0x91
146
147#define CPIA2_VC_DP_CTRL 0x98
148#define CPIA2_VC_DP_CTRL_MODE_0 0x00
149#define CPIA2_VC_DP_CTRL_MODE_A 0x01
150#define CPIA2_VC_DP_CTRL_MODE_B 0x02
151#define CPIA2_VC_DP_CTRL_MODE_C 0x03
152#define CPIA2_VC_DP_CTRL_FAKE_FST 0x04
153
154#define CPIA2_VC_AD_CTRL 0x99
155#define CPIA2_VC_AD_CTRL_SRC_0 0x00
156#define CPIA2_VC_AD_CTRL_SRC_DIGI_A 0x01
157#define CPIA2_VC_AD_CTRL_SRC_REG 0x02
158#define CPIA2_VC_AD_CTRL_DST_USB 0x00
159#define CPIA2_VC_AD_CTRL_DST_REG 0x04
160
161#define CPIA2_VC_AD_TEST_IN 0x9B
162
163#define CPIA2_VC_AD_TEST_OUT 0x9C
164
165#define CPIA2_VC_AD_STATUS 0x9D
166#define CPIA2_VC_AD_STATUS_EMPTY 0x01
167#define CPIA2_VC_AD_STATUS_FULL 0x02
168
169#define CPIA2_VC_DP_DATA 0x9E
170
171#define CPIA2_VC_ST_CTRL 0xA0
172#define CPIA2_VC_ST_CTRL_SRC_VC 0x00
173#define CPIA2_VC_ST_CTRL_SRC_DP 0x01
174#define CPIA2_VC_ST_CTRL_SRC_REG 0x02
175
176#define CPIA2_VC_ST_CTRL_RAW_SELECT 0x04
177
178#define CPIA2_VC_ST_CTRL_DST_USB 0x00
179#define CPIA2_VC_ST_CTRL_DST_DP 0x08
180#define CPIA2_VC_ST_CTRL_DST_REG 0x10
181
182#define CPIA2_VC_ST_CTRL_FIFO_ENABLE 0x20
183#define CPIA2_VC_ST_CTRL_EOF_DETECT 0x40
184
185#define CPIA2_VC_ST_TEST 0xA1
186#define CPIA2_VC_ST_TEST_MODE_MANUAL 0x00
187#define CPIA2_VC_ST_TEST_MODE_INCREMENT 0x02
188
189#define CPIA2_VC_ST_TEST_AUTO_FILL 0x08
190
191#define CPIA2_VC_ST_TEST_REPEAT_FIFO 0x10
192
193#define CPIA2_VC_ST_TEST_IN 0xA2
194
195#define CPIA2_VC_ST_TEST_OUT 0xA3
196
197#define CPIA2_VC_ST_STATUS 0xA4
198#define CPIA2_VC_ST_STATUS_EMPTY 0x01
199#define CPIA2_VC_ST_STATUS_FULL 0x02
200
201#define CPIA2_VC_ST_FRAME_DETECT_1 0xA5
202
203#define CPIA2_VC_ST_FRAME_DETECT_2 0xA6
204
205#define CPIA2_VC_USB_CTRL 0xA8
206#define CPIA2_VC_USB_CTRL_CMD_STALLED 0x01
207#define CPIA2_VC_USB_CTRL_CMD_READY 0x02
208#define CPIA2_VC_USB_CTRL_CMD_STATUS 0x04
209#define CPIA2_VC_USB_CTRL_CMD_STATUS_DIR 0x08
210#define CPIA2_VC_USB_CTRL_CMD_NO_CLASH 0x10
211#define CPIA2_VC_USB_CTRL_CMD_MICRO_ACCESS 0x80
212
213#define CPIA2_VC_USB_STRM 0xA9
214#define CPIA2_VC_USB_STRM_ISO_ENABLE 0x01
215#define CPIA2_VC_USB_STRM_BLK_ENABLE 0x02
216#define CPIA2_VC_USB_STRM_INT_ENABLE 0x04
217#define CPIA2_VC_USB_STRM_AUD_ENABLE 0x08
218
219#define CPIA2_VC_USB_STATUS 0xAA
220#define CPIA2_VC_USB_STATUS_CMD_IN_PROGRESS 0x01
221#define CPIA2_VC_USB_STATUS_CMD_STATUS_STALL 0x02
222#define CPIA2_VC_USB_STATUS_CMD_HANDSHAKE 0x04
223#define CPIA2_VC_USB_STATUS_CMD_OVERRIDE 0x08
224#define CPIA2_VC_USB_STATUS_CMD_FIFO_BUSY 0x10
225#define CPIA2_VC_USB_STATUS_BULK_REPEAT_TXN 0x20
226#define CPIA2_VC_USB_STATUS_CONFIG_DONE 0x40
227#define CPIA2_VC_USB_STATUS_USB_SUSPEND 0x80
228
229#define CPIA2_VC_USB_CMDW 0xAB
230
231#define CPIA2_VC_USB_DATARW 0xAC
232
233#define CPIA2_VC_USB_INFO 0xAD
234
235#define CPIA2_VC_USB_CONFIG 0xAE
236
237#define CPIA2_VC_USB_SETTINGS 0xAF
238#define CPIA2_VC_USB_SETTINGS_CONFIG_MASK 0x03
239#define CPIA2_VC_USB_SETTINGS_INTERFACE_MASK 0x0C
240#define CPIA2_VC_USB_SETTINGS_ALTERNATE_MASK 0x70
241
242#define CPIA2_VC_USB_ISOLIM 0xB0
243
244#define CPIA2_VC_USB_ISOFAILS 0xB1
245
246#define CPIA2_VC_USB_ISOMAXPKTHI 0xB2
247
248#define CPIA2_VC_USB_ISOMAXPKTLO 0xB3
249
250#define CPIA2_VC_V2W_CTRL 0xB8
251#define CPIA2_VC_V2W_SELECT 0x01
252
253#define CPIA2_VC_V2W_SCL 0xB9
254
255#define CPIA2_VC_V2W_SDA 0xBA
256
257#define CPIA2_VC_VC_CTRL 0xC0
258#define CPIA2_VC_VC_CTRL_RUN 0x01
259#define CPIA2_VC_VC_CTRL_SINGLESHOT 0x02
260#define CPIA2_VC_VC_CTRL_IDLING 0x04
261#define CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES 0x10
262#define CPIA2_VC_VC_CTRL_INHIBIT_Q_TABLES 0x20
263#define CPIA2_VC_VC_CTRL_INHIBIT_PRIVATE 0x40
264
265#define CPIA2_VC_VC_RESTART_IVAL_HI 0xC1
266
267#define CPIA2_VC_VC_RESTART_IVAL_LO 0xC2
268
269#define CPIA2_VC_VC_FORMAT 0xC3
270#define CPIA2_VC_VC_FORMAT_UFIRST 0x01
271#define CPIA2_VC_VC_FORMAT_MONO 0x02
272#define CPIA2_VC_VC_FORMAT_DECIMATING 0x04
273#define CPIA2_VC_VC_FORMAT_SHORTLINE 0x08
274#define CPIA2_VC_VC_FORMAT_SELFTEST 0x10
275
276#define CPIA2_VC_VC_CLOCKS 0xC4
277#define CPIA2_VC_VC_CLOCKS_CLKDIV_MASK 0x03
278#define CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 0x04
279#define CPIA2_VC_VC_672_CLOCKS_SCALING 0x08
280#define CPIA2_VC_VC_CLOCKS_LOGDIV0 0x00
281#define CPIA2_VC_VC_CLOCKS_LOGDIV1 0x01
282#define CPIA2_VC_VC_CLOCKS_LOGDIV2 0x02
283#define CPIA2_VC_VC_CLOCKS_LOGDIV3 0x03
284#define CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 0x08
285#define CPIA2_VC_VC_676_CLOCKS_SCALING 0x10
286
287#define CPIA2_VC_VC_IHSIZE_LO 0xC5
288
289#define CPIA2_VC_VC_XLIM_HI 0xC6
290
291#define CPIA2_VC_VC_XLIM_LO 0xC7
292
293#define CPIA2_VC_VC_YLIM_HI 0xC8
294
295#define CPIA2_VC_VC_YLIM_LO 0xC9
296
297#define CPIA2_VC_VC_OHSIZE 0xCA
298
299#define CPIA2_VC_VC_OVSIZE 0xCB
300
301#define CPIA2_VC_VC_HCROP 0xCC
302
303#define CPIA2_VC_VC_VCROP 0xCD
304
305#define CPIA2_VC_VC_HPHASE 0xCE
306
307#define CPIA2_VC_VC_VPHASE 0xCF
308
309#define CPIA2_VC_VC_HISPAN 0xD0
310
311#define CPIA2_VC_VC_VISPAN 0xD1
312
313#define CPIA2_VC_VC_HICROP 0xD2
314
315#define CPIA2_VC_VC_VICROP 0xD3
316
317#define CPIA2_VC_VC_HFRACT 0xD4
318#define CPIA2_VC_VC_HFRACT_DEN_MASK 0x0F
319#define CPIA2_VC_VC_HFRACT_NUM_MASK 0xF0
320
321#define CPIA2_VC_VC_VFRACT 0xD5
322#define CPIA2_VC_VC_VFRACT_DEN_MASK 0x0F
323#define CPIA2_VC_VC_VFRACT_NUM_MASK 0xF0
324
325#define CPIA2_VC_VC_JPEG_OPT 0xD6
326#define CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE 0x01
327#define CPIA2_VC_VC_JPEG_OPT_NO_DC_AUTO_SQUEEZE 0x02
328#define CPIA2_VC_VC_JPEG_OPT_AUTO_SQUEEZE 0x04
329#define CPIA2_VC_VC_JPEG_OPT_DEFAULT (CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE|\
330 CPIA2_VC_VC_JPEG_OPT_AUTO_SQUEEZE)
331
332
333#define CPIA2_VC_VC_CREEP_PERIOD 0xD7
334#define CPIA2_VC_VC_USER_SQUEEZE 0xD8
335#define CPIA2_VC_VC_TARGET_KB 0xD9
336
337#define CPIA2_VC_VC_AUTO_SQUEEZE 0xE6
338
339
340/***
341 * VP register set (Bank 2)
342 ***/
343#define CPIA2_VP_DEVICEH 0
344#define CPIA2_VP_DEVICEL 1
345
346#define CPIA2_VP_SYSTEMSTATE 0x02
347#define CPIA2_VP_SYSTEMSTATE_HK_ALIVE 0x01
348
349#define CPIA2_VP_SYSTEMCTRL 0x03
350#define CPIA2_VP_SYSTEMCTRL_REQ_CLEAR_ERROR 0x80
351#define CPIA2_VP_SYSTEMCTRL_POWER_DOWN_PLL 0x20
352#define CPIA2_VP_SYSTEMCTRL_REQ_SUSPEND_STATE 0x10
353#define CPIA2_VP_SYSTEMCTRL_REQ_SERIAL_WAKEUP 0x08
354#define CPIA2_VP_SYSTEMCTRL_REQ_AUTOLOAD 0x04
355#define CPIA2_VP_SYSTEMCTRL_HK_CONTROL 0x02
356#define CPIA2_VP_SYSTEMCTRL_POWER_CONTROL 0x01
357
358#define CPIA2_VP_SENSOR_FLAGS 0x05
359#define CPIA2_VP_SENSOR_FLAGS_404 0x01
360#define CPIA2_VP_SENSOR_FLAGS_407 0x02
361#define CPIA2_VP_SENSOR_FLAGS_409 0x04
362#define CPIA2_VP_SENSOR_FLAGS_410 0x08
363#define CPIA2_VP_SENSOR_FLAGS_500 0x10
364
365#define CPIA2_VP_SENSOR_REV 0x06
366
367#define CPIA2_VP_DEVICE_CONFIG 0x07
368#define CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE 0x01
369
370#define CPIA2_VP_GPIO_DIRECTION 0x08
371#define CPIA2_VP_GPIO_READ 0xFF
372#define CPIA2_VP_GPIO_WRITE 0x00
373
374#define CPIA2_VP_GPIO_DATA 0x09
375
376#define CPIA2_VP_RAM_ADDR_H 0x0A
377#define CPIA2_VP_RAM_ADDR_L 0x0B
378#define CPIA2_VP_RAM_DATA 0x0C
379
380#define CPIA2_VP_PATCH_REV 0x0F
381
382#define CPIA2_VP4_USER_MODE 0x10
383#define CPIA2_VP5_USER_MODE 0x13
384#define CPIA2_VP_USER_MODE_CIF 0x01
385#define CPIA2_VP_USER_MODE_QCIFDS 0x02
386#define CPIA2_VP_USER_MODE_QCIFPTC 0x04
387#define CPIA2_VP_USER_MODE_QVGADS 0x08
388#define CPIA2_VP_USER_MODE_QVGAPTC 0x10
389#define CPIA2_VP_USER_MODE_VGA 0x20
390
391#define CPIA2_VP4_FRAMERATE_REQUEST 0x11
392#define CPIA2_VP5_FRAMERATE_REQUEST 0x14
393#define CPIA2_VP_FRAMERATE_60 0x80
394#define CPIA2_VP_FRAMERATE_50 0x40
395#define CPIA2_VP_FRAMERATE_30 0x20
396#define CPIA2_VP_FRAMERATE_25 0x10
397#define CPIA2_VP_FRAMERATE_15 0x08
398#define CPIA2_VP_FRAMERATE_12_5 0x04
399#define CPIA2_VP_FRAMERATE_7_5 0x02
400#define CPIA2_VP_FRAMERATE_6_25 0x01
401
402#define CPIA2_VP4_USER_EFFECTS 0x12
403#define CPIA2_VP5_USER_EFFECTS 0x15
404#define CPIA2_VP_USER_EFFECTS_COLBARS 0x01
405#define CPIA2_VP_USER_EFFECTS_COLBARS_GRAD 0x02
406#define CPIA2_VP_USER_EFFECTS_MIRROR 0x04
407#define CPIA2_VP_USER_EFFECTS_FLIP 0x40 // VP5 only
408
409/* NOTE: CPIA2_VP_EXPOSURE_MODES shares the same register as VP5 User
410 * Effects */
411#define CPIA2_VP_EXPOSURE_MODES 0x15
412#define CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER 0x20
413#define CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP 0x10
414
415#define CPIA2_VP4_EXPOSURE_TARGET 0x16 // VP4
416#define CPIA2_VP5_EXPOSURE_TARGET 0x20 // VP5
417
418#define CPIA2_VP_FLICKER_MODES 0x1B
419#define CPIA2_VP_FLICKER_MODES_50HZ 0x80
420#define CPIA2_VP_FLICKER_MODES_CUSTOM_FLT_FFREQ 0x40
421#define CPIA2_VP_FLICKER_MODES_NEVER_FLICKER 0x20
422#define CPIA2_VP_FLICKER_MODES_INHIBIT_RUB 0x10
423#define CPIA2_VP_FLICKER_MODES_ADJUST_LINE_FREQ 0x08
424#define CPIA2_VP_FLICKER_MODES_CUSTOM_INT_FFREQ 0x04
425
426#define CPIA2_VP_UMISC 0x1D
427#define CPIA2_VP_UMISC_FORCE_MONO 0x80
428#define CPIA2_VP_UMISC_FORCE_ID_MASK 0x40
429#define CPIA2_VP_UMISC_INHIBIT_AUTO_FGS 0x20
430#define CPIA2_VP_UMISC_INHIBIT_AUTO_DIMS 0x08
431#define CPIA2_VP_UMISC_OPT_FOR_SENSOR_DS 0x04
432#define CPIA2_VP_UMISC_INHIBIT_AUTO_MODE_INT 0x02
433
434#define CPIA2_VP5_ANTIFLKRSETUP 0x22 //34
435
436#define CPIA2_VP_INTERPOLATION 0x24
437#define CPIA2_VP_INTERPOLATION_EVEN_FIRST 0x40
438#define CPIA2_VP_INTERPOLATION_HJOG 0x20
439#define CPIA2_VP_INTERPOLATION_VJOG 0x10
440
441#define CPIA2_VP_GAMMA 0x25
442#define CPIA2_VP_DEFAULT_GAMMA 0x10
443
444#define CPIA2_VP_YRANGE 0x26
445
446#define CPIA2_VP_SATURATION 0x27
447
448#define CPIA2_VP5_MYBLACK_LEVEL 0x3A //58
449#define CPIA2_VP5_MCYRANGE 0x3B //59
450#define CPIA2_VP5_MYCEILING 0x3C //60
451#define CPIA2_VP5_MCUVSATURATION 0x3D //61
452
453
454#define CPIA2_VP_REHASH_VALUES 0x60
455
456
457/***
458 * Common sensor registers
459 ***/
460#define CPIA2_SENSOR_DEVICE_H 0x00
461#define CPIA2_SENSOR_DEVICE_L 0x01
462
463#define CPIA2_SENSOR_DATA_FORMAT 0x16
464#define CPIA2_SENSOR_DATA_FORMAT_HMIRROR 0x08
465#define CPIA2_SENSOR_DATA_FORMAT_VMIRROR 0x10
466
467#define CPIA2_SENSOR_CR1 0x76
468#define CPIA2_SENSOR_CR1_STAND_BY 0x01
469#define CPIA2_SENSOR_CR1_DOWN_RAMP_GEN 0x02
470#define CPIA2_SENSOR_CR1_DOWN_COLUMN_ADC 0x04
471#define CPIA2_SENSOR_CR1_DOWN_CAB_REGULATOR 0x08
472#define CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR 0x10
473#define CPIA2_SENSOR_CR1_DOWN_VRT_AMP 0x20
474#define CPIA2_SENSOR_CR1_DOWN_BAND_GAP 0x40
475
476#endif
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c
new file mode 100644
index 000000000000..f4da02941493
--- /dev/null
+++ b/drivers/media/video/cpia2/cpia2_usb.c
@@ -0,0 +1,907 @@
1/****************************************************************************
2 *
3 * Filename: cpia2_usb.c
4 *
5 * Copyright 2001, STMicrolectronics, Inc.
6 * Contact: steve.miller@st.com
7 *
8 * Description:
9 * This is a USB driver for CPia2 based video cameras.
10 * The infrastructure of this driver is based on the cpia usb driver by
11 * Jochen Scharrlach and Johannes Erdfeldt.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 * Stripped of 2.4 stuff ready for main kernel submit by
28 * Alan Cox <alan@redhat.com>
29 ****************************************************************************/
30
31#include <linux/kernel.h>
32#include <linux/slab.h>
33#include <linux/usb.h>
34
35#include "cpia2.h"
36
37static int frame_sizes[] = {
38 0, // USBIF_CMDONLY
39 0, // USBIF_BULK
40 128, // USBIF_ISO_1
41 384, // USBIF_ISO_2
42 640, // USBIF_ISO_3
43 768, // USBIF_ISO_4
44 896, // USBIF_ISO_5
45 1023, // USBIF_ISO_6
46};
47
48#define FRAMES_PER_DESC 10
49#define FRAME_SIZE_PER_DESC frame_sizes[cam->cur_alt]
50
51static void process_frame(struct camera_data *cam);
52static void cpia2_usb_complete(struct urb *urb, struct pt_regs *);
53static int cpia2_usb_probe(struct usb_interface *intf,
54 const struct usb_device_id *id);
55static void cpia2_usb_disconnect(struct usb_interface *intf);
56
57static void free_sbufs(struct camera_data *cam);
58static void add_APPn(struct camera_data *cam);
59static void add_COM(struct camera_data *cam);
60static int submit_urbs(struct camera_data *cam);
61static int set_alternate(struct camera_data *cam, unsigned int alt);
62static int configure_transfer_mode(struct camera_data *cam, unsigned int alt);
63
64static struct usb_device_id cpia2_id_table[] = {
65 {USB_DEVICE(0x0553, 0x0100)},
66 {USB_DEVICE(0x0553, 0x0140)},
67 {USB_DEVICE(0x0553, 0x0151)}, /* STV0676 */
68 {} /* Terminating entry */
69};
70MODULE_DEVICE_TABLE(usb, cpia2_id_table);
71
72static struct usb_driver cpia2_driver = {
73 .name = "cpia2",
74 .probe = cpia2_usb_probe,
75 .disconnect = cpia2_usb_disconnect,
76 .id_table = cpia2_id_table
77};
78
79
80/******************************************************************************
81 *
82 * process_frame
83 *
84 *****************************************************************************/
85static void process_frame(struct camera_data *cam)
86{
87 static int frame_count = 0;
88
89 unsigned char *inbuff = cam->workbuff->data;
90
91 DBG("Processing frame #%d, current:%d\n",
92 cam->workbuff->num, cam->curbuff->num);
93
94 if(cam->workbuff->length > cam->workbuff->max_length)
95 cam->workbuff->max_length = cam->workbuff->length;
96
97 if ((inbuff[0] == 0xFF) && (inbuff[1] == 0xD8)) {
98 frame_count++;
99 } else {
100 cam->workbuff->status = FRAME_ERROR;
101 DBG("Start of frame not found\n");
102 return;
103 }
104
105 /***
106 * Now the output buffer should have a JPEG image in it.
107 ***/
108 if(!cam->first_image_seen) {
109 /* Always skip the first image after streaming
110 * starts. It is almost certainly corrupt. */
111 cam->first_image_seen = 1;
112 cam->workbuff->status = FRAME_EMPTY;
113 return;
114 }
115 if (cam->workbuff->length > 3) {
116 if(cam->mmapped &&
117 cam->workbuff->length < cam->workbuff->max_length) {
118 /* No junk in the buffers */
119 memset(cam->workbuff->data+cam->workbuff->length,
120 0, cam->workbuff->max_length-
121 cam->workbuff->length);
122 }
123 cam->workbuff->max_length = cam->workbuff->length;
124 cam->workbuff->status = FRAME_READY;
125
126 if(!cam->mmapped && cam->num_frames > 2) {
127 /* During normal reading, the most recent
128 * frame will be read. If the current frame
129 * hasn't started reading yet, it will never
130 * be read, so mark it empty. If the buffer is
131 * mmapped, or we have few buffers, we need to
132 * wait for the user to free the buffer.
133 *
134 * NOTE: This is not entirely foolproof with 3
135 * buffers, but it would take an EXTREMELY
136 * overloaded system to cause problems (possible
137 * image data corruption). Basically, it would
138 * need to take more time to execute cpia2_read
139 * than it would for the camera to send
140 * cam->num_frames-2 frames before problems
141 * could occur.
142 */
143 cam->curbuff->status = FRAME_EMPTY;
144 }
145 cam->curbuff = cam->workbuff;
146 cam->workbuff = cam->workbuff->next;
147 DBG("Changed buffers, work:%d, current:%d\n",
148 cam->workbuff->num, cam->curbuff->num);
149 return;
150 } else {
151 DBG("Not enough data for an image.\n");
152 }
153
154 cam->workbuff->status = FRAME_ERROR;
155 return;
156}
157
158/******************************************************************************
159 *
160 * add_APPn
161 *
162 * Adds a user specified APPn record
163 *****************************************************************************/
164static void add_APPn(struct camera_data *cam)
165{
166 if(cam->APP_len > 0) {
167 cam->workbuff->data[cam->workbuff->length++] = 0xFF;
168 cam->workbuff->data[cam->workbuff->length++] = 0xE0+cam->APPn;
169 cam->workbuff->data[cam->workbuff->length++] = 0;
170 cam->workbuff->data[cam->workbuff->length++] = cam->APP_len+2;
171 memcpy(cam->workbuff->data+cam->workbuff->length,
172 cam->APP_data, cam->APP_len);
173 cam->workbuff->length += cam->APP_len;
174 }
175}
176
177/******************************************************************************
178 *
179 * add_COM
180 *
181 * Adds a user specified COM record
182 *****************************************************************************/
183static void add_COM(struct camera_data *cam)
184{
185 if(cam->COM_len > 0) {
186 cam->workbuff->data[cam->workbuff->length++] = 0xFF;
187 cam->workbuff->data[cam->workbuff->length++] = 0xFE;
188 cam->workbuff->data[cam->workbuff->length++] = 0;
189 cam->workbuff->data[cam->workbuff->length++] = cam->COM_len+2;
190 memcpy(cam->workbuff->data+cam->workbuff->length,
191 cam->COM_data, cam->COM_len);
192 cam->workbuff->length += cam->COM_len;
193 }
194}
195
196/******************************************************************************
197 *
198 * cpia2_usb_complete
199 *
200 * callback when incoming packet is received
201 *****************************************************************************/
202static void cpia2_usb_complete(struct urb *urb, struct pt_regs *regs)
203{
204 int i;
205 unsigned char *cdata;
206 static int frame_ready = false;
207 struct camera_data *cam = (struct camera_data *) urb->context;
208
209 if (urb->status!=0) {
210 if (!(urb->status == -ENOENT ||
211 urb->status == -ECONNRESET ||
212 urb->status == -ESHUTDOWN))
213 {
214 DBG("urb->status = %d!\n", urb->status);
215 }
216 DBG("Stopping streaming\n");
217 return;
218 }
219
220 if (!cam->streaming || !cam->present || cam->open_count == 0) {
221 LOG("Will now stop the streaming: streaming = %d, "
222 "present=%d, open_count=%d\n",
223 cam->streaming, cam->present, cam->open_count);
224 return;
225 }
226
227 /***
228 * Packet collater
229 ***/
230 //DBG("Collating %d packets\n", urb->number_of_packets);
231 for (i = 0; i < urb->number_of_packets; i++) {
232 u16 checksum, iso_checksum;
233 int j;
234 int n = urb->iso_frame_desc[i].actual_length;
235 int st = urb->iso_frame_desc[i].status;
236
237 if(cam->workbuff->status == FRAME_READY) {
238 struct framebuf *ptr;
239 /* Try to find an available buffer */
240 DBG("workbuff full, searching\n");
241 for (ptr = cam->workbuff->next;
242 ptr != cam->workbuff;
243 ptr = ptr->next)
244 {
245 if (ptr->status == FRAME_EMPTY) {
246 ptr->status = FRAME_READING;
247 ptr->length = 0;
248 break;
249 }
250 }
251 if (ptr == cam->workbuff)
252 break; /* No READING or EMPTY buffers left */
253
254 cam->workbuff = ptr;
255 }
256
257 if (cam->workbuff->status == FRAME_EMPTY ||
258 cam->workbuff->status == FRAME_ERROR) {
259 cam->workbuff->status = FRAME_READING;
260 cam->workbuff->length = 0;
261 }
262
263 //DBG(" Packet %d length = %d, status = %d\n", i, n, st);
264 cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
265
266 if (st) {
267 LOG("cpia2 data error: [%d] len=%d, status = %d\n",
268 i, n, st);
269 if(!ALLOW_CORRUPT)
270 cam->workbuff->status = FRAME_ERROR;
271 continue;
272 }
273
274 if(n<=2)
275 continue;
276
277 checksum = 0;
278 for(j=0; j<n-2; ++j)
279 checksum += cdata[j];
280 iso_checksum = cdata[j] + cdata[j+1]*256;
281 if(checksum != iso_checksum) {
282 LOG("checksum mismatch: [%d] len=%d, calculated = %x, checksum = %x\n",
283 i, n, (int)checksum, (int)iso_checksum);
284 if(!ALLOW_CORRUPT) {
285 cam->workbuff->status = FRAME_ERROR;
286 continue;
287 }
288 }
289 n -= 2;
290
291 if(cam->workbuff->status != FRAME_READING) {
292 if((0xFF == cdata[0] && 0xD8 == cdata[1]) ||
293 (0xD8 == cdata[0] && 0xFF == cdata[1] &&
294 0 != cdata[2])) {
295 /* frame is skipped, but increment total
296 * frame count anyway */
297 cam->frame_count++;
298 }
299 DBG("workbuff not reading, status=%d\n",
300 cam->workbuff->status);
301 continue;
302 }
303
304 if (cam->frame_size < cam->workbuff->length + n) {
305 ERR("buffer overflow! length: %d, n: %d\n",
306 cam->workbuff->length, n);
307 cam->workbuff->status = FRAME_ERROR;
308 if(cam->workbuff->length > cam->workbuff->max_length)
309 cam->workbuff->max_length =
310 cam->workbuff->length;
311 continue;
312 }
313
314 if (cam->workbuff->length == 0) {
315 int data_offset;
316 if ((0xD8 == cdata[0]) && (0xFF == cdata[1])) {
317 data_offset = 1;
318 } else if((0xFF == cdata[0]) && (0xD8 == cdata[1])
319 && (0xFF == cdata[2])) {
320 data_offset = 2;
321 } else {
322 DBG("Ignoring packet, not beginning!\n");
323 continue;
324 }
325 DBG("Start of frame pattern found\n");
326 do_gettimeofday(&cam->workbuff->timestamp);
327 cam->workbuff->seq = cam->frame_count++;
328 cam->workbuff->data[0] = 0xFF;
329 cam->workbuff->data[1] = 0xD8;
330 cam->workbuff->length = 2;
331 add_APPn(cam);
332 add_COM(cam);
333 memcpy(cam->workbuff->data+cam->workbuff->length,
334 cdata+data_offset, n-data_offset);
335 cam->workbuff->length += n-data_offset;
336 } else if (cam->workbuff->length > 0) {
337 memcpy(cam->workbuff->data + cam->workbuff->length,
338 cdata, n);
339 cam->workbuff->length += n;
340 }
341
342 if ((cam->workbuff->length >= 3) &&
343 (cam->workbuff->data[cam->workbuff->length - 3] == 0xFF) &&
344 (cam->workbuff->data[cam->workbuff->length - 2] == 0xD9) &&
345 (cam->workbuff->data[cam->workbuff->length - 1] == 0xFF)) {
346 frame_ready = true;
347 cam->workbuff->data[cam->workbuff->length - 1] = 0;
348 cam->workbuff->length -= 1;
349 } else if ((cam->workbuff->length >= 2) &&
350 (cam->workbuff->data[cam->workbuff->length - 2] == 0xFF) &&
351 (cam->workbuff->data[cam->workbuff->length - 1] == 0xD9)) {
352 frame_ready = true;
353 }
354
355 if (frame_ready) {
356 DBG("Workbuff image size = %d\n",cam->workbuff->length);
357 process_frame(cam);
358
359 frame_ready = false;
360
361 if (waitqueue_active(&cam->wq_stream))
362 wake_up_interruptible(&cam->wq_stream);
363 }
364 }
365
366 if(cam->streaming) {
367 /* resubmit */
368 urb->dev = cam->dev;
369 if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0)
370 ERR("%s: usb_submit_urb ret %d!\n", __func__, i);
371 }
372}
373
374/******************************************************************************
375 *
376 * configure_transfer_mode
377 *
378 *****************************************************************************/
379static int configure_transfer_mode(struct camera_data *cam, unsigned int alt)
380{
381 static unsigned char iso_regs[8][4] = {
382 {0x00, 0x00, 0x00, 0x00},
383 {0x00, 0x00, 0x00, 0x00},
384 {0xB9, 0x00, 0x00, 0x7E},
385 {0xB9, 0x00, 0x01, 0x7E},
386 {0xB9, 0x00, 0x02, 0x7E},
387 {0xB9, 0x00, 0x02, 0xFE},
388 {0xB9, 0x00, 0x03, 0x7E},
389 {0xB9, 0x00, 0x03, 0xFD}
390 };
391 struct cpia2_command cmd;
392 unsigned char reg;
393
394 if(!cam->present)
395 return -ENODEV;
396
397 /***
398 * Write the isoc registers according to the alternate selected
399 ***/
400 cmd.direction = TRANSFER_WRITE;
401 cmd.buffer.block_data[0] = iso_regs[alt][0];
402 cmd.buffer.block_data[1] = iso_regs[alt][1];
403 cmd.buffer.block_data[2] = iso_regs[alt][2];
404 cmd.buffer.block_data[3] = iso_regs[alt][3];
405 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
406 cmd.start = CPIA2_VC_USB_ISOLIM;
407 cmd.reg_count = 4;
408 cpia2_send_command(cam, &cmd);
409
410 /***
411 * Enable relevant streams before starting polling.
412 * First read USB Stream Config Register.
413 ***/
414 cmd.direction = TRANSFER_READ;
415 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
416 cmd.start = CPIA2_VC_USB_STRM;
417 cmd.reg_count = 1;
418 cpia2_send_command(cam, &cmd);
419 reg = cmd.buffer.block_data[0];
420
421 /* Clear iso, bulk, and int */
422 reg &= ~(CPIA2_VC_USB_STRM_BLK_ENABLE |
423 CPIA2_VC_USB_STRM_ISO_ENABLE |
424 CPIA2_VC_USB_STRM_INT_ENABLE);
425
426 if (alt == USBIF_BULK) {
427 DBG("Enabling bulk xfer\n");
428 reg |= CPIA2_VC_USB_STRM_BLK_ENABLE; /* Enable Bulk */
429 cam->xfer_mode = XFER_BULK;
430 } else if (alt >= USBIF_ISO_1) {
431 DBG("Enabling ISOC xfer\n");
432 reg |= CPIA2_VC_USB_STRM_ISO_ENABLE;
433 cam->xfer_mode = XFER_ISOC;
434 }
435
436 cmd.buffer.block_data[0] = reg;
437 cmd.direction = TRANSFER_WRITE;
438 cmd.start = CPIA2_VC_USB_STRM;
439 cmd.reg_count = 1;
440 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
441 cpia2_send_command(cam, &cmd);
442
443 return 0;
444}
445
446/******************************************************************************
447 *
448 * cpia2_usb_change_streaming_alternate
449 *
450 *****************************************************************************/
451int cpia2_usb_change_streaming_alternate(struct camera_data *cam,
452 unsigned int alt)
453{
454 int ret = 0;
455
456 if(alt < USBIF_ISO_1 || alt > USBIF_ISO_6)
457 return -EINVAL;
458
459 if(alt == cam->params.camera_state.stream_mode)
460 return 0;
461
462 cpia2_usb_stream_pause(cam);
463
464 configure_transfer_mode(cam, alt);
465
466 cam->params.camera_state.stream_mode = alt;
467
468 /* Reset the camera to prevent image quality degradation */
469 cpia2_reset_camera(cam);
470
471 cpia2_usb_stream_resume(cam);
472
473 return ret;
474}
475
476/******************************************************************************
477 *
478 * set_alternate
479 *
480 *****************************************************************************/
481int set_alternate(struct camera_data *cam, unsigned int alt)
482{
483 int ret = 0;
484
485 if(alt == cam->cur_alt)
486 return 0;
487
488 if (cam->cur_alt != USBIF_CMDONLY) {
489 DBG("Changing from alt %d to %d\n", cam->cur_alt, USBIF_CMDONLY);
490 ret = usb_set_interface(cam->dev, cam->iface, USBIF_CMDONLY);
491 if (ret != 0)
492 return ret;
493 }
494 if (alt != USBIF_CMDONLY) {
495 DBG("Changing from alt %d to %d\n", USBIF_CMDONLY, alt);
496 ret = usb_set_interface(cam->dev, cam->iface, alt);
497 if (ret != 0)
498 return ret;
499 }
500
501 cam->old_alt = cam->cur_alt;
502 cam->cur_alt = alt;
503
504 return ret;
505}
506
507/******************************************************************************
508 *
509 * free_sbufs
510 *
511 * Free all cam->sbuf[]. All non-NULL .data and .urb members that are non-NULL
512 * are assumed to be allocated. Non-NULL .urb members are also assumed to be
513 * submitted (and must therefore be killed before they are freed).
514 *****************************************************************************/
515static void free_sbufs(struct camera_data *cam)
516{
517 int i;
518
519 for (i = 0; i < NUM_SBUF; i++) {
520 if(cam->sbuf[i].urb) {
521 usb_kill_urb(cam->sbuf[i].urb);
522 usb_free_urb(cam->sbuf[i].urb);
523 cam->sbuf[i].urb = NULL;
524 }
525 if(cam->sbuf[i].data) {
526 kfree(cam->sbuf[i].data);
527 cam->sbuf[i].data = NULL;
528 }
529 }
530}
531
532/*******
533* Convenience functions
534*******/
535/****************************************************************************
536 *
537 * write_packet
538 *
539 ***************************************************************************/
540static int write_packet(struct usb_device *udev,
541 u8 request, u8 * registers, u16 start, size_t size)
542{
543 if (!registers || size <= 0)
544 return -EINVAL;
545
546 return usb_control_msg(udev,
547 usb_sndctrlpipe(udev, 0),
548 request,
549 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
550 start, /* value */
551 0, /* index */
552 registers, /* buffer */
553 size,
554 HZ);
555}
556
557/****************************************************************************
558 *
559 * read_packet
560 *
561 ***************************************************************************/
562static int read_packet(struct usb_device *udev,
563 u8 request, u8 * registers, u16 start, size_t size)
564{
565 if (!registers || size <= 0)
566 return -EINVAL;
567
568 return usb_control_msg(udev,
569 usb_rcvctrlpipe(udev, 0),
570 request,
571 USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
572 start, /* value */
573 0, /* index */
574 registers, /* buffer */
575 size,
576 HZ);
577}
578
579/******************************************************************************
580 *
581 * cpia2_usb_transfer_cmd
582 *
583 *****************************************************************************/
584int cpia2_usb_transfer_cmd(struct camera_data *cam,
585 void *registers,
586 u8 request, u8 start, u8 count, u8 direction)
587{
588 int err = 0;
589 struct usb_device *udev = cam->dev;
590
591 if (!udev) {
592 ERR("%s: Internal driver error: udev is NULL\n", __func__);
593 return -EINVAL;
594 }
595
596 if (!registers) {
597 ERR("%s: Internal driver error: register array is NULL\n", __func__);
598 return -EINVAL;
599 }
600
601 if (direction == TRANSFER_READ) {
602 err = read_packet(udev, request, (u8 *)registers, start, count);
603 if (err > 0)
604 err = 0;
605 } else if (direction == TRANSFER_WRITE) {
606 err =write_packet(udev, request, (u8 *)registers, start, count);
607 if (err < 0) {
608 LOG("Control message failed, err val = %d\n", err);
609 LOG("Message: request = 0x%0X, start = 0x%0X\n",
610 request, start);
611 LOG("Message: count = %d, register[0] = 0x%0X\n",
612 count, ((unsigned char *) registers)[0]);
613 } else
614 err=0;
615 } else {
616 LOG("Unexpected first byte of direction: %d\n",
617 direction);
618 return -EINVAL;
619 }
620
621 if(err != 0)
622 LOG("Unexpected error: %d\n", err);
623 return err;
624}
625
626
627/******************************************************************************
628 *
629 * submit_urbs
630 *
631 *****************************************************************************/
632static int submit_urbs(struct camera_data *cam)
633{
634 struct urb *urb;
635 int fx, err, i;
636
637 for(i=0; i<NUM_SBUF; ++i) {
638 if (cam->sbuf[i].data)
639 continue;
640 cam->sbuf[i].data =
641 kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
642 if (!cam->sbuf[i].data) {
643 return -ENOMEM;
644 }
645 }
646
647 /* We double buffer the Isoc lists, and also know the polling
648 * interval is every frame (1 == (1 << (bInterval -1))).
649 */
650 for(i=0; i<NUM_SBUF; ++i) {
651 if(cam->sbuf[i].urb) {
652 continue;
653 }
654 urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
655 if (!urb) {
656 return -ENOMEM;
657 }
658
659 cam->sbuf[i].urb = urb;
660 urb->dev = cam->dev;
661 urb->context = cam;
662 urb->pipe = usb_rcvisocpipe(cam->dev, 1 /*ISOC endpoint*/);
663 urb->transfer_flags = URB_ISO_ASAP;
664 urb->transfer_buffer = cam->sbuf[i].data;
665 urb->complete = cpia2_usb_complete;
666 urb->number_of_packets = FRAMES_PER_DESC;
667 urb->interval = 1;
668 urb->transfer_buffer_length =
669 FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
670
671 for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
672 urb->iso_frame_desc[fx].offset =
673 FRAME_SIZE_PER_DESC * fx;
674 urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
675 }
676 }
677
678
679 /* Queue the ISO urbs, and resubmit in the completion handler */
680 for(i=0; i<NUM_SBUF; ++i) {
681 err = usb_submit_urb(cam->sbuf[i].urb, GFP_KERNEL);
682 if (err) {
683 ERR("usb_submit_urb[%d]() = %d\n", i, err);
684 return err;
685 }
686 }
687
688 return 0;
689}
690
691/******************************************************************************
692 *
693 * cpia2_usb_stream_start
694 *
695 *****************************************************************************/
696int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate)
697{
698 int ret;
699 int old_alt;
700
701 if(cam->streaming)
702 return 0;
703
704 if (cam->flush) {
705 int i;
706 DBG("Flushing buffers\n");
707 for(i=0; i<cam->num_frames; ++i) {
708 cam->buffers[i].status = FRAME_EMPTY;
709 cam->buffers[i].length = 0;
710 }
711 cam->curbuff = &cam->buffers[0];
712 cam->workbuff = cam->curbuff->next;
713 cam->flush = false;
714 }
715
716 old_alt = cam->params.camera_state.stream_mode;
717 cam->params.camera_state.stream_mode = 0;
718 ret = cpia2_usb_change_streaming_alternate(cam, alternate);
719 if (ret < 0) {
720 int ret2;
721 ERR("cpia2_usb_change_streaming_alternate() = %d!\n", ret);
722 cam->params.camera_state.stream_mode = old_alt;
723 ret2 = set_alternate(cam, USBIF_CMDONLY);
724 if (ret2 < 0) {
725 ERR("cpia2_usb_change_streaming_alternate(%d) =%d has already "
726 "failed. Then tried to call "
727 "set_alternate(USBIF_CMDONLY) = %d.\n",
728 alternate, ret, ret2);
729 }
730 } else {
731 cam->frame_count = 0;
732 cam->streaming = 1;
733 ret = cpia2_usb_stream_resume(cam);
734 }
735 return ret;
736}
737
738/******************************************************************************
739 *
740 * cpia2_usb_stream_pause
741 *
742 *****************************************************************************/
743int cpia2_usb_stream_pause(struct camera_data *cam)
744{
745 int ret = 0;
746 if(cam->streaming) {
747 ret = set_alternate(cam, USBIF_CMDONLY);
748 free_sbufs(cam);
749 }
750 return ret;
751}
752
753/******************************************************************************
754 *
755 * cpia2_usb_stream_resume
756 *
757 *****************************************************************************/
758int cpia2_usb_stream_resume(struct camera_data *cam)
759{
760 int ret = 0;
761 if(cam->streaming) {
762 cam->first_image_seen = 0;
763 ret = set_alternate(cam, cam->params.camera_state.stream_mode);
764 if(ret == 0) {
765 ret = submit_urbs(cam);
766 }
767 }
768 return ret;
769}
770
771/******************************************************************************
772 *
773 * cpia2_usb_stream_stop
774 *
775 *****************************************************************************/
776int cpia2_usb_stream_stop(struct camera_data *cam)
777{
778 int ret;
779 ret = cpia2_usb_stream_pause(cam);
780 cam->streaming = 0;
781 configure_transfer_mode(cam, 0);
782 return ret;
783}
784
785/******************************************************************************
786 *
787 * cpia2_usb_probe
788 *
789 * Probe and initialize.
790 *****************************************************************************/
791static int cpia2_usb_probe(struct usb_interface *intf,
792 const struct usb_device_id *id)
793{
794 struct usb_device *udev = interface_to_usbdev(intf);
795 struct usb_interface_descriptor *interface;
796 struct camera_data *cam;
797 int ret;
798
799 /* A multi-config CPiA2 camera? */
800 if (udev->descriptor.bNumConfigurations != 1)
801 return -ENODEV;
802 interface = &intf->cur_altsetting->desc;
803
804 /* If we get to this point, we found a CPiA2 camera */
805 LOG("CPiA2 USB camera found\n");
806
807 if((cam = cpia2_init_camera_struct()) == NULL)
808 return -ENOMEM;
809
810 cam->dev = udev;
811 cam->iface = interface->bInterfaceNumber;
812
813 ret = set_alternate(cam, USBIF_CMDONLY);
814 if (ret < 0) {
815 ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret);
816 kfree(cam);
817 return ret;
818 }
819
820 if ((ret = cpia2_register_camera(cam)) < 0) {
821 ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret);
822 kfree(cam);
823 return ret;
824 }
825
826
827 if((ret = cpia2_init_camera(cam)) < 0) {
828 ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret);
829 cpia2_unregister_camera(cam);
830 kfree(cam);
831 return ret;
832 }
833 LOG(" CPiA Version: %d.%02d (%d.%d)\n",
834 cam->params.version.firmware_revision_hi,
835 cam->params.version.firmware_revision_lo,
836 cam->params.version.asic_id,
837 cam->params.version.asic_rev);
838 LOG(" CPiA PnP-ID: %04x:%04x:%04x\n",
839 cam->params.pnp_id.vendor,
840 cam->params.pnp_id.product,
841 cam->params.pnp_id.device_revision);
842 LOG(" SensorID: %d.(version %d)\n",
843 cam->params.version.sensor_flags,
844 cam->params.version.sensor_rev);
845
846 usb_set_intfdata(intf, cam);
847
848 return 0;
849}
850
851/******************************************************************************
852 *
853 * cpia2_disconnect
854 *
855 *****************************************************************************/
856static void cpia2_usb_disconnect(struct usb_interface *intf)
857{
858 struct camera_data *cam = usb_get_intfdata(intf);
859 usb_set_intfdata(intf, NULL);
860 cam->present = 0;
861
862 DBG("Stopping stream\n");
863 cpia2_usb_stream_stop(cam);
864
865 DBG("Unregistering camera\n");
866 cpia2_unregister_camera(cam);
867
868 if(cam->buffers) {
869 DBG("Wakeup waiting processes\n");
870 cam->curbuff->status = FRAME_READY;
871 cam->curbuff->length = 0;
872 if (waitqueue_active(&cam->wq_stream))
873 wake_up_interruptible(&cam->wq_stream);
874 }
875
876 DBG("Releasing interface\n");
877 usb_driver_release_interface(&cpia2_driver, intf);
878
879 if (cam->open_count == 0) {
880 DBG("Freeing camera structure\n");
881 kfree(cam);
882 }
883
884 LOG("CPiA2 camera disconnected.\n");
885}
886
887
888/******************************************************************************
889 *
890 * usb_cpia2_init
891 *
892 *****************************************************************************/
893int cpia2_usb_init(void)
894{
895 return usb_register(&cpia2_driver);
896}
897
898/******************************************************************************
899 *
900 * usb_cpia_cleanup
901 *
902 *****************************************************************************/
903void cpia2_usb_cleanup(void)
904{
905 schedule_timeout(2 * HZ);
906 usb_deregister(&cpia2_driver);
907}
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
new file mode 100644
index 000000000000..3480a2ca7cdc
--- /dev/null
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -0,0 +1,2104 @@
1/****************************************************************************
2 *
3 * Filename: cpia2_v4l.c
4 *
5 * Copyright 2001, STMicrolectronics, Inc.
6 * Contact: steve.miller@st.com
7 * Copyright 2001,2005, Scott J. Bertin <scottbertin@yahoo.com>
8 *
9 * Description:
10 * This is a USB driver for CPia2 based video cameras.
11 * The infrastructure of this driver is based on the cpia usb driver by
12 * Jochen Scharrlach and Johannes Erdfeldt.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Stripped of 2.4 stuff ready for main kernel submit by
29 * Alan Cox <alan@redhat.com>
30 ****************************************************************************/
31
32#include <linux/version.h>
33
34#include <linux/config.h>
35
36#include <linux/module.h>
37#include <linux/time.h>
38#include <linux/sched.h>
39#include <linux/slab.h>
40#include <linux/init.h>
41#include <linux/moduleparam.h>
42
43#include "cpia2.h"
44#include "cpia2dev.h"
45
46
47//#define _CPIA2_DEBUG_
48
49#define MAKE_STRING_1(x) #x
50#define MAKE_STRING(x) MAKE_STRING_1(x)
51
52static int video_nr = -1;
53module_param(video_nr, int, 0);
54MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)");
55
56static int buffer_size = 68*1024;
57module_param(buffer_size, int, 0);
58MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)");
59
60static int num_buffers = 3;
61module_param(num_buffers, int, 0);
62MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-"
63 MAKE_STRING(VIDEO_MAX_FRAME) ", default 3)");
64
65static int alternate = DEFAULT_ALT;
66module_param(alternate, int, 0);
67MODULE_PARM_DESC(alternate, "USB Alternate (" MAKE_STRING(USBIF_ISO_1) "-"
68 MAKE_STRING(USBIF_ISO_6) ", default "
69 MAKE_STRING(DEFAULT_ALT) ")");
70
71static int flicker_freq = 60;
72module_param(flicker_freq, int, 0);
73MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" MAKE_STRING(50) "or"
74 MAKE_STRING(60) ", default "
75 MAKE_STRING(60) ")");
76
77static int flicker_mode = NEVER_FLICKER;
78module_param(flicker_mode, int, 0);
79MODULE_PARM_DESC(flicker_mode,
80 "Flicker supression (" MAKE_STRING(NEVER_FLICKER) "or"
81 MAKE_STRING(ANTI_FLICKER_ON) ", default "
82 MAKE_STRING(NEVER_FLICKER) ")");
83
84MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>");
85MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras");
86MODULE_SUPPORTED_DEVICE("video");
87MODULE_LICENSE("GPL");
88
89#define ABOUT "V4L-Driver for Vision CPiA2 based cameras"
90
91#ifndef VID_HARDWARE_CPIA2
92#error "VID_HARDWARE_CPIA2 should have been defined in linux/videodev.h"
93#endif
94
95struct control_menu_info {
96 int value;
97 char name[32];
98};
99
100static struct control_menu_info framerate_controls[] =
101{
102 { CPIA2_VP_FRAMERATE_6_25, "6.25 fps" },
103 { CPIA2_VP_FRAMERATE_7_5, "7.5 fps" },
104 { CPIA2_VP_FRAMERATE_12_5, "12.5 fps" },
105 { CPIA2_VP_FRAMERATE_15, "15 fps" },
106 { CPIA2_VP_FRAMERATE_25, "25 fps" },
107 { CPIA2_VP_FRAMERATE_30, "30 fps" },
108};
109#define NUM_FRAMERATE_CONTROLS (sizeof(framerate_controls)/sizeof(framerate_controls[0]))
110
111static struct control_menu_info flicker_controls[] =
112{
113 { NEVER_FLICKER, "Off" },
114 { FLICKER_50, "50 Hz" },
115 { FLICKER_60, "60 Hz" },
116};
117#define NUM_FLICKER_CONTROLS (sizeof(flicker_controls)/sizeof(flicker_controls[0]))
118
119static struct control_menu_info lights_controls[] =
120{
121 { 0, "Off" },
122 { 64, "Top" },
123 { 128, "Bottom" },
124 { 192, "Both" },
125};
126#define NUM_LIGHTS_CONTROLS (sizeof(lights_controls)/sizeof(lights_controls[0]))
127#define GPIO_LIGHTS_MASK 192
128
129static struct v4l2_queryctrl controls[] = {
130 {
131 .id = V4L2_CID_BRIGHTNESS,
132 .type = V4L2_CTRL_TYPE_INTEGER,
133 .name = "Brightness",
134 .minimum = 0,
135 .maximum = 255,
136 .step = 1,
137 .default_value = DEFAULT_BRIGHTNESS,
138 },
139 {
140 .id = V4L2_CID_CONTRAST,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "Contrast",
143 .minimum = 0,
144 .maximum = 255,
145 .step = 1,
146 .default_value = DEFAULT_CONTRAST,
147 },
148 {
149 .id = V4L2_CID_SATURATION,
150 .type = V4L2_CTRL_TYPE_INTEGER,
151 .name = "Saturation",
152 .minimum = 0,
153 .maximum = 255,
154 .step = 1,
155 .default_value = DEFAULT_SATURATION,
156 },
157 {
158 .id = V4L2_CID_HFLIP,
159 .type = V4L2_CTRL_TYPE_BOOLEAN,
160 .name = "Mirror Horizontally",
161 .minimum = 0,
162 .maximum = 1,
163 .step = 1,
164 .default_value = 0,
165 },
166 {
167 .id = V4L2_CID_VFLIP,
168 .type = V4L2_CTRL_TYPE_BOOLEAN,
169 .name = "Flip Vertically",
170 .minimum = 0,
171 .maximum = 1,
172 .step = 1,
173 .default_value = 0,
174 },
175 {
176 .id = CPIA2_CID_TARGET_KB,
177 .type = V4L2_CTRL_TYPE_INTEGER,
178 .name = "Target KB",
179 .minimum = 0,
180 .maximum = 255,
181 .step = 1,
182 .default_value = DEFAULT_TARGET_KB,
183 },
184 {
185 .id = CPIA2_CID_GPIO,
186 .type = V4L2_CTRL_TYPE_INTEGER,
187 .name = "GPIO",
188 .minimum = 0,
189 .maximum = 255,
190 .step = 1,
191 .default_value = 0,
192 },
193 {
194 .id = CPIA2_CID_FLICKER_MODE,
195 .type = V4L2_CTRL_TYPE_MENU,
196 .name = "Flicker Reduction",
197 .minimum = 0,
198 .maximum = NUM_FLICKER_CONTROLS-1,
199 .step = 1,
200 .default_value = 0,
201 },
202 {
203 .id = CPIA2_CID_FRAMERATE,
204 .type = V4L2_CTRL_TYPE_MENU,
205 .name = "Framerate",
206 .minimum = 0,
207 .maximum = NUM_FRAMERATE_CONTROLS-1,
208 .step = 1,
209 .default_value = NUM_FRAMERATE_CONTROLS-1,
210 },
211 {
212 .id = CPIA2_CID_USB_ALT,
213 .type = V4L2_CTRL_TYPE_INTEGER,
214 .name = "USB Alternate",
215 .minimum = USBIF_ISO_1,
216 .maximum = USBIF_ISO_6,
217 .step = 1,
218 .default_value = DEFAULT_ALT,
219 },
220 {
221 .id = CPIA2_CID_LIGHTS,
222 .type = V4L2_CTRL_TYPE_MENU,
223 .name = "Lights",
224 .minimum = 0,
225 .maximum = NUM_LIGHTS_CONTROLS-1,
226 .step = 1,
227 .default_value = 0,
228 },
229 {
230 .id = CPIA2_CID_RESET_CAMERA,
231 .type = V4L2_CTRL_TYPE_BUTTON,
232 .name = "Reset Camera",
233 .minimum = 0,
234 .maximum = 0,
235 .step = 0,
236 .default_value = 0,
237 },
238};
239#define NUM_CONTROLS (sizeof(controls)/sizeof(controls[0]))
240
241
242/******************************************************************************
243 *
244 * cpia2_open
245 *
246 *****************************************************************************/
247static int cpia2_open(struct inode *inode, struct file *file)
248{
249 struct video_device *dev = video_devdata(file);
250 struct camera_data *cam = video_get_drvdata(dev);
251 int retval = 0;
252
253 if (!cam) {
254 ERR("Internal error, camera_data not found!\n");
255 return -ENODEV;
256 }
257
258 if(down_interruptible(&cam->busy_lock))
259 return -ERESTARTSYS;
260
261 if(!cam->present) {
262 retval = -ENODEV;
263 goto err_return;
264 }
265
266 if (cam->open_count > 0) {
267 goto skip_init;
268 }
269
270 if (cpia2_allocate_buffers(cam)) {
271 retval = -ENOMEM;
272 goto err_return;
273 }
274
275 /* reset the camera */
276 if (cpia2_reset_camera(cam) < 0) {
277 retval = -EIO;
278 goto err_return;
279 }
280
281 cam->APP_len = 0;
282 cam->COM_len = 0;
283
284skip_init:
285 {
286 struct cpia2_fh *fh = kmalloc(sizeof(*fh),GFP_KERNEL);
287 if(!fh) {
288 retval = -ENOMEM;
289 goto err_return;
290 }
291 file->private_data = fh;
292 fh->prio = V4L2_PRIORITY_UNSET;
293 v4l2_prio_open(&cam->prio, &fh->prio);
294 fh->mmapped = 0;
295 }
296
297 ++cam->open_count;
298
299 cpia2_dbg_dump_registers(cam);
300
301err_return:
302 up(&cam->busy_lock);
303 return retval;
304}
305
306/******************************************************************************
307 *
308 * cpia2_close
309 *
310 *****************************************************************************/
311static int cpia2_close(struct inode *inode, struct file *file)
312{
313 struct video_device *dev = video_devdata(file);
314 struct camera_data *cam = video_get_drvdata(dev);
315 struct cpia2_fh *fh = file->private_data;
316
317 down(&cam->busy_lock);
318
319 if (cam->present &&
320 (cam->open_count == 1
321 || fh->prio == V4L2_PRIORITY_RECORD
322 )) {
323 cpia2_usb_stream_stop(cam);
324
325 if(cam->open_count == 1) {
326 /* save camera state for later open */
327 cpia2_save_camera_state(cam);
328
329 cpia2_set_low_power(cam);
330 cpia2_free_buffers(cam);
331 }
332 }
333
334 {
335 if(fh->mmapped)
336 cam->mmapped = 0;
337 v4l2_prio_close(&cam->prio,&fh->prio);
338 file->private_data = NULL;
339 kfree(fh);
340 }
341
342 if (--cam->open_count == 0) {
343 cpia2_free_buffers(cam);
344 if (!cam->present) {
345 video_unregister_device(dev);
346 kfree(cam);
347 }
348 }
349
350 up(&cam->busy_lock);
351
352 return 0;
353}
354
355/******************************************************************************
356 *
357 * cpia2_v4l_read
358 *
359 *****************************************************************************/
360static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count,
361 loff_t *off)
362{
363 struct video_device *dev = video_devdata(file);
364 struct camera_data *cam = video_get_drvdata(dev);
365 int noblock = file->f_flags&O_NONBLOCK;
366
367 struct cpia2_fh *fh = file->private_data;
368
369 if(!cam)
370 return -EINVAL;
371
372 /* Priority check */
373 if(fh->prio != V4L2_PRIORITY_RECORD) {
374 return -EBUSY;
375 }
376
377 return cpia2_read(cam, buf, count, noblock);
378}
379
380
381/******************************************************************************
382 *
383 * cpia2_v4l_poll
384 *
385 *****************************************************************************/
386static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait)
387{
388 struct video_device *dev = video_devdata(filp);
389 struct camera_data *cam = video_get_drvdata(dev);
390
391 struct cpia2_fh *fh = filp->private_data;
392
393 if(!cam)
394 return POLLERR;
395
396 /* Priority check */
397 if(fh->prio != V4L2_PRIORITY_RECORD) {
398 return POLLERR;
399 }
400
401 return cpia2_poll(cam, filp, wait);
402}
403
404
405/******************************************************************************
406 *
407 * ioctl_cap_query
408 *
409 *****************************************************************************/
410static int ioctl_cap_query(void *arg, struct camera_data *cam)
411{
412 struct video_capability *vc;
413 int retval = 0;
414 vc = arg;
415
416 if (cam->params.pnp_id.product == 0x151)
417 strcpy(vc->name, "QX5 Microscope");
418 else
419 strcpy(vc->name, "CPiA2 Camera");
420
421 vc->type = VID_TYPE_CAPTURE | VID_TYPE_MJPEG_ENCODER;
422 vc->channels = 1;
423 vc->audios = 0;
424 vc->minwidth = 176; /* VIDEOSIZE_QCIF */
425 vc->minheight = 144;
426 switch (cam->params.version.sensor_flags) {
427 case CPIA2_VP_SENSOR_FLAGS_500:
428 vc->maxwidth = STV_IMAGE_VGA_COLS;
429 vc->maxheight = STV_IMAGE_VGA_ROWS;
430 break;
431 case CPIA2_VP_SENSOR_FLAGS_410:
432 vc->maxwidth = STV_IMAGE_CIF_COLS;
433 vc->maxheight = STV_IMAGE_CIF_ROWS;
434 break;
435 default:
436 return -EINVAL;
437 }
438
439 return retval;
440}
441
442/******************************************************************************
443 *
444 * ioctl_get_channel
445 *
446 *****************************************************************************/
447static int ioctl_get_channel(void *arg)
448{
449 int retval = 0;
450 struct video_channel *v;
451 v = arg;
452
453 if (v->channel != 0)
454 return -EINVAL;
455
456 v->channel = 0;
457 strcpy(v->name, "Camera");
458 v->tuners = 0;
459 v->flags = 0;
460 v->type = VIDEO_TYPE_CAMERA;
461 v->norm = 0;
462
463 return retval;
464}
465
466/******************************************************************************
467 *
468 * ioctl_set_channel
469 *
470 *****************************************************************************/
471static int ioctl_set_channel(void *arg)
472{
473 struct video_channel *v;
474 int retval = 0;
475 v = arg;
476
477 if (retval == 0 && v->channel != 0)
478 retval = -EINVAL;
479
480 return retval;
481}
482
483/******************************************************************************
484 *
485 * ioctl_set_image_prop
486 *
487 *****************************************************************************/
488static int ioctl_set_image_prop(void *arg, struct camera_data *cam)
489{
490 struct video_picture *vp;
491 int retval = 0;
492 vp = arg;
493
494 /* brightness, color, contrast need no check 0-65535 */
495 memcpy(&cam->vp, vp, sizeof(*vp));
496
497 /* update cam->params.colorParams */
498 cam->params.color_params.brightness = vp->brightness / 256;
499 cam->params.color_params.saturation = vp->colour / 256;
500 cam->params.color_params.contrast = vp->contrast / 256;
501
502 DBG("Requested params: bright 0x%X, sat 0x%X, contrast 0x%X\n",
503 cam->params.color_params.brightness,
504 cam->params.color_params.saturation,
505 cam->params.color_params.contrast);
506
507 cpia2_set_color_params(cam);
508
509 return retval;
510}
511
512static int sync(struct camera_data *cam, int frame_nr)
513{
514 struct framebuf *frame = &cam->buffers[frame_nr];
515
516 while (1) {
517 if (frame->status == FRAME_READY)
518 return 0;
519
520 if (!cam->streaming) {
521 frame->status = FRAME_READY;
522 frame->length = 0;
523 return 0;
524 }
525
526 up(&cam->busy_lock);
527 wait_event_interruptible(cam->wq_stream,
528 !cam->streaming ||
529 frame->status == FRAME_READY);
530 down(&cam->busy_lock);
531 if (signal_pending(current))
532 return -ERESTARTSYS;
533 if(!cam->present)
534 return -ENOTTY;
535 }
536}
537
538/******************************************************************************
539 *
540 * ioctl_set_window_size
541 *
542 *****************************************************************************/
543static int ioctl_set_window_size(void *arg, struct camera_data *cam,
544 struct cpia2_fh *fh)
545{
546 /* copy_from_user, check validity, copy to internal structure */
547 struct video_window *vw;
548 int frame, err;
549 vw = arg;
550
551 if (vw->clipcount != 0) /* clipping not supported */
552 return -EINVAL;
553
554 if (vw->clips != NULL) /* clipping not supported */
555 return -EINVAL;
556
557 /* Ensure that only this process can change the format. */
558 err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD);
559 if(err != 0)
560 return err;
561
562 cam->pixelformat = V4L2_PIX_FMT_JPEG;
563
564 /* Be sure to supply the Huffman tables, this isn't MJPEG */
565 cam->params.compression.inhibit_htables = 0;
566
567 /* we set the video window to something smaller or equal to what
568 * is requested by the user???
569 */
570 DBG("Requested width = %d, height = %d\n", vw->width, vw->height);
571 if (vw->width != cam->vw.width || vw->height != cam->vw.height) {
572 cam->vw.width = vw->width;
573 cam->vw.height = vw->height;
574 cam->params.roi.width = vw->width;
575 cam->params.roi.height = vw->height;
576 cpia2_set_format(cam);
577 }
578
579 for (frame = 0; frame < cam->num_frames; ++frame) {
580 if (cam->buffers[frame].status == FRAME_READING)
581 if ((err = sync(cam, frame)) < 0)
582 return err;
583
584 cam->buffers[frame].status = FRAME_EMPTY;
585 }
586
587 return 0;
588}
589
590/******************************************************************************
591 *
592 * ioctl_get_mbuf
593 *
594 *****************************************************************************/
595static int ioctl_get_mbuf(void *arg, struct camera_data *cam)
596{
597 struct video_mbuf *vm;
598 int i;
599 vm = arg;
600
601 memset(vm, 0, sizeof(*vm));
602 vm->size = cam->frame_size*cam->num_frames;
603 vm->frames = cam->num_frames;
604 for (i = 0; i < cam->num_frames; i++)
605 vm->offsets[i] = cam->frame_size * i;
606
607 return 0;
608}
609
610/******************************************************************************
611 *
612 * ioctl_mcapture
613 *
614 *****************************************************************************/
615static int ioctl_mcapture(void *arg, struct camera_data *cam,
616 struct cpia2_fh *fh)
617{
618 struct video_mmap *vm;
619 int video_size, err;
620 vm = arg;
621
622 if (vm->frame < 0 || vm->frame >= cam->num_frames)
623 return -EINVAL;
624
625 /* set video size */
626 video_size = cpia2_match_video_size(vm->width, vm->height);
627 if (cam->video_size < 0) {
628 return -EINVAL;
629 }
630
631 /* Ensure that only this process can change the format. */
632 err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD);
633 if(err != 0)
634 return err;
635
636 if (video_size != cam->video_size) {
637 cam->video_size = video_size;
638 cam->params.roi.width = vm->width;
639 cam->params.roi.height = vm->height;
640 cpia2_set_format(cam);
641 }
642
643 if (cam->buffers[vm->frame].status == FRAME_READING)
644 if ((err=sync(cam, vm->frame)) < 0)
645 return err;
646
647 cam->buffers[vm->frame].status = FRAME_EMPTY;
648
649 return cpia2_usb_stream_start(cam,cam->params.camera_state.stream_mode);
650}
651
652/******************************************************************************
653 *
654 * ioctl_sync
655 *
656 *****************************************************************************/
657static int ioctl_sync(void *arg, struct camera_data *cam)
658{
659 int frame;
660
661 frame = *(int*)arg;
662
663 if (frame < 0 || frame >= cam->num_frames)
664 return -EINVAL;
665
666 return sync(cam, frame);
667}
668
669
670/******************************************************************************
671 *
672 * ioctl_set_gpio
673 *
674 *****************************************************************************/
675
676static int ioctl_set_gpio(void *arg, struct camera_data *cam)
677{
678 __u32 gpio_val;
679
680 gpio_val = *(__u32*) arg;
681
682 if (gpio_val &~ 0xFFU)
683 return -EINVAL;
684
685 return cpia2_set_gpio(cam, (unsigned char)gpio_val);
686}
687
688/******************************************************************************
689 *
690 * ioctl_querycap
691 *
692 * V4L2 device capabilities
693 *
694 *****************************************************************************/
695
696static int ioctl_querycap(void *arg, struct camera_data *cam)
697{
698 struct v4l2_capability *vc = arg;
699
700 memset(vc, 0, sizeof(*vc));
701 strcpy(vc->driver, "cpia2");
702
703 if (cam->params.pnp_id.product == 0x151)
704 strcpy(vc->card, "QX5 Microscope");
705 else
706 strcpy(vc->card, "CPiA2 Camera");
707 switch (cam->params.pnp_id.device_type) {
708 case DEVICE_STV_672:
709 strcat(vc->card, " (672/");
710 break;
711 case DEVICE_STV_676:
712 strcat(vc->card, " (676/");
713 break;
714 default:
715 strcat(vc->card, " (???/");
716 break;
717 }
718 switch (cam->params.version.sensor_flags) {
719 case CPIA2_VP_SENSOR_FLAGS_404:
720 strcat(vc->card, "404)");
721 break;
722 case CPIA2_VP_SENSOR_FLAGS_407:
723 strcat(vc->card, "407)");
724 break;
725 case CPIA2_VP_SENSOR_FLAGS_409:
726 strcat(vc->card, "409)");
727 break;
728 case CPIA2_VP_SENSOR_FLAGS_410:
729 strcat(vc->card, "410)");
730 break;
731 case CPIA2_VP_SENSOR_FLAGS_500:
732 strcat(vc->card, "500)");
733 break;
734 default:
735 strcat(vc->card, "???)");
736 break;
737 }
738
739 if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0)
740 memset(vc->bus_info,0, sizeof(vc->bus_info));
741
742 vc->version = KERNEL_VERSION(CPIA2_MAJ_VER, CPIA2_MIN_VER,
743 CPIA2_PATCH_VER);
744
745 vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
746 V4L2_CAP_READWRITE |
747 V4L2_CAP_STREAMING;
748
749 return 0;
750}
751
752/******************************************************************************
753 *
754 * ioctl_input
755 *
756 * V4L2 input get/set/enumerate
757 *
758 *****************************************************************************/
759
760static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam)
761{
762 struct v4l2_input *i = arg;
763
764 if(ioclt_nr != VIDIOC_G_INPUT) {
765 if (i->index != 0)
766 return -EINVAL;
767 }
768
769 memset(i, 0, sizeof(*i));
770 strcpy(i->name, "Camera");
771 i->type = V4L2_INPUT_TYPE_CAMERA;
772
773 return 0;
774}
775
776/******************************************************************************
777 *
778 * ioctl_enum_fmt
779 *
780 * V4L2 format enumerate
781 *
782 *****************************************************************************/
783
784static int ioctl_enum_fmt(void *arg,struct camera_data *cam)
785{
786 struct v4l2_fmtdesc *f = arg;
787 int index = f->index;
788
789 if (index < 0 || index > 1)
790 return -EINVAL;
791
792 memset(f, 0, sizeof(*f));
793 f->index = index;
794 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
795 f->flags = V4L2_FMT_FLAG_COMPRESSED;
796 switch(index) {
797 case 0:
798 strcpy(f->description, "MJPEG");
799 f->pixelformat = V4L2_PIX_FMT_MJPEG;
800 break;
801 case 1:
802 strcpy(f->description, "JPEG");
803 f->pixelformat = V4L2_PIX_FMT_JPEG;
804 break;
805 default:
806 return -EINVAL;
807 }
808
809 return 0;
810}
811
812/******************************************************************************
813 *
814 * ioctl_try_fmt
815 *
816 * V4L2 format try
817 *
818 *****************************************************************************/
819
820static int ioctl_try_fmt(void *arg,struct camera_data *cam)
821{
822 struct v4l2_format *f = arg;
823
824 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
825 return -EINVAL;
826
827 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
828 f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
829 return -EINVAL;
830
831 f->fmt.pix.field = V4L2_FIELD_NONE;
832 f->fmt.pix.bytesperline = 0;
833 f->fmt.pix.sizeimage = cam->frame_size;
834 f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
835 f->fmt.pix.priv = 0;
836
837 switch (cpia2_match_video_size(f->fmt.pix.width, f->fmt.pix.height)) {
838 case VIDEOSIZE_VGA:
839 f->fmt.pix.width = 640;
840 f->fmt.pix.height = 480;
841 break;
842 case VIDEOSIZE_CIF:
843 f->fmt.pix.width = 352;
844 f->fmt.pix.height = 288;
845 break;
846 case VIDEOSIZE_QVGA:
847 f->fmt.pix.width = 320;
848 f->fmt.pix.height = 240;
849 break;
850 case VIDEOSIZE_288_216:
851 f->fmt.pix.width = 288;
852 f->fmt.pix.height = 216;
853 break;
854 case VIDEOSIZE_256_192:
855 f->fmt.pix.width = 256;
856 f->fmt.pix.height = 192;
857 break;
858 case VIDEOSIZE_224_168:
859 f->fmt.pix.width = 224;
860 f->fmt.pix.height = 168;
861 break;
862 case VIDEOSIZE_192_144:
863 f->fmt.pix.width = 192;
864 f->fmt.pix.height = 144;
865 break;
866 case VIDEOSIZE_QCIF:
867 default:
868 f->fmt.pix.width = 176;
869 f->fmt.pix.height = 144;
870 break;
871 }
872
873 return 0;
874}
875
876/******************************************************************************
877 *
878 * ioctl_set_fmt
879 *
880 * V4L2 format set
881 *
882 *****************************************************************************/
883
884static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh)
885{
886 struct v4l2_format *f = arg;
887 int err, frame;
888
889 err = ioctl_try_fmt(arg, cam);
890 if(err != 0)
891 return err;
892
893 /* Ensure that only this process can change the format. */
894 err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD);
895 if(err != 0) {
896 return err;
897 }
898
899 cam->pixelformat = f->fmt.pix.pixelformat;
900
901 /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle
902 * the missing Huffman table properly. */
903 cam->params.compression.inhibit_htables = 0;
904 /*f->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG;*/
905
906 /* we set the video window to something smaller or equal to what
907 * is requested by the user???
908 */
909 DBG("Requested width = %d, height = %d\n",
910 f->fmt.pix.width, f->fmt.pix.height);
911 if (f->fmt.pix.width != cam->vw.width ||
912 f->fmt.pix.height != cam->vw.height) {
913 cam->vw.width = f->fmt.pix.width;
914 cam->vw.height = f->fmt.pix.height;
915 cam->params.roi.width = f->fmt.pix.width;
916 cam->params.roi.height = f->fmt.pix.height;
917 cpia2_set_format(cam);
918 }
919
920 for (frame = 0; frame < cam->num_frames; ++frame) {
921 if (cam->buffers[frame].status == FRAME_READING)
922 if ((err = sync(cam, frame)) < 0)
923 return err;
924
925 cam->buffers[frame].status = FRAME_EMPTY;
926 }
927
928 return 0;
929}
930
931/******************************************************************************
932 *
933 * ioctl_get_fmt
934 *
935 * V4L2 format get
936 *
937 *****************************************************************************/
938
939static int ioctl_get_fmt(void *arg,struct camera_data *cam)
940{
941 struct v4l2_format *f = arg;
942
943 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
944 return -EINVAL;
945
946 f->fmt.pix.width = cam->vw.width;
947 f->fmt.pix.height = cam->vw.height;
948 f->fmt.pix.pixelformat = cam->pixelformat;
949 f->fmt.pix.field = V4L2_FIELD_NONE;
950 f->fmt.pix.bytesperline = 0;
951 f->fmt.pix.sizeimage = cam->frame_size;
952 f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
953 f->fmt.pix.priv = 0;
954
955 return 0;
956}
957
958/******************************************************************************
959 *
960 * ioctl_cropcap
961 *
962 * V4L2 query cropping capabilities
963 * NOTE: cropping is currently disabled
964 *
965 *****************************************************************************/
966
967static int ioctl_cropcap(void *arg,struct camera_data *cam)
968{
969 struct v4l2_cropcap *c = arg;
970
971 if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
972 return -EINVAL;
973
974 c->bounds.left = 0;
975 c->bounds.top = 0;
976 c->bounds.width = cam->vw.width;
977 c->bounds.height = cam->vw.height;
978 c->defrect.left = 0;
979 c->defrect.top = 0;
980 c->defrect.width = cam->vw.width;
981 c->defrect.height = cam->vw.height;
982 c->pixelaspect.numerator = 1;
983 c->pixelaspect.denominator = 1;
984
985 return 0;
986}
987
988/******************************************************************************
989 *
990 * ioctl_queryctrl
991 *
992 * V4L2 query possible control variables
993 *
994 *****************************************************************************/
995
996static int ioctl_queryctrl(void *arg,struct camera_data *cam)
997{
998 struct v4l2_queryctrl *c = arg;
999 int i;
1000
1001 for(i=0; i<NUM_CONTROLS; ++i) {
1002 if(c->id == controls[i].id) {
1003 memcpy(c, controls+i, sizeof(*c));
1004 break;
1005 }
1006 }
1007
1008 if(i == NUM_CONTROLS)
1009 return -EINVAL;
1010
1011 /* Some devices have additional limitations */
1012 switch(c->id) {
1013 case V4L2_CID_BRIGHTNESS:
1014 /***
1015 * Don't let the register be set to zero - bug in VP4
1016 * flash of full brightness
1017 ***/
1018 if (cam->params.pnp_id.device_type == DEVICE_STV_672)
1019 c->minimum = 1;
1020 break;
1021 case V4L2_CID_VFLIP:
1022 // VP5 Only
1023 if(cam->params.pnp_id.device_type == DEVICE_STV_672)
1024 c->flags |= V4L2_CTRL_FLAG_DISABLED;
1025 break;
1026 case CPIA2_CID_FRAMERATE:
1027 if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
1028 cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
1029 // Maximum 15fps
1030 int i;
1031 for(i=0; i<c->maximum; ++i) {
1032 if(framerate_controls[i].value ==
1033 CPIA2_VP_FRAMERATE_15) {
1034 c->maximum = i;
1035 c->default_value = i;
1036 }
1037 }
1038 }
1039 break;
1040 case CPIA2_CID_FLICKER_MODE:
1041 // Flicker control only valid for 672.
1042 if(cam->params.pnp_id.device_type != DEVICE_STV_672)
1043 c->flags |= V4L2_CTRL_FLAG_DISABLED;
1044 break;
1045 case CPIA2_CID_LIGHTS:
1046 // Light control only valid for the QX5 Microscope.
1047 if(cam->params.pnp_id.product != 0x151)
1048 c->flags |= V4L2_CTRL_FLAG_DISABLED;
1049 break;
1050 default:
1051 break;
1052 }
1053
1054 return 0;
1055}
1056
1057/******************************************************************************
1058 *
1059 * ioctl_querymenu
1060 *
1061 * V4L2 query possible control variables
1062 *
1063 *****************************************************************************/
1064
1065static int ioctl_querymenu(void *arg,struct camera_data *cam)
1066{
1067 struct v4l2_querymenu *m = arg;
1068
1069 memset(m->name, 0, sizeof(m->name));
1070 m->reserved = 0;
1071
1072 switch(m->id) {
1073 case CPIA2_CID_FLICKER_MODE:
1074 if(m->index < 0 || m->index >= NUM_FLICKER_CONTROLS)
1075 return -EINVAL;
1076
1077 strcpy(m->name, flicker_controls[m->index].name);
1078 break;
1079 case CPIA2_CID_FRAMERATE:
1080 {
1081 int maximum = NUM_FRAMERATE_CONTROLS - 1;
1082 if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
1083 cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
1084 // Maximum 15fps
1085 int i;
1086 for(i=0; i<maximum; ++i) {
1087 if(framerate_controls[i].value ==
1088 CPIA2_VP_FRAMERATE_15)
1089 maximum = i;
1090 }
1091 }
1092 if(m->index < 0 || m->index > maximum)
1093 return -EINVAL;
1094
1095 strcpy(m->name, framerate_controls[m->index].name);
1096 break;
1097 }
1098 case CPIA2_CID_LIGHTS:
1099 if(m->index < 0 || m->index >= NUM_LIGHTS_CONTROLS)
1100 return -EINVAL;
1101
1102 strcpy(m->name, lights_controls[m->index].name);
1103 break;
1104 default:
1105 return -EINVAL;
1106 }
1107
1108 return 0;
1109}
1110
1111/******************************************************************************
1112 *
1113 * ioctl_g_ctrl
1114 *
1115 * V4L2 get the value of a control variable
1116 *
1117 *****************************************************************************/
1118
1119static int ioctl_g_ctrl(void *arg,struct camera_data *cam)
1120{
1121 struct v4l2_control *c = arg;
1122
1123 switch(c->id) {
1124 case V4L2_CID_BRIGHTNESS:
1125 cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS,
1126 TRANSFER_READ, 0);
1127 c->value = cam->params.color_params.brightness;
1128 break;
1129 case V4L2_CID_CONTRAST:
1130 cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST,
1131 TRANSFER_READ, 0);
1132 c->value = cam->params.color_params.contrast;
1133 break;
1134 case V4L2_CID_SATURATION:
1135 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION,
1136 TRANSFER_READ, 0);
1137 c->value = cam->params.color_params.saturation;
1138 break;
1139 case V4L2_CID_HFLIP:
1140 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS,
1141 TRANSFER_READ, 0);
1142 c->value = (cam->params.vp_params.user_effects &
1143 CPIA2_VP_USER_EFFECTS_MIRROR) != 0;
1144 break;
1145 case V4L2_CID_VFLIP:
1146 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS,
1147 TRANSFER_READ, 0);
1148 c->value = (cam->params.vp_params.user_effects &
1149 CPIA2_VP_USER_EFFECTS_FLIP) != 0;
1150 break;
1151 case CPIA2_CID_TARGET_KB:
1152 c->value = cam->params.vc_params.target_kb;
1153 break;
1154 case CPIA2_CID_GPIO:
1155 cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA,
1156 TRANSFER_READ, 0);
1157 c->value = cam->params.vp_params.gpio_data;
1158 break;
1159 case CPIA2_CID_FLICKER_MODE:
1160 {
1161 int i, mode;
1162 cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES,
1163 TRANSFER_READ, 0);
1164 if(cam->params.flicker_control.cam_register &
1165 CPIA2_VP_FLICKER_MODES_NEVER_FLICKER) {
1166 mode = NEVER_FLICKER;
1167 } else {
1168 if(cam->params.flicker_control.cam_register &
1169 CPIA2_VP_FLICKER_MODES_50HZ) {
1170 mode = FLICKER_50;
1171 } else {
1172 mode = FLICKER_60;
1173 }
1174 }
1175 for(i=0; i<NUM_FLICKER_CONTROLS; i++) {
1176 if(flicker_controls[i].value == mode) {
1177 c->value = i;
1178 break;
1179 }
1180 }
1181 if(i == NUM_FLICKER_CONTROLS)
1182 return -EINVAL;
1183 break;
1184 }
1185 case CPIA2_CID_FRAMERATE:
1186 {
1187 int maximum = NUM_FRAMERATE_CONTROLS - 1;
1188 int i;
1189 for(i=0; i<= maximum; i++) {
1190 if(cam->params.vp_params.frame_rate ==
1191 framerate_controls[i].value)
1192 break;
1193 }
1194 if(i > maximum)
1195 return -EINVAL;
1196 c->value = i;
1197 break;
1198 }
1199 case CPIA2_CID_USB_ALT:
1200 c->value = cam->params.camera_state.stream_mode;
1201 break;
1202 case CPIA2_CID_LIGHTS:
1203 {
1204 int i;
1205 cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA,
1206 TRANSFER_READ, 0);
1207 for(i=0; i<NUM_LIGHTS_CONTROLS; i++) {
1208 if((cam->params.vp_params.gpio_data&GPIO_LIGHTS_MASK) ==
1209 lights_controls[i].value) {
1210 break;
1211 }
1212 }
1213 if(i == NUM_LIGHTS_CONTROLS)
1214 return -EINVAL;
1215 c->value = i;
1216 break;
1217 }
1218 case CPIA2_CID_RESET_CAMERA:
1219 return -EINVAL;
1220 default:
1221 return -EINVAL;
1222 }
1223
1224 DBG("Get control id:%d, value:%d\n", c->id, c->value);
1225
1226 return 0;
1227}
1228
1229/******************************************************************************
1230 *
1231 * ioctl_s_ctrl
1232 *
1233 * V4L2 set the value of a control variable
1234 *
1235 *****************************************************************************/
1236
1237static int ioctl_s_ctrl(void *arg,struct camera_data *cam)
1238{
1239 struct v4l2_control *c = arg;
1240 int i;
1241 int retval = 0;
1242
1243 DBG("Set control id:%d, value:%d\n", c->id, c->value);
1244
1245 /* Check that the value is in range */
1246 for(i=0; i<NUM_CONTROLS; i++) {
1247 if(c->id == controls[i].id) {
1248 if(c->value < controls[i].minimum ||
1249 c->value > controls[i].maximum) {
1250 return -EINVAL;
1251 }
1252 break;
1253 }
1254 }
1255 if(i == NUM_CONTROLS)
1256 return -EINVAL;
1257
1258 switch(c->id) {
1259 case V4L2_CID_BRIGHTNESS:
1260 cpia2_set_brightness(cam, c->value);
1261 break;
1262 case V4L2_CID_CONTRAST:
1263 cpia2_set_contrast(cam, c->value);
1264 break;
1265 case V4L2_CID_SATURATION:
1266 cpia2_set_saturation(cam, c->value);
1267 break;
1268 case V4L2_CID_HFLIP:
1269 cpia2_set_property_mirror(cam, c->value);
1270 break;
1271 case V4L2_CID_VFLIP:
1272 cpia2_set_property_flip(cam, c->value);
1273 break;
1274 case CPIA2_CID_TARGET_KB:
1275 retval = cpia2_set_target_kb(cam, c->value);
1276 break;
1277 case CPIA2_CID_GPIO:
1278 retval = cpia2_set_gpio(cam, c->value);
1279 break;
1280 case CPIA2_CID_FLICKER_MODE:
1281 retval = cpia2_set_flicker_mode(cam,
1282 flicker_controls[c->value].value);
1283 break;
1284 case CPIA2_CID_FRAMERATE:
1285 retval = cpia2_set_fps(cam, framerate_controls[c->value].value);
1286 break;
1287 case CPIA2_CID_USB_ALT:
1288 retval = cpia2_usb_change_streaming_alternate(cam, c->value);
1289 break;
1290 case CPIA2_CID_LIGHTS:
1291 retval = cpia2_set_gpio(cam, lights_controls[c->value].value);
1292 break;
1293 case CPIA2_CID_RESET_CAMERA:
1294 cpia2_usb_stream_pause(cam);
1295 cpia2_reset_camera(cam);
1296 cpia2_usb_stream_resume(cam);
1297 break;
1298 default:
1299 retval = -EINVAL;
1300 }
1301
1302 return retval;
1303}
1304
1305/******************************************************************************
1306 *
1307 * ioctl_g_jpegcomp
1308 *
1309 * V4L2 get the JPEG compression parameters
1310 *
1311 *****************************************************************************/
1312
1313static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam)
1314{
1315 struct v4l2_jpegcompression *parms = arg;
1316
1317 memset(parms, 0, sizeof(*parms));
1318
1319 parms->quality = 80; // TODO: Can this be made meaningful?
1320
1321 parms->jpeg_markers = V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI;
1322 if(!cam->params.compression.inhibit_htables) {
1323 parms->jpeg_markers |= V4L2_JPEG_MARKER_DHT;
1324 }
1325
1326 parms->APPn = cam->APPn;
1327 parms->APP_len = cam->APP_len;
1328 if(cam->APP_len > 0) {
1329 memcpy(parms->APP_data, cam->APP_data, cam->APP_len);
1330 parms->jpeg_markers |= V4L2_JPEG_MARKER_APP;
1331 }
1332
1333 parms->COM_len = cam->COM_len;
1334 if(cam->COM_len > 0) {
1335 memcpy(parms->COM_data, cam->COM_data, cam->COM_len);
1336 parms->jpeg_markers |= JPEG_MARKER_COM;
1337 }
1338
1339 DBG("G_JPEGCOMP APP_len:%d COM_len:%d\n",
1340 parms->APP_len, parms->COM_len);
1341
1342 return 0;
1343}
1344
1345/******************************************************************************
1346 *
1347 * ioctl_s_jpegcomp
1348 *
1349 * V4L2 set the JPEG compression parameters
1350 * NOTE: quality and some jpeg_markers are ignored.
1351 *
1352 *****************************************************************************/
1353
1354static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam)
1355{
1356 struct v4l2_jpegcompression *parms = arg;
1357
1358 DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n",
1359 parms->APP_len, parms->COM_len);
1360
1361 cam->params.compression.inhibit_htables =
1362 !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT);
1363
1364 if(parms->APP_len != 0) {
1365 if(parms->APP_len > 0 &&
1366 parms->APP_len <= sizeof(cam->APP_data) &&
1367 parms->APPn >= 0 && parms->APPn <= 15) {
1368 cam->APPn = parms->APPn;
1369 cam->APP_len = parms->APP_len;
1370 memcpy(cam->APP_data, parms->APP_data, parms->APP_len);
1371 } else {
1372 LOG("Bad APPn Params n=%d len=%d\n",
1373 parms->APPn, parms->APP_len);
1374 return -EINVAL;
1375 }
1376 } else {
1377 cam->APP_len = 0;
1378 }
1379
1380 if(parms->COM_len != 0) {
1381 if(parms->COM_len > 0 &&
1382 parms->COM_len <= sizeof(cam->COM_data)) {
1383 cam->COM_len = parms->COM_len;
1384 memcpy(cam->COM_data, parms->COM_data, parms->COM_len);
1385 } else {
1386 LOG("Bad COM_len=%d\n", parms->COM_len);
1387 return -EINVAL;
1388 }
1389 }
1390
1391 return 0;
1392}
1393
1394/******************************************************************************
1395 *
1396 * ioctl_reqbufs
1397 *
1398 * V4L2 Initiate memory mapping.
1399 * NOTE: The user's request is ignored. For now the buffers are fixed.
1400 *
1401 *****************************************************************************/
1402
1403static int ioctl_reqbufs(void *arg,struct camera_data *cam)
1404{
1405 struct v4l2_requestbuffers *req = arg;
1406
1407 if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1408 req->memory != V4L2_MEMORY_MMAP)
1409 return -EINVAL;
1410
1411 DBG("REQBUFS requested:%d returning:%d\n", req->count, cam->num_frames);
1412 req->count = cam->num_frames;
1413 memset(&req->reserved, 0, sizeof(req->reserved));
1414
1415 return 0;
1416}
1417
1418/******************************************************************************
1419 *
1420 * ioctl_querybuf
1421 *
1422 * V4L2 Query memory buffer status.
1423 *
1424 *****************************************************************************/
1425
1426static int ioctl_querybuf(void *arg,struct camera_data *cam)
1427{
1428 struct v4l2_buffer *buf = arg;
1429
1430 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1431 buf->index > cam->num_frames)
1432 return -EINVAL;
1433
1434 buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
1435 buf->length = cam->frame_size;
1436
1437 buf->memory = V4L2_MEMORY_MMAP;
1438
1439 if(cam->mmapped)
1440 buf->flags = V4L2_BUF_FLAG_MAPPED;
1441 else
1442 buf->flags = 0;
1443
1444 switch (cam->buffers[buf->index].status) {
1445 case FRAME_EMPTY:
1446 case FRAME_ERROR:
1447 case FRAME_READING:
1448 buf->bytesused = 0;
1449 buf->flags = V4L2_BUF_FLAG_QUEUED;
1450 break;
1451 case FRAME_READY:
1452 buf->bytesused = cam->buffers[buf->index].length;
1453 buf->timestamp = cam->buffers[buf->index].timestamp;
1454 buf->sequence = cam->buffers[buf->index].seq;
1455 buf->flags = V4L2_BUF_FLAG_DONE;
1456 break;
1457 }
1458
1459 DBG("QUERYBUF index:%d offset:%d flags:%d seq:%d bytesused:%d\n",
1460 buf->index, buf->m.offset, buf->flags, buf->sequence,
1461 buf->bytesused);
1462
1463 return 0;
1464}
1465
1466/******************************************************************************
1467 *
1468 * ioctl_qbuf
1469 *
1470 * V4L2 User is freeing buffer
1471 *
1472 *****************************************************************************/
1473
1474static int ioctl_qbuf(void *arg,struct camera_data *cam)
1475{
1476 struct v4l2_buffer *buf = arg;
1477
1478 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1479 buf->memory != V4L2_MEMORY_MMAP ||
1480 buf->index > cam->num_frames)
1481 return -EINVAL;
1482
1483 DBG("QBUF #%d\n", buf->index);
1484
1485 if(cam->buffers[buf->index].status == FRAME_READY)
1486 cam->buffers[buf->index].status = FRAME_EMPTY;
1487
1488 return 0;
1489}
1490
1491/******************************************************************************
1492 *
1493 * find_earliest_filled_buffer
1494 *
1495 * Helper for ioctl_dqbuf. Find the next ready buffer.
1496 *
1497 *****************************************************************************/
1498
1499static int find_earliest_filled_buffer(struct camera_data *cam)
1500{
1501 int i;
1502 int found = -1;
1503 for (i=0; i<cam->num_frames; i++) {
1504 if(cam->buffers[i].status == FRAME_READY) {
1505 if(found < 0) {
1506 found = i;
1507 } else {
1508 /* find which buffer is earlier */
1509 struct timeval *tv1, *tv2;
1510 tv1 = &cam->buffers[i].timestamp;
1511 tv2 = &cam->buffers[found].timestamp;
1512 if(tv1->tv_sec < tv2->tv_sec ||
1513 (tv1->tv_sec == tv2->tv_sec &&
1514 tv1->tv_usec < tv2->tv_usec))
1515 found = i;
1516 }
1517 }
1518 }
1519 return found;
1520}
1521
1522/******************************************************************************
1523 *
1524 * ioctl_dqbuf
1525 *
1526 * V4L2 User is asking for a filled buffer.
1527 *
1528 *****************************************************************************/
1529
1530static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
1531{
1532 struct v4l2_buffer *buf = arg;
1533 int frame;
1534
1535 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1536 buf->memory != V4L2_MEMORY_MMAP)
1537 return -EINVAL;
1538
1539 frame = find_earliest_filled_buffer(cam);
1540
1541 if(frame < 0 && file->f_flags&O_NONBLOCK)
1542 return -EAGAIN;
1543
1544 if(frame < 0) {
1545 /* Wait for a frame to become available */
1546 struct framebuf *cb=cam->curbuff;
1547 up(&cam->busy_lock);
1548 wait_event_interruptible(cam->wq_stream,
1549 !cam->present ||
1550 (cb=cam->curbuff)->status == FRAME_READY);
1551 down(&cam->busy_lock);
1552 if (signal_pending(current))
1553 return -ERESTARTSYS;
1554 if(!cam->present)
1555 return -ENOTTY;
1556 frame = cb->num;
1557 }
1558
1559
1560 buf->index = frame;
1561 buf->bytesused = cam->buffers[buf->index].length;
1562 buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
1563 buf->field = V4L2_FIELD_NONE;
1564 buf->timestamp = cam->buffers[buf->index].timestamp;
1565 buf->sequence = cam->buffers[buf->index].seq;
1566 buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
1567 buf->length = cam->frame_size;
1568 buf->input = 0;
1569 buf->reserved = 0;
1570 memset(&buf->timecode, 0, sizeof(buf->timecode));
1571
1572 DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index,
1573 cam->buffers[buf->index].status, buf->sequence, buf->bytesused);
1574
1575 return 0;
1576}
1577
1578/******************************************************************************
1579 *
1580 * cpia2_ioctl
1581 *
1582 *****************************************************************************/
1583static int cpia2_do_ioctl(struct inode *inode, struct file *file,
1584 unsigned int ioctl_nr, void *arg)
1585{
1586 struct video_device *dev = video_devdata(file);
1587 struct camera_data *cam = video_get_drvdata(dev);
1588 int retval = 0;
1589
1590 if (!cam)
1591 return -ENOTTY;
1592
1593 /* make this _really_ smp-safe */
1594 if (down_interruptible(&cam->busy_lock))
1595 return -ERESTARTSYS;
1596
1597 if (!cam->present) {
1598 up(&cam->busy_lock);
1599 return -ENODEV;
1600 }
1601
1602 /* Priority check */
1603 switch (ioctl_nr) {
1604 case VIDIOCSWIN:
1605 case VIDIOCMCAPTURE:
1606 case VIDIOC_S_FMT:
1607 {
1608 struct cpia2_fh *fh = file->private_data;
1609 retval = v4l2_prio_check(&cam->prio, &fh->prio);
1610 if(retval) {
1611 up(&cam->busy_lock);
1612 return retval;
1613 }
1614 break;
1615 }
1616 case VIDIOCGMBUF:
1617 case VIDIOCSYNC:
1618 {
1619 struct cpia2_fh *fh = file->private_data;
1620 if(fh->prio != V4L2_PRIORITY_RECORD) {
1621 up(&cam->busy_lock);
1622 return -EBUSY;
1623 }
1624 break;
1625 }
1626 default:
1627 break;
1628 }
1629
1630 switch (ioctl_nr) {
1631 case VIDIOCGCAP: /* query capabilites */
1632 retval = ioctl_cap_query(arg, cam);
1633 break;
1634
1635 case VIDIOCGCHAN: /* get video source - we are a camera, nothing else */
1636 retval = ioctl_get_channel(arg);
1637 break;
1638 case VIDIOCSCHAN: /* set video source - we are a camera, nothing else */
1639 retval = ioctl_set_channel(arg);
1640 break;
1641 case VIDIOCGPICT: /* image properties */
1642 memcpy(arg, &cam->vp, sizeof(struct video_picture));
1643 break;
1644 case VIDIOCSPICT:
1645 retval = ioctl_set_image_prop(arg, cam);
1646 break;
1647 case VIDIOCGWIN: /* get/set capture window */
1648 memcpy(arg, &cam->vw, sizeof(struct video_window));
1649 break;
1650 case VIDIOCSWIN:
1651 retval = ioctl_set_window_size(arg, cam, file->private_data);
1652 break;
1653 case VIDIOCGMBUF: /* mmap interface */
1654 retval = ioctl_get_mbuf(arg, cam);
1655 break;
1656 case VIDIOCMCAPTURE:
1657 retval = ioctl_mcapture(arg, cam, file->private_data);
1658 break;
1659 case VIDIOCSYNC:
1660 retval = ioctl_sync(arg, cam);
1661 break;
1662 /* pointless to implement overlay with this camera */
1663 case VIDIOCCAPTURE:
1664 case VIDIOCGFBUF:
1665 case VIDIOCSFBUF:
1666 case VIDIOCKEY:
1667 retval = -EINVAL;
1668 break;
1669
1670 /* tuner interface - we have none */
1671 case VIDIOCGTUNER:
1672 case VIDIOCSTUNER:
1673 case VIDIOCGFREQ:
1674 case VIDIOCSFREQ:
1675 retval = -EINVAL;
1676 break;
1677
1678 /* audio interface - we have none */
1679 case VIDIOCGAUDIO:
1680 case VIDIOCSAUDIO:
1681 retval = -EINVAL;
1682 break;
1683
1684 /* CPIA2 extension to Video4Linux API */
1685 case CPIA2_IOC_SET_GPIO:
1686 retval = ioctl_set_gpio(arg, cam);
1687 break;
1688 case VIDIOC_QUERYCAP:
1689 retval = ioctl_querycap(arg,cam);
1690 break;
1691
1692 case VIDIOC_ENUMINPUT:
1693 case VIDIOC_G_INPUT:
1694 case VIDIOC_S_INPUT:
1695 retval = ioctl_input(ioctl_nr, arg,cam);
1696 break;
1697
1698 case VIDIOC_ENUM_FMT:
1699 retval = ioctl_enum_fmt(arg,cam);
1700 break;
1701 case VIDIOC_TRY_FMT:
1702 retval = ioctl_try_fmt(arg,cam);
1703 break;
1704 case VIDIOC_G_FMT:
1705 retval = ioctl_get_fmt(arg,cam);
1706 break;
1707 case VIDIOC_S_FMT:
1708 retval = ioctl_set_fmt(arg,cam,file->private_data);
1709 break;
1710
1711 case VIDIOC_CROPCAP:
1712 retval = ioctl_cropcap(arg,cam);
1713 break;
1714 case VIDIOC_G_CROP:
1715 case VIDIOC_S_CROP:
1716 // TODO: I think cropping can be implemented - SJB
1717 retval = -EINVAL;
1718 break;
1719
1720 case VIDIOC_QUERYCTRL:
1721 retval = ioctl_queryctrl(arg,cam);
1722 break;
1723 case VIDIOC_QUERYMENU:
1724 retval = ioctl_querymenu(arg,cam);
1725 break;
1726 case VIDIOC_G_CTRL:
1727 retval = ioctl_g_ctrl(arg,cam);
1728 break;
1729 case VIDIOC_S_CTRL:
1730 retval = ioctl_s_ctrl(arg,cam);
1731 break;
1732
1733 case VIDIOC_G_JPEGCOMP:
1734 retval = ioctl_g_jpegcomp(arg,cam);
1735 break;
1736 case VIDIOC_S_JPEGCOMP:
1737 retval = ioctl_s_jpegcomp(arg,cam);
1738 break;
1739
1740 case VIDIOC_G_PRIORITY:
1741 {
1742 struct cpia2_fh *fh = file->private_data;
1743 *(enum v4l2_priority*)arg = fh->prio;
1744 break;
1745 }
1746 case VIDIOC_S_PRIORITY:
1747 {
1748 struct cpia2_fh *fh = file->private_data;
1749 enum v4l2_priority prio;
1750 prio = *(enum v4l2_priority*)arg;
1751 if(cam->streaming &&
1752 prio != fh->prio &&
1753 fh->prio == V4L2_PRIORITY_RECORD) {
1754 /* Can't drop record priority while streaming */
1755 retval = -EBUSY;
1756 } else if(prio == V4L2_PRIORITY_RECORD &&
1757 prio != fh->prio &&
1758 v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) {
1759 /* Only one program can record at a time */
1760 retval = -EBUSY;
1761 } else {
1762 retval = v4l2_prio_change(&cam->prio, &fh->prio, prio);
1763 }
1764 break;
1765 }
1766
1767 case VIDIOC_REQBUFS:
1768 retval = ioctl_reqbufs(arg,cam);
1769 break;
1770 case VIDIOC_QUERYBUF:
1771 retval = ioctl_querybuf(arg,cam);
1772 break;
1773 case VIDIOC_QBUF:
1774 retval = ioctl_qbuf(arg,cam);
1775 break;
1776 case VIDIOC_DQBUF:
1777 retval = ioctl_dqbuf(arg,cam,file);
1778 break;
1779 case VIDIOC_STREAMON:
1780 {
1781 int type;
1782 DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming);
1783 type = *(int*)arg;
1784 if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1785 retval = -EINVAL;
1786
1787 if(!cam->streaming) {
1788 retval = cpia2_usb_stream_start(cam,
1789 cam->params.camera_state.stream_mode);
1790 } else {
1791 retval = -EINVAL;
1792 }
1793
1794 break;
1795 }
1796 case VIDIOC_STREAMOFF:
1797 {
1798 int type;
1799 DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming);
1800 type = *(int*)arg;
1801 if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1802 retval = -EINVAL;
1803
1804 if(cam->streaming) {
1805 retval = cpia2_usb_stream_stop(cam);
1806 } else {
1807 retval = -EINVAL;
1808 }
1809
1810 break;
1811 }
1812
1813 case VIDIOC_ENUMOUTPUT:
1814 case VIDIOC_G_OUTPUT:
1815 case VIDIOC_S_OUTPUT:
1816 case VIDIOC_G_MODULATOR:
1817 case VIDIOC_S_MODULATOR:
1818
1819 case VIDIOC_ENUMAUDIO:
1820 case VIDIOC_G_AUDIO:
1821 case VIDIOC_S_AUDIO:
1822
1823 case VIDIOC_ENUMAUDOUT:
1824 case VIDIOC_G_AUDOUT:
1825 case VIDIOC_S_AUDOUT:
1826
1827 case VIDIOC_ENUMSTD:
1828 case VIDIOC_QUERYSTD:
1829 case VIDIOC_G_STD:
1830 case VIDIOC_S_STD:
1831
1832 case VIDIOC_G_TUNER:
1833 case VIDIOC_S_TUNER:
1834 case VIDIOC_G_FREQUENCY:
1835 case VIDIOC_S_FREQUENCY:
1836
1837 case VIDIOC_OVERLAY:
1838 case VIDIOC_G_FBUF:
1839 case VIDIOC_S_FBUF:
1840
1841 case VIDIOC_G_PARM:
1842 case VIDIOC_S_PARM:
1843 retval = -EINVAL;
1844 break;
1845 default:
1846 retval = -ENOIOCTLCMD;
1847 break;
1848 }
1849
1850 up(&cam->busy_lock);
1851 return retval;
1852}
1853
1854static int cpia2_ioctl(struct inode *inode, struct file *file,
1855 unsigned int ioctl_nr, unsigned long iarg)
1856{
1857 return video_usercopy(inode, file, ioctl_nr, iarg, cpia2_do_ioctl);
1858}
1859
1860/******************************************************************************
1861 *
1862 * cpia2_mmap
1863 *
1864 *****************************************************************************/
1865static int cpia2_mmap(struct file *file, struct vm_area_struct *area)
1866{
1867 int retval;
1868 struct video_device *dev = video_devdata(file);
1869 struct camera_data *cam = video_get_drvdata(dev);
1870
1871 /* Priority check */
1872 struct cpia2_fh *fh = file->private_data;
1873 if(fh->prio != V4L2_PRIORITY_RECORD) {
1874 return -EBUSY;
1875 }
1876
1877 retval = cpia2_remap_buffer(cam, area);
1878
1879 if(!retval)
1880 fh->mmapped = 1;
1881 return retval;
1882}
1883
1884/******************************************************************************
1885 *
1886 * reset_camera_struct_v4l
1887 *
1888 * Sets all values to the defaults
1889 *****************************************************************************/
1890static void reset_camera_struct_v4l(struct camera_data *cam)
1891{
1892 /***
1893 * Fill in the v4l structures. video_cap is filled in inside the VIDIOCCAP
1894 * Ioctl. Here, just do the window and picture stucts.
1895 ***/
1896 cam->vp.palette = (u16) VIDEO_PALETTE_RGB24; /* Is this right? */
1897 cam->vp.brightness = (u16) cam->params.color_params.brightness * 256;
1898 cam->vp.colour = (u16) cam->params.color_params.saturation * 256;
1899 cam->vp.contrast = (u16) cam->params.color_params.contrast * 256;
1900
1901 cam->vw.x = 0;
1902 cam->vw.y = 0;
1903 cam->vw.width = cam->params.roi.width;
1904 cam->vw.height = cam->params.roi.height;
1905 cam->vw.flags = 0;
1906 cam->vw.clipcount = 0;
1907
1908 cam->frame_size = buffer_size;
1909 cam->num_frames = num_buffers;
1910
1911 /* FlickerModes */
1912 cam->params.flicker_control.flicker_mode_req = flicker_mode;
1913 cam->params.flicker_control.mains_frequency = flicker_freq;
1914
1915 /* streamMode */
1916 cam->params.camera_state.stream_mode = alternate;
1917
1918 cam->pixelformat = V4L2_PIX_FMT_JPEG;
1919 v4l2_prio_init(&cam->prio);
1920 return;
1921}
1922
1923/***
1924 * The v4l video device structure initialized for this device
1925 ***/
1926static struct file_operations fops_template = {
1927 .owner= THIS_MODULE,
1928 .open= cpia2_open,
1929 .release= cpia2_close,
1930 .read= cpia2_v4l_read,
1931 .poll= cpia2_v4l_poll,
1932 .ioctl= cpia2_ioctl,
1933 .llseek= no_llseek,
1934 .mmap= cpia2_mmap,
1935};
1936
1937static struct video_device cpia2_template = {
1938 /* I could not find any place for the old .initialize initializer?? */
1939 .owner= THIS_MODULE,
1940 .name= "CPiA2 Camera",
1941 .type= VID_TYPE_CAPTURE,
1942 .type2 = V4L2_CAP_VIDEO_CAPTURE |
1943 V4L2_CAP_STREAMING,
1944 .hardware= VID_HARDWARE_CPIA2,
1945 .minor= -1,
1946 .fops= &fops_template,
1947 .release= video_device_release,
1948};
1949
1950/******************************************************************************
1951 *
1952 * cpia2_register_camera
1953 *
1954 *****************************************************************************/
1955int cpia2_register_camera(struct camera_data *cam)
1956{
1957 cam->vdev = video_device_alloc();
1958 if(!cam->vdev)
1959 return -ENOMEM;
1960
1961 memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template));
1962 video_set_drvdata(cam->vdev, cam);
1963
1964 reset_camera_struct_v4l(cam);
1965
1966 /* register v4l device */
1967 if (video_register_device
1968 (cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1969 ERR("video_register_device failed\n");
1970 video_device_release(cam->vdev);
1971 return -ENODEV;
1972 }
1973
1974 return 0;
1975}
1976
1977/******************************************************************************
1978 *
1979 * cpia2_unregister_camera
1980 *
1981 *****************************************************************************/
1982void cpia2_unregister_camera(struct camera_data *cam)
1983{
1984 if (!cam->open_count) {
1985 video_unregister_device(cam->vdev);
1986 } else {
1987 LOG("/dev/video%d removed while open, "
1988 "deferring video_unregister_device\n",
1989 cam->vdev->minor);
1990 }
1991}
1992
1993/******************************************************************************
1994 *
1995 * check_parameters
1996 *
1997 * Make sure that all user-supplied parameters are sensible
1998 *****************************************************************************/
1999static void __init check_parameters(void)
2000{
2001 if(buffer_size < PAGE_SIZE) {
2002 buffer_size = PAGE_SIZE;
2003 LOG("buffer_size too small, setting to %d\n", buffer_size);
2004 } else if(buffer_size > 1024*1024) {
2005 /* arbitrary upper limiit */
2006 buffer_size = 1024*1024;
2007 LOG("buffer_size ridiculously large, setting to %d\n",
2008 buffer_size);
2009 } else {
2010 buffer_size += PAGE_SIZE-1;
2011 buffer_size &= ~(PAGE_SIZE-1);
2012 }
2013
2014 if(num_buffers < 1) {
2015 num_buffers = 1;
2016 LOG("num_buffers too small, setting to %d\n", num_buffers);
2017 } else if(num_buffers > VIDEO_MAX_FRAME) {
2018 num_buffers = VIDEO_MAX_FRAME;
2019 LOG("num_buffers too large, setting to %d\n", num_buffers);
2020 }
2021
2022 if(alternate < USBIF_ISO_1 || alternate > USBIF_ISO_6) {
2023 alternate = DEFAULT_ALT;
2024 LOG("alternate specified is invalid, using %d\n", alternate);
2025 }
2026
2027 if (flicker_mode != NEVER_FLICKER && flicker_mode != ANTI_FLICKER_ON) {
2028 flicker_mode = NEVER_FLICKER;
2029 LOG("Flicker mode specified is invalid, using %d\n",
2030 flicker_mode);
2031 }
2032
2033 if (flicker_freq != FLICKER_50 && flicker_freq != FLICKER_60) {
2034 flicker_freq = FLICKER_60;
2035 LOG("Flicker mode specified is invalid, using %d\n",
2036 flicker_freq);
2037 }
2038
2039 if(video_nr < -1 || video_nr > 64) {
2040 video_nr = -1;
2041 LOG("invalid video_nr specified, must be -1 to 64\n");
2042 }
2043
2044 DBG("Using %d buffers, each %d bytes, alternate=%d\n",
2045 num_buffers, buffer_size, alternate);
2046}
2047
2048/************ Module Stuff ***************/
2049
2050
2051/******************************************************************************
2052 *
2053 * cpia2_init/module_init
2054 *
2055 *****************************************************************************/
2056int __init cpia2_init(void)
2057{
2058 LOG("%s v%d.%d.%d\n",
2059 ABOUT, CPIA2_MAJ_VER, CPIA2_MIN_VER, CPIA2_PATCH_VER);
2060 check_parameters();
2061 cpia2_usb_init();
2062 return 0;
2063}
2064
2065
2066/******************************************************************************
2067 *
2068 * cpia2_exit/module_exit
2069 *
2070 *****************************************************************************/
2071void __exit cpia2_exit(void)
2072{
2073 cpia2_usb_cleanup();
2074 schedule_timeout(2 * HZ);
2075}
2076
2077
2078int __init cpia2_setup(char *str)
2079{
2080 while(str) {
2081 if(!strncmp(str, "buffer_size:", 12)) {
2082 buffer_size = simple_strtoul(str + 13, &str, 10);
2083 } else if(!strncmp(str, "num_buffers:", 12)) {
2084 num_buffers = simple_strtoul(str + 13, &str, 10);
2085 } else if(!strncmp(str, "alternate:", 10)) {
2086 alternate = simple_strtoul(str + 11, &str, 10);
2087 } else if(!strncmp(str, "video_nr:", 9)) {
2088 video_nr = simple_strtoul(str + 10, &str, 10);
2089 } else if(!strncmp(str, "flicker_freq:",13)) {
2090 flicker_freq = simple_strtoul(str + 14, &str, 10);
2091 } else if(!strncmp(str, "flicker_mode:",13)) {
2092 flicker_mode = simple_strtoul(str + 14, &str, 10);
2093 } else {
2094 ++str;
2095 }
2096 }
2097 return 1;
2098}
2099
2100__setup("cpia2=", cpia2_setup);
2101
2102module_init(cpia2_init);
2103module_exit(cpia2_exit);
2104
diff --git a/drivers/media/video/cpia2/cpia2dev.h b/drivers/media/video/cpia2/cpia2dev.h
new file mode 100644
index 000000000000..d58097ce0d5e
--- /dev/null
+++ b/drivers/media/video/cpia2/cpia2dev.h
@@ -0,0 +1,50 @@
1/****************************************************************************
2 *
3 * Filename: cpia2dev.h
4 *
5 * Copyright 2001, STMicrolectronics, Inc.
6 *
7 * Contact: steve.miller@st.com
8 *
9 * Description:
10 * This file provides definitions for applications wanting to use the
11 * cpia2 driver beyond the generic v4l capabilities.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 ****************************************************************************/
28
29#ifndef CPIA2_DEV_HEADER
30#define CPIA2_DEV_HEADER
31
32#include <linux/videodev.h>
33
34/***
35 * The following defines are ioctl numbers based on video4linux private ioctls,
36 * which can range from 192 (BASE_VIDIOCPRIVATE) to 255. All of these take int
37 * args
38 */
39#define CPIA2_IOC_SET_GPIO _IOW('v', BASE_VIDIOCPRIVATE + 17, __u32)
40
41/* V4L2 driver specific controls */
42#define CPIA2_CID_TARGET_KB (V4L2_CID_PRIVATE_BASE+0)
43#define CPIA2_CID_GPIO (V4L2_CID_PRIVATE_BASE+1)
44#define CPIA2_CID_FLICKER_MODE (V4L2_CID_PRIVATE_BASE+2)
45#define CPIA2_CID_FRAMERATE (V4L2_CID_PRIVATE_BASE+3)
46#define CPIA2_CID_USB_ALT (V4L2_CID_PRIVATE_BASE+4)
47#define CPIA2_CID_LIGHTS (V4L2_CID_PRIVATE_BASE+5)
48#define CPIA2_CID_RESET_CAMERA (V4L2_CID_PRIVATE_BASE+6)
49
50#endif
diff --git a/drivers/media/video/cpia2/cpia2patch.h b/drivers/media/video/cpia2/cpia2patch.h
new file mode 100644
index 000000000000..7f085fbe76fb
--- /dev/null
+++ b/drivers/media/video/cpia2/cpia2patch.h
@@ -0,0 +1,233 @@
1/****************************************************************************
2 *
3 * Filename: cpia2patch.h
4 *
5 * Copyright 2001, STMicrolectronics, Inc.
6 *
7 * Contact: steve.miller@st.com
8 *
9 * Description:
10 * This file contains patch data for the CPiA2 (stv0672) VP4.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 ****************************************************************************/
27
28#ifndef CPIA2_PATCH_HEADER
29#define CPIA2_PATCH_HEADER
30
31typedef struct {
32 unsigned char reg;
33 unsigned char count;
34 const unsigned char *data;
35} cpia2_patch;
36
37static const unsigned char start_address_hi[1] = {
38 0x01
39};
40
41static const unsigned char start_address_lo[1] = {
42 0xBC
43};
44
45static const unsigned char patch_block0[64] = {
46 0xE3, 0x02, 0xE3, 0x03, 0xE3, 0x04, 0xE3, 0x05,
47 0xE3, 0x06, 0xE3, 0x07, 0x93, 0x44, 0x56, 0xD4,
48 0x93, 0x4E, 0x56, 0x51, 0x93, 0x4E, 0x51, 0xD6,
49 0x93, 0x4E, 0x4F, 0x54, 0x93, 0x4E, 0x92, 0x4F,
50 0x92, 0xA4, 0x93, 0x05, 0x92, 0xF4, 0x93, 0x1B,
51 0x92, 0x92, 0x91, 0xE6, 0x92, 0x36, 0x92, 0x74,
52 0x92, 0x4A, 0x92, 0x8C, 0x92, 0x8E, 0xC8, 0xD0,
53 0x0B, 0x42, 0x02, 0xA0, 0xCA, 0x92, 0x09, 0x02
54};
55
56static const unsigned char patch_block1[64] = {
57 0xC9, 0x10, 0x0A, 0x0A, 0x0A, 0x81, 0xE3, 0xB8,
58 0xE3, 0xB0, 0xE3, 0xA8, 0xE3, 0xA0, 0xE3, 0x98,
59 0xE3, 0x90, 0xE1, 0x00, 0xCF, 0xD7, 0x0A, 0x12,
60 0xCC, 0x95, 0x08, 0xB2, 0x0A, 0x18, 0xE1, 0x00,
61 0x01, 0xEE, 0x0C, 0x08, 0x4A, 0x12, 0xC8, 0x18,
62 0xF0, 0x9A, 0xC0, 0x22, 0xF3, 0x1C, 0x4A, 0x13,
63 0xF3, 0x14, 0xC8, 0xA0, 0xF2, 0x14, 0xF2, 0x1C,
64 0xEB, 0x13, 0xD3, 0xA2, 0x63, 0x16, 0x48, 0x9E
65};
66
67static const unsigned char patch_block2[64] = {
68 0xF0, 0x18, 0xA4, 0x03, 0xF3, 0x93, 0xC0, 0x58,
69 0xF7, 0x13, 0x51, 0x9C, 0xE9, 0x20, 0xCF, 0xEF,
70 0x63, 0xF9, 0x92, 0x2E, 0xD3, 0x5F, 0x63, 0xFA,
71 0x92, 0x2E, 0xD3, 0x67, 0x63, 0xFB, 0x92, 0x2E,
72 0xD3, 0x6F, 0xE9, 0x1A, 0x63, 0x16, 0x48, 0xA7,
73 0xF0, 0x20, 0xA4, 0x06, 0xF3, 0x94, 0xC0, 0x27,
74 0xF7, 0x14, 0xF5, 0x13, 0x51, 0x9D, 0xF6, 0x13,
75 0x63, 0x18, 0xC4, 0x20, 0xCB, 0xEF, 0x63, 0xFC
76};
77
78static const unsigned char patch_block3[64] = {
79 0x92, 0x2E, 0xD3, 0x77, 0x63, 0xFD, 0x92, 0x2E,
80 0xD3, 0x7F, 0x63, 0xFE, 0x92, 0x2E, 0xD3, 0x87,
81 0x63, 0xFF, 0x92, 0x2E, 0xD3, 0x8F, 0x64, 0x38,
82 0x92, 0x2E, 0xD3, 0x97, 0x64, 0x39, 0x92, 0x2E,
83 0xD3, 0x9F, 0xE1, 0x00, 0xF5, 0x3A, 0xF4, 0x3B,
84 0xF7, 0xBF, 0xF2, 0xBC, 0xF2, 0x3D, 0xE1, 0x00,
85 0x80, 0x87, 0x90, 0x80, 0x51, 0xD5, 0x02, 0x22,
86 0x02, 0x32, 0x4B, 0xD3, 0xF7, 0x11, 0x0B, 0xDA
87};
88
89static const unsigned char patch_block4[64] = {
90 0xE1, 0x00, 0x0E, 0x02, 0x02, 0x40, 0x0D, 0xB5,
91 0xE3, 0x02, 0x48, 0x55, 0xE5, 0x12, 0xA4, 0x01,
92 0xE8, 0x1B, 0xE3, 0x90, 0xF0, 0x18, 0xA4, 0x01,
93 0xE8, 0xBF, 0x8D, 0xB8, 0x4B, 0xD1, 0x4B, 0xD8,
94 0x0B, 0xCB, 0x0B, 0xC2, 0xE1, 0x00, 0xE3, 0x02,
95 0xE3, 0x03, 0x52, 0xD3, 0x60, 0x59, 0xE6, 0x93,
96 0x0D, 0x22, 0x52, 0xD4, 0xE6, 0x93, 0x0D, 0x2A,
97 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, 0x02, 0x5D
98};
99
100static const unsigned char patch_block5[64] = {
101 0x02, 0x63, 0xE3, 0x02, 0xC8, 0x12, 0x02, 0xCA,
102 0xC8, 0x52, 0x02, 0xC2, 0x82, 0x68, 0xE3, 0x02,
103 0xC8, 0x14, 0x02, 0xCA, 0xC8, 0x90, 0x02, 0xC2,
104 0x0A, 0xD0, 0xC9, 0x93, 0x0A, 0xDA, 0xCC, 0xD2,
105 0x0A, 0xE2, 0x63, 0x12, 0x02, 0xDA, 0x0A, 0x98,
106 0x0A, 0xA0, 0x0A, 0xA8, 0xE3, 0x90, 0xE1, 0x00,
107 0xE3, 0x02, 0x0A, 0xD0, 0xC9, 0x93, 0x0A, 0xDA,
108 0xCC, 0xD2, 0x0A, 0xE2, 0x63, 0x12, 0x02, 0xDA
109};
110
111static const unsigned char patch_block6[64] = {
112 0x0A, 0x98, 0x0A, 0xA0, 0x0A, 0xA8, 0x49, 0x91,
113 0xE5, 0x6A, 0xA4, 0x04, 0xC8, 0x12, 0x02, 0xCA,
114 0xC8, 0x52, 0x82, 0x89, 0xC8, 0x14, 0x02, 0xCA,
115 0xC8, 0x90, 0x02, 0xC2, 0xE3, 0x90, 0xE1, 0x00,
116 0x08, 0x60, 0xE1, 0x00, 0x48, 0x53, 0xE8, 0x97,
117 0x08, 0x5A, 0xE1, 0x00, 0xE3, 0x02, 0xE3, 0x03,
118 0x54, 0xD3, 0x60, 0x59, 0xE6, 0x93, 0x0D, 0x52,
119 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, 0x02, 0x9C
120};
121
122static const unsigned char patch_block7[64] = {
123 0xE3, 0x02, 0x55, 0x13, 0x93, 0x17, 0x55, 0x13,
124 0x93, 0x17, 0xE3, 0x90, 0xE1, 0x00, 0x75, 0x30,
125 0xE3, 0x02, 0xE3, 0x03, 0x55, 0x55, 0x60, 0x59,
126 0xE6, 0x93, 0x0D, 0xB2, 0xE3, 0x98, 0xE3, 0x90,
127 0xE1, 0x00, 0x02, 0xAE, 0xE7, 0x92, 0xE9, 0x18,
128 0xEA, 0x9A, 0xE8, 0x98, 0xE8, 0x10, 0xE8, 0x11,
129 0xE8, 0x51, 0xD2, 0xDA, 0xD2, 0xF3, 0xE8, 0x13,
130 0xD2, 0xFA, 0xE8, 0x50, 0xD2, 0xEA, 0xE8, 0xD0
131};
132
133static const unsigned char patch_block8[64] = {
134 0xE8, 0xD1, 0xD3, 0x0A, 0x03, 0x09, 0x48, 0x23,
135 0xE5, 0x2C, 0xA0, 0x03, 0x48, 0x24, 0xEA, 0x1C,
136 0x03, 0x08, 0xD2, 0xE3, 0xD3, 0x03, 0xD3, 0x13,
137 0xE1, 0x00, 0x02, 0xCB, 0x05, 0x93, 0x57, 0x93,
138 0xF0, 0x9A, 0xAC, 0x0B, 0xE3, 0x07, 0x92, 0xEA,
139 0xE2, 0x9F, 0xE5, 0x06, 0xE3, 0xB0, 0xA0, 0x02,
140 0xEB, 0x1E, 0x82, 0xD7, 0xEA, 0x1E, 0xE2, 0x3B,
141 0x85, 0x9B, 0xE9, 0x1E, 0xC8, 0x90, 0x85, 0x94
142};
143
144static const unsigned char patch_block9[64] = {
145 0x02, 0xDE, 0x05, 0x80, 0x57, 0x93, 0xF0, 0xBA,
146 0xAC, 0x06, 0x92, 0xEA, 0xE2, 0xBF, 0xE5, 0x06,
147 0xA0, 0x01, 0xEB, 0xBF, 0x85, 0x88, 0xE9, 0x3E,
148 0xC8, 0x90, 0x85, 0x81, 0xE9, 0x3E, 0xF0, 0xBA,
149 0xF3, 0x39, 0xF0, 0x3A, 0x60, 0x17, 0xF0, 0x3A,
150 0xC0, 0x90, 0xF0, 0xBA, 0xE1, 0x00, 0x00, 0x3F,
151 0xE3, 0x02, 0xE3, 0x03, 0x58, 0x10, 0x60, 0x59,
152 0xE6, 0x93, 0x0D, 0xA2, 0x58, 0x12, 0xE6, 0x93
153};
154
155static const unsigned char patch_block10[64] = {
156 0x0D, 0xAA, 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00,
157 0x03, 0x01, 0xE1, 0x00, 0x03, 0x03, 0x9B, 0x7D,
158 0x8B, 0x8B, 0xE3, 0x02, 0xE3, 0x03, 0x58, 0x56,
159 0x60, 0x59, 0xE6, 0x93, 0x0D, 0xBA, 0xE3, 0x98,
160 0xE3, 0x90, 0xE1, 0x00, 0x03, 0x0F, 0x93, 0x11,
161 0xE1, 0x00, 0xE3, 0x02, 0x4A, 0x11, 0x0B, 0x42,
162 0x91, 0xAF, 0xE3, 0x90, 0xE1, 0x00, 0xF2, 0x91,
163 0xF0, 0x91, 0xA3, 0xFE, 0xE1, 0x00, 0x60, 0x92
164};
165
166static const unsigned char patch_block11[64] = {
167 0xC0, 0x5F, 0xF0, 0x13, 0xF0, 0x13, 0x59, 0x5B,
168 0xE2, 0x13, 0xF0, 0x11, 0x5A, 0x19, 0xE2, 0x13,
169 0xE1, 0x00, 0x00, 0x00, 0x03, 0x27, 0x68, 0x61,
170 0x76, 0x61, 0x6E, 0x61, 0x00, 0x06, 0x03, 0x2C,
171 0xE3, 0x02, 0xE3, 0x03, 0xE9, 0x38, 0x59, 0x15,
172 0x59, 0x5A, 0xF2, 0x9A, 0xBC, 0x0B, 0xA4, 0x0A,
173 0x59, 0x1E, 0xF3, 0x11, 0xF0, 0x1A, 0xE2, 0xBB,
174 0x59, 0x15, 0xF0, 0x11, 0x19, 0x2A, 0xE5, 0x02
175};
176
177static const unsigned char patch_block12[54] = {
178 0xA4, 0x01, 0xEB, 0xBF, 0xE3, 0x98, 0xE3, 0x90,
179 0xE1, 0x00, 0x03, 0x42, 0x19, 0x28, 0xE1, 0x00,
180 0xE9, 0x30, 0x60, 0x79, 0xE1, 0x00, 0xE3, 0x03,
181 0xE3, 0x07, 0x60, 0x79, 0x93, 0x4E, 0xE3, 0xB8,
182 0xE3, 0x98, 0xE1, 0x00, 0xE9, 0x1A, 0xF0, 0x1F,
183 0xE2, 0x33, 0xF0, 0x91, 0xE2, 0x92, 0xE0, 0x32,
184 0xF0, 0x31, 0xE1, 0x00, 0x00, 0x00
185};
186
187static const unsigned char do_call[1] = {
188 0x01
189};
190
191
192#define PATCH_DATA_SIZE 18
193
194static const cpia2_patch patch_data[PATCH_DATA_SIZE] = {
195 {0x0A, sizeof(start_address_hi), start_address_hi}
196 , // 0
197 {0x0B, sizeof(start_address_lo), start_address_lo}
198 , // 1
199 {0x0C, sizeof(patch_block0), patch_block0}
200 , // 2
201 {0x0C, sizeof(patch_block1), patch_block1}
202 , // 3
203 {0x0C, sizeof(patch_block2), patch_block2}
204 , // 4
205 {0x0C, sizeof(patch_block3), patch_block3}
206 , // 5
207 {0x0C, sizeof(patch_block4), patch_block4}
208 , // 6
209 {0x0C, sizeof(patch_block5), patch_block5}
210 , // 7
211 {0x0C, sizeof(patch_block6), patch_block6}
212 , // 8
213 {0x0C, sizeof(patch_block7), patch_block7}
214 , // 9
215 {0x0C, sizeof(patch_block8), patch_block8}
216 , // 10
217 {0x0C, sizeof(patch_block9), patch_block9}
218 , //11
219 {0x0C, sizeof(patch_block10), patch_block10}
220 , // 12
221 {0x0C, sizeof(patch_block11), patch_block11}
222 , // 13
223 {0x0C, sizeof(patch_block12), patch_block12}
224 , // 14
225 {0x0A, sizeof(start_address_hi), start_address_hi}
226 , // 15
227 {0x0B, sizeof(start_address_lo), start_address_lo}
228 , // 16
229 {0x0D, sizeof(do_call), do_call} //17
230};
231
232
233#endif