aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cpia2
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/video/cpia2
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/media/video/cpia2')
-rw-r--r--drivers/media/video/cpia2/Kconfig9
-rw-r--r--drivers/media/video/cpia2/Makefile3
-rw-r--r--drivers/media/video/cpia2/cpia2.h489
-rw-r--r--drivers/media/video/cpia2/cpia2_core.c2493
-rw-r--r--drivers/media/video/cpia2/cpia2_registers.h476
-rw-r--r--drivers/media/video/cpia2/cpia2_usb.c914
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c1578
-rw-r--r--drivers/media/video/cpia2/cpia2dev.h50
8 files changed, 6012 insertions, 0 deletions
diff --git a/drivers/media/video/cpia2/Kconfig b/drivers/media/video/cpia2/Kconfig
new file mode 100644
index 00000000000..66e9283f599
--- /dev/null
+++ b/drivers/media/video/cpia2/Kconfig
@@ -0,0 +1,9 @@
1config VIDEO_CPIA2
2 tristate "CPiA2 Video For Linux"
3 depends on VIDEO_DEV && USB && VIDEO_V4L2
4 ---help---
5 This is the video4linux driver for cameras based on Vision's CPiA2
6 (Colour Processor Interface ASIC), such as the Digital Blue QX5
7 Microscope. If you have one of these cameras, say Y here
8
9 This driver is also available as a module (cpia2).
diff --git a/drivers/media/video/cpia2/Makefile b/drivers/media/video/cpia2/Makefile
new file mode 100644
index 00000000000..828cf1b1df8
--- /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 00000000000..ab252188981
--- /dev/null
+++ b/drivers/media/video/cpia2/cpia2.h
@@ -0,0 +1,489 @@
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/videodev2.h>
35#include <media/v4l2-common.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/***
46 * Image defines
47 ***/
48
49/* Misc constants */
50#define ALLOW_CORRUPT 0 /* Causes collater to discard checksum */
51
52/* USB Transfer mode */
53#define XFER_ISOC 0
54#define XFER_BULK 1
55
56/* USB Alternates */
57#define USBIF_CMDONLY 0
58#define USBIF_BULK 1
59#define USBIF_ISO_1 2 /* 128 bytes/ms */
60#define USBIF_ISO_2 3 /* 384 bytes/ms */
61#define USBIF_ISO_3 4 /* 640 bytes/ms */
62#define USBIF_ISO_4 5 /* 768 bytes/ms */
63#define USBIF_ISO_5 6 /* 896 bytes/ms */
64#define USBIF_ISO_6 7 /* 1023 bytes/ms */
65
66/* Flicker Modes */
67#define NEVER_FLICKER 0
68#define ANTI_FLICKER_ON 1
69#define FLICKER_60 60
70#define FLICKER_50 50
71
72/* Debug flags */
73#define DEBUG_NONE 0
74#define DEBUG_REG 0x00000001
75#define DEBUG_DUMP_PATCH 0x00000002
76#define DEBUG_DUMP_REGS 0x00000004
77
78/***
79 * Video frame sizes
80 ***/
81enum {
82 VIDEOSIZE_VGA = 0, /* 640x480 */
83 VIDEOSIZE_CIF, /* 352x288 */
84 VIDEOSIZE_QVGA, /* 320x240 */
85 VIDEOSIZE_QCIF, /* 176x144 */
86 VIDEOSIZE_288_216,
87 VIDEOSIZE_256_192,
88 VIDEOSIZE_224_168,
89 VIDEOSIZE_192_144,
90};
91
92#define STV_IMAGE_CIF_ROWS 288
93#define STV_IMAGE_CIF_COLS 352
94
95#define STV_IMAGE_QCIF_ROWS 144
96#define STV_IMAGE_QCIF_COLS 176
97
98#define STV_IMAGE_VGA_ROWS 480
99#define STV_IMAGE_VGA_COLS 640
100
101#define STV_IMAGE_QVGA_ROWS 240
102#define STV_IMAGE_QVGA_COLS 320
103
104#define JPEG_MARKER_COM (1<<6) /* Comment segment */
105
106/***
107 * Enums
108 ***/
109/* Sensor types available with cpia2 asics */
110enum sensors {
111 CPIA2_SENSOR_410,
112 CPIA2_SENSOR_500
113};
114
115/* Asic types available in the CPiA2 architecture */
116#define CPIA2_ASIC_672 0x67
117
118/* Device types (stv672, stv676, etc) */
119#define DEVICE_STV_672 0x0001
120#define DEVICE_STV_676 0x0002
121
122enum frame_status {
123 FRAME_EMPTY,
124 FRAME_READING, /* In the process of being grabbed into */
125 FRAME_READY, /* Ready to be read */
126 FRAME_ERROR,
127};
128
129/***
130 * Register access (for USB request byte)
131 ***/
132enum {
133 CAMERAACCESS_SYSTEM = 0,
134 CAMERAACCESS_VC,
135 CAMERAACCESS_VP,
136 CAMERAACCESS_IDATA
137};
138
139#define CAMERAACCESS_TYPE_BLOCK 0x00
140#define CAMERAACCESS_TYPE_RANDOM 0x04
141#define CAMERAACCESS_TYPE_MASK 0x08
142#define CAMERAACCESS_TYPE_REPEAT 0x0C
143
144#define TRANSFER_READ 0
145#define TRANSFER_WRITE 1
146
147#define DEFAULT_ALT USBIF_ISO_6
148#define DEFAULT_BRIGHTNESS 0x46
149#define DEFAULT_CONTRAST 0x93
150#define DEFAULT_SATURATION 0x7f
151#define DEFAULT_TARGET_KB 0x30
152
153/* Power state */
154#define HI_POWER_MODE CPIA2_SYSTEM_CONTROL_HIGH_POWER
155#define LO_POWER_MODE CPIA2_SYSTEM_CONTROL_LOW_POWER
156
157
158/********
159 * Commands
160 *******/
161enum {
162 CPIA2_CMD_NONE = 0,
163 CPIA2_CMD_GET_VERSION,
164 CPIA2_CMD_GET_PNP_ID,
165 CPIA2_CMD_GET_ASIC_TYPE,
166 CPIA2_CMD_GET_SENSOR,
167 CPIA2_CMD_GET_VP_DEVICE,
168 CPIA2_CMD_GET_VP_BRIGHTNESS,
169 CPIA2_CMD_SET_VP_BRIGHTNESS,
170 CPIA2_CMD_GET_CONTRAST,
171 CPIA2_CMD_SET_CONTRAST,
172 CPIA2_CMD_GET_VP_SATURATION,
173 CPIA2_CMD_SET_VP_SATURATION,
174 CPIA2_CMD_GET_VP_GPIO_DIRECTION,
175 CPIA2_CMD_SET_VP_GPIO_DIRECTION,
176 CPIA2_CMD_GET_VP_GPIO_DATA,
177 CPIA2_CMD_SET_VP_GPIO_DATA,
178 CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION,
179 CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
180 CPIA2_CMD_GET_VC_MP_GPIO_DATA,
181 CPIA2_CMD_SET_VC_MP_GPIO_DATA,
182 CPIA2_CMD_ENABLE_PACKET_CTRL,
183 CPIA2_CMD_GET_FLICKER_MODES,
184 CPIA2_CMD_SET_FLICKER_MODES,
185 CPIA2_CMD_RESET_FIFO, /* clear fifo and enable stream block */
186 CPIA2_CMD_SET_HI_POWER,
187 CPIA2_CMD_SET_LOW_POWER,
188 CPIA2_CMD_CLEAR_V2W_ERR,
189 CPIA2_CMD_SET_USER_MODE,
190 CPIA2_CMD_GET_USER_MODE,
191 CPIA2_CMD_FRAMERATE_REQ,
192 CPIA2_CMD_SET_COMPRESSION_STATE,
193 CPIA2_CMD_GET_WAKEUP,
194 CPIA2_CMD_SET_WAKEUP,
195 CPIA2_CMD_GET_PW_CONTROL,
196 CPIA2_CMD_SET_PW_CONTROL,
197 CPIA2_CMD_GET_SYSTEM_CTRL,
198 CPIA2_CMD_SET_SYSTEM_CTRL,
199 CPIA2_CMD_GET_VP_SYSTEM_STATE,
200 CPIA2_CMD_GET_VP_SYSTEM_CTRL,
201 CPIA2_CMD_SET_VP_SYSTEM_CTRL,
202 CPIA2_CMD_GET_VP_EXP_MODES,
203 CPIA2_CMD_SET_VP_EXP_MODES,
204 CPIA2_CMD_GET_DEVICE_CONFIG,
205 CPIA2_CMD_SET_DEVICE_CONFIG,
206 CPIA2_CMD_SET_SERIAL_ADDR,
207 CPIA2_CMD_SET_SENSOR_CR1,
208 CPIA2_CMD_GET_VC_CONTROL,
209 CPIA2_CMD_SET_VC_CONTROL,
210 CPIA2_CMD_SET_TARGET_KB,
211 CPIA2_CMD_SET_DEF_JPEG_OPT,
212 CPIA2_CMD_REHASH_VP4,
213 CPIA2_CMD_GET_USER_EFFECTS,
214 CPIA2_CMD_SET_USER_EFFECTS
215};
216
217enum user_cmd {
218 COMMAND_NONE = 0x00000001,
219 COMMAND_SET_FPS = 0x00000002,
220 COMMAND_SET_COLOR_PARAMS = 0x00000004,
221 COMMAND_GET_COLOR_PARAMS = 0x00000008,
222 COMMAND_SET_FORMAT = 0x00000010, /* size, etc */
223 COMMAND_SET_FLICKER = 0x00000020
224};
225
226/***
227 * Some defines specific to the 676 chip
228 ***/
229#define CAMACC_CIF 0x01
230#define CAMACC_VGA 0x02
231#define CAMACC_QCIF 0x04
232#define CAMACC_QVGA 0x08
233
234
235struct cpia2_register {
236 u8 index;
237 u8 value;
238};
239
240struct cpia2_reg_mask {
241 u8 index;
242 u8 and_mask;
243 u8 or_mask;
244 u8 fill;
245};
246
247struct cpia2_command {
248 u32 command;
249 u8 req_mode; /* (Block or random) | registerBank */
250 u8 reg_count;
251 u8 direction;
252 u8 start;
253 union reg_types {
254 struct cpia2_register registers[32];
255 struct cpia2_reg_mask masks[16];
256 u8 block_data[64];
257 u8 *patch_data; /* points to function defined block */
258 } buffer;
259};
260
261struct camera_params {
262 struct {
263 u8 firmware_revision_hi; /* For system register set (bank 0) */
264 u8 firmware_revision_lo;
265 u8 asic_id; /* Video Compressor set (bank 1) */
266 u8 asic_rev;
267 u8 vp_device_hi; /* Video Processor set (bank 2) */
268 u8 vp_device_lo;
269 u8 sensor_flags;
270 u8 sensor_rev;
271 } version;
272
273 struct {
274 u32 device_type; /* enumerated from vendor/product ids.
275 * Currently, either STV_672 or STV_676 */
276 u16 vendor;
277 u16 product;
278 u16 device_revision;
279 } pnp_id;
280
281 struct {
282 u8 brightness; /* CPIA2_VP_EXPOSURE_TARGET */
283 u8 contrast; /* Note: this is CPIA2_VP_YRANGE */
284 u8 saturation; /* CPIA2_VP_SATURATION */
285 } color_params;
286
287 struct {
288 u8 cam_register;
289 u8 flicker_mode_req; /* 1 if flicker on, else never flicker */
290 int mains_frequency;
291 } flicker_control;
292
293 struct {
294 u8 jpeg_options;
295 u8 creep_period;
296 u8 user_squeeze;
297 u8 inhibit_htables;
298 } compression;
299
300 struct {
301 u8 ohsize; /* output image size */
302 u8 ovsize;
303 u8 hcrop; /* cropping start_pos/4 */
304 u8 vcrop;
305 u8 hphase; /* scaling registers */
306 u8 vphase;
307 u8 hispan;
308 u8 vispan;
309 u8 hicrop;
310 u8 vicrop;
311 u8 hifraction;
312 u8 vifraction;
313 } image_size;
314
315 struct {
316 int width; /* actual window width */
317 int height; /* actual window height */
318 } roi;
319
320 struct {
321 u8 video_mode;
322 u8 frame_rate;
323 u8 video_size; /* Not a register, just a convenience for cropped sizes */
324 u8 gpio_direction;
325 u8 gpio_data;
326 u8 system_ctrl;
327 u8 system_state;
328 u8 lowlight_boost; /* Bool: 0 = off, 1 = on */
329 u8 device_config;
330 u8 exposure_modes;
331 u8 user_effects;
332 } vp_params;
333
334 struct {
335 u8 pw_control;
336 u8 wakeup;
337 u8 vc_control;
338 u8 vc_mp_direction;
339 u8 vc_mp_data;
340 u8 target_kb;
341 } vc_params;
342
343 struct {
344 u8 power_mode;
345 u8 system_ctrl;
346 u8 stream_mode; /* This is the current alternate for usb drivers */
347 u8 allow_corrupt;
348 } camera_state;
349};
350
351#define NUM_SBUF 2
352
353struct cpia2_sbuf {
354 char *data;
355 struct urb *urb;
356};
357
358struct framebuf {
359 struct timeval timestamp;
360 unsigned long seq;
361 int num;
362 int length;
363 int max_length;
364 volatile enum frame_status status;
365 u8 *data;
366 struct framebuf *next;
367};
368
369struct cpia2_fh {
370 enum v4l2_priority prio;
371 u8 mmapped;
372};
373
374struct camera_data {
375 /* locks */
376 struct mutex v4l2_lock; /* serialize file operations */
377 struct v4l2_prio_state prio;
378
379 /* camera status */
380 volatile int present; /* Is the camera still present? */
381 int open_count; /* # of process that have camera open */
382 int first_image_seen;
383 u8 mains_freq; /* for flicker control */
384 enum sensors sensor_type;
385 u8 flush;
386 u8 mmapped;
387 int streaming; /* 0 = no, 1 = yes */
388 int xfer_mode; /* XFER_BULK or XFER_ISOC */
389 struct camera_params params; /* camera settings */
390
391 /* v4l */
392 int video_size; /* VIDEO_SIZE_ */
393 struct video_device *vdev; /* v4l videodev */
394 u32 width;
395 u32 height; /* Its size */
396 __u32 pixelformat; /* Format fourcc */
397
398 /* USB */
399 struct usb_device *dev;
400 unsigned char iface;
401 unsigned int cur_alt;
402 unsigned int old_alt;
403 struct cpia2_sbuf sbuf[NUM_SBUF]; /* Double buffering */
404
405 wait_queue_head_t wq_stream;
406
407 /* Buffering */
408 u32 frame_size;
409 int num_frames;
410 unsigned long frame_count;
411 u8 *frame_buffer; /* frame buffer data */
412 struct framebuf *buffers;
413 struct framebuf * volatile curbuff;
414 struct framebuf *workbuff;
415
416 /* MJPEG Extension */
417 int APPn; /* Number of APP segment to be written, must be 0..15 */
418 int APP_len; /* Length of data in JPEG APPn segment */
419 char APP_data[60]; /* Data in the JPEG APPn segment. */
420
421 int COM_len; /* Length of data in JPEG COM segment */
422 char COM_data[60]; /* Data in JPEG COM segment */
423};
424
425/* v4l */
426int cpia2_register_camera(struct camera_data *cam);
427void cpia2_unregister_camera(struct camera_data *cam);
428
429/* core */
430int cpia2_reset_camera(struct camera_data *cam);
431int cpia2_set_low_power(struct camera_data *cam);
432void cpia2_dbg_dump_registers(struct camera_data *cam);
433int cpia2_match_video_size(int width, int height);
434void cpia2_set_camera_state(struct camera_data *cam);
435void cpia2_save_camera_state(struct camera_data *cam);
436void cpia2_set_color_params(struct camera_data *cam);
437void cpia2_set_brightness(struct camera_data *cam, unsigned char value);
438void cpia2_set_contrast(struct camera_data *cam, unsigned char value);
439void cpia2_set_saturation(struct camera_data *cam, unsigned char value);
440int cpia2_set_flicker_mode(struct camera_data *cam, int mode);
441void cpia2_set_format(struct camera_data *cam);
442int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd);
443int cpia2_do_command(struct camera_data *cam,
444 unsigned int command,
445 unsigned char direction, unsigned char param);
446struct camera_data *cpia2_init_camera_struct(void);
447int cpia2_init_camera(struct camera_data *cam);
448int cpia2_allocate_buffers(struct camera_data *cam);
449void cpia2_free_buffers(struct camera_data *cam);
450long cpia2_read(struct camera_data *cam,
451 char __user *buf, unsigned long count, int noblock);
452unsigned int cpia2_poll(struct camera_data *cam,
453 struct file *filp, poll_table *wait);
454int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma);
455void cpia2_set_property_flip(struct camera_data *cam, int prop_val);
456void cpia2_set_property_mirror(struct camera_data *cam, int prop_val);
457int cpia2_set_target_kb(struct camera_data *cam, unsigned char value);
458int cpia2_set_gpio(struct camera_data *cam, unsigned char setting);
459int cpia2_set_fps(struct camera_data *cam, int framerate);
460
461/* usb */
462int cpia2_usb_init(void);
463void cpia2_usb_cleanup(void);
464int cpia2_usb_transfer_cmd(struct camera_data *cam, void *registers,
465 u8 request, u8 start, u8 count, u8 direction);
466int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate);
467int cpia2_usb_stream_stop(struct camera_data *cam);
468int cpia2_usb_stream_pause(struct camera_data *cam);
469int cpia2_usb_stream_resume(struct camera_data *cam);
470int cpia2_usb_change_streaming_alternate(struct camera_data *cam,
471 unsigned int alt);
472
473
474/* ----------------------- debug functions ---------------------- */
475#ifdef _CPIA2_DEBUG_
476#define ALOG(lev, fmt, args...) printk(lev "%s:%d %s(): " fmt, __FILE__, __LINE__, __func__, ## args)
477#define LOG(fmt, args...) ALOG(KERN_INFO, fmt, ## args)
478#define ERR(fmt, args...) ALOG(KERN_ERR, fmt, ## args)
479#define DBG(fmt, args...) ALOG(KERN_DEBUG, fmt, ## args)
480#else
481#define ALOG(fmt,args...) printk(fmt,##args)
482#define LOG(fmt,args...) ALOG(KERN_INFO "cpia2: "fmt,##args)
483#define ERR(fmt,args...) ALOG(KERN_ERR "cpia2: "fmt,##args)
484#define DBG(fmn,args...) do {} while(0)
485#endif
486/* No function or lineno, for shorter lines */
487#define KINFO(fmt, args...) printk(KERN_INFO fmt,##args)
488
489#endif
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c
new file mode 100644
index 00000000000..ee91e295c90
--- /dev/null
+++ b/drivers/media/video/cpia2/cpia2_core.c
@@ -0,0 +1,2493 @@
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@lxorguk.ukuu.org.uk>
29 *
30 ****************************************************************************/
31
32#include "cpia2.h"
33
34#include <linux/slab.h>
35#include <linux/mm.h>
36#include <linux/vmalloc.h>
37#include <linux/firmware.h>
38
39/* #define _CPIA2_DEBUG_ */
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; /* default 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 *****************************************************************************/
522
523#define DIR(cmd) ((cmd->direction == TRANSFER_WRITE) ? "Write" : "Read")
524#define BINDEX(cmd) (cmd->req_mode & 0x03)
525
526int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd)
527{
528 u8 count;
529 u8 start;
530 u8 *buffer;
531 int retval;
532
533 switch (cmd->req_mode & 0x0c) {
534 case CAMERAACCESS_TYPE_RANDOM:
535 count = cmd->reg_count * sizeof(struct cpia2_register);
536 start = 0;
537 buffer = (u8 *) & cmd->buffer;
538 if (debugs_on & DEBUG_REG)
539 DBG("%s Random: Register block %s\n", DIR(cmd),
540 block_name[BINDEX(cmd)]);
541 break;
542 case CAMERAACCESS_TYPE_BLOCK:
543 count = cmd->reg_count;
544 start = cmd->start;
545 buffer = cmd->buffer.block_data;
546 if (debugs_on & DEBUG_REG)
547 DBG("%s Block: Register block %s\n", DIR(cmd),
548 block_name[BINDEX(cmd)]);
549 break;
550 case CAMERAACCESS_TYPE_MASK:
551 count = cmd->reg_count * sizeof(struct cpia2_reg_mask);
552 start = 0;
553 buffer = (u8 *) & cmd->buffer;
554 if (debugs_on & DEBUG_REG)
555 DBG("%s Mask: Register block %s\n", DIR(cmd),
556 block_name[BINDEX(cmd)]);
557 break;
558 case CAMERAACCESS_TYPE_REPEAT: /* For patch blocks only */
559 count = cmd->reg_count;
560 start = cmd->start;
561 buffer = cmd->buffer.block_data;
562 if (debugs_on & DEBUG_REG)
563 DBG("%s Repeat: Register block %s\n", DIR(cmd),
564 block_name[BINDEX(cmd)]);
565 break;
566 default:
567 LOG("%s: invalid request mode\n",__func__);
568 return -EINVAL;
569 }
570
571 retval = cpia2_usb_transfer_cmd(cam,
572 buffer,
573 cmd->req_mode,
574 start, count, cmd->direction);
575#ifdef _CPIA2_DEBUG_
576 if (debugs_on & DEBUG_REG) {
577 int i;
578 for (i = 0; i < cmd->reg_count; i++) {
579 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_BLOCK)
580 KINFO("%s Block: [0x%02X] = 0x%02X\n",
581 DIR(cmd), start + i, buffer[i]);
582 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_RANDOM)
583 KINFO("%s Random: [0x%02X] = 0x%02X\n",
584 DIR(cmd), cmd->buffer.registers[i].index,
585 cmd->buffer.registers[i].value);
586 }
587 }
588#endif
589
590 return retval;
591};
592
593/*************
594 * Functions to implement camera functionality
595 *************/
596/******************************************************************************
597 *
598 * cpia2_get_version_info
599 *
600 *****************************************************************************/
601static void cpia2_get_version_info(struct camera_data *cam)
602{
603 cpia2_do_command(cam, CPIA2_CMD_GET_VERSION, TRANSFER_READ, 0);
604 cpia2_do_command(cam, CPIA2_CMD_GET_PNP_ID, TRANSFER_READ, 0);
605 cpia2_do_command(cam, CPIA2_CMD_GET_ASIC_TYPE, TRANSFER_READ, 0);
606 cpia2_do_command(cam, CPIA2_CMD_GET_SENSOR, TRANSFER_READ, 0);
607 cpia2_do_command(cam, CPIA2_CMD_GET_VP_DEVICE, TRANSFER_READ, 0);
608}
609
610/******************************************************************************
611 *
612 * cpia2_reset_camera
613 *
614 * Called at least during the open process, sets up initial params.
615 *****************************************************************************/
616int cpia2_reset_camera(struct camera_data *cam)
617{
618 u8 tmp_reg;
619 int retval = 0;
620 int i;
621 struct cpia2_command cmd;
622
623 /***
624 * VC setup
625 ***/
626 retval = configure_sensor(cam,
627 cam->params.roi.width,
628 cam->params.roi.height);
629 if (retval < 0) {
630 ERR("Couldn't configure sensor, error=%d\n", retval);
631 return retval;
632 }
633
634 /* Clear FIFO and route/enable stream block */
635 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
636 cmd.direction = TRANSFER_WRITE;
637 cmd.reg_count = 2;
638 cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL;
639 cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC |
640 CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT;
641 cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL;
642 cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC |
643 CPIA2_VC_ST_CTRL_DST_USB |
644 CPIA2_VC_ST_CTRL_EOF_DETECT | CPIA2_VC_ST_CTRL_FIFO_ENABLE;
645
646 cpia2_send_command(cam, &cmd);
647
648 cpia2_set_high_power(cam);
649
650 if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
651 /* Enable button notification */
652 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM;
653 cmd.buffer.registers[0].index = CPIA2_SYSTEM_INT_PACKET_CTRL;
654 cmd.buffer.registers[0].value =
655 CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX;
656 cmd.reg_count = 1;
657 cpia2_send_command(cam, &cmd);
658 }
659
660 schedule_timeout_interruptible(msecs_to_jiffies(100));
661
662 if (cam->params.pnp_id.device_type == DEVICE_STV_672)
663 retval = apply_vp_patch(cam);
664
665 /* wait for vp to go to sleep */
666 schedule_timeout_interruptible(msecs_to_jiffies(100));
667
668 /***
669 * If this is a 676, apply VP5 fixes before we start streaming
670 ***/
671 if (cam->params.pnp_id.device_type == DEVICE_STV_676) {
672 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
673
674 /* The following writes improve the picture */
675 cmd.buffer.registers[0].index = CPIA2_VP5_MYBLACK_LEVEL;
676 cmd.buffer.registers[0].value = 0; /* reduce from the default
677 * rec 601 pedestal of 16 */
678 cmd.buffer.registers[1].index = CPIA2_VP5_MCYRANGE;
679 cmd.buffer.registers[1].value = 0x92; /* increase from 100% to
680 * (256/256 - 31) to fill
681 * available range */
682 cmd.buffer.registers[2].index = CPIA2_VP5_MYCEILING;
683 cmd.buffer.registers[2].value = 0xFF; /* Increase from the
684 * default rec 601 ceiling
685 * of 240 */
686 cmd.buffer.registers[3].index = CPIA2_VP5_MCUVSATURATION;
687 cmd.buffer.registers[3].value = 0xFF; /* Increase from the rec
688 * 601 100% level (128)
689 * to 145-192 */
690 cmd.buffer.registers[4].index = CPIA2_VP5_ANTIFLKRSETUP;
691 cmd.buffer.registers[4].value = 0x80; /* Inhibit the
692 * anti-flicker */
693
694 /* The following 4 writes are a fix to allow QVGA to work at 30 fps */
695 cmd.buffer.registers[5].index = CPIA2_VP_RAM_ADDR_H;
696 cmd.buffer.registers[5].value = 0x01;
697 cmd.buffer.registers[6].index = CPIA2_VP_RAM_ADDR_L;
698 cmd.buffer.registers[6].value = 0xE3;
699 cmd.buffer.registers[7].index = CPIA2_VP_RAM_DATA;
700 cmd.buffer.registers[7].value = 0x02;
701 cmd.buffer.registers[8].index = CPIA2_VP_RAM_DATA;
702 cmd.buffer.registers[8].value = 0xFC;
703
704 cmd.direction = TRANSFER_WRITE;
705 cmd.reg_count = 9;
706
707 cpia2_send_command(cam, &cmd);
708 }
709
710 /* Activate all settings and start the data stream */
711 /* Set user mode */
712 set_default_user_mode(cam);
713
714 /* Give VP time to wake up */
715 schedule_timeout_interruptible(msecs_to_jiffies(100));
716
717 set_all_properties(cam);
718
719 cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0);
720 DBG("After SetAllProperties(cam), user mode is 0x%0X\n",
721 cam->params.vp_params.video_mode);
722
723 /***
724 * Set audio regulator off. This and the code to set the compresison
725 * state are too complex to form a CPIA2_CMD_, and seem to be somewhat
726 * intertwined. This stuff came straight from the windows driver.
727 ***/
728 /* Turn AutoExposure off in VP and enable the serial bridge to the sensor */
729 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0);
730 tmp_reg = cam->params.vp_params.system_ctrl;
731 cmd.buffer.registers[0].value = tmp_reg &
732 (tmp_reg & (CPIA2_VP_SYSTEMCTRL_HK_CONTROL ^ 0xFF));
733
734 cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0);
735 cmd.buffer.registers[1].value = cam->params.vp_params.device_config |
736 CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE;
737 cmd.buffer.registers[0].index = CPIA2_VP_SYSTEMCTRL;
738 cmd.buffer.registers[1].index = CPIA2_VP_DEVICE_CONFIG;
739 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
740 cmd.reg_count = 2;
741 cmd.direction = TRANSFER_WRITE;
742 cmd.start = 0;
743 cpia2_send_command(cam, &cmd);
744
745 /* Set the correct I2C address in the CPiA-2 system register */
746 cpia2_do_command(cam,
747 CPIA2_CMD_SET_SERIAL_ADDR,
748 TRANSFER_WRITE,
749 CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR);
750
751 /* Now have sensor access - set bit to turn the audio regulator off */
752 cpia2_do_command(cam,
753 CPIA2_CMD_SET_SENSOR_CR1,
754 TRANSFER_WRITE, CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR);
755
756 /* Set the correct I2C address in the CPiA-2 system register */
757 if (cam->params.pnp_id.device_type == DEVICE_STV_672)
758 cpia2_do_command(cam,
759 CPIA2_CMD_SET_SERIAL_ADDR,
760 TRANSFER_WRITE,
761 CPIA2_SYSTEM_VP_SERIAL_ADDR_VP); // 0x88
762 else
763 cpia2_do_command(cam,
764 CPIA2_CMD_SET_SERIAL_ADDR,
765 TRANSFER_WRITE,
766 CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP); // 0x8a
767
768 /* increase signal drive strength */
769 if (cam->params.pnp_id.device_type == DEVICE_STV_676)
770 cpia2_do_command(cam,
771 CPIA2_CMD_SET_VP_EXP_MODES,
772 TRANSFER_WRITE,
773 CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP);
774
775 /* Start autoexposure */
776 cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0);
777 cmd.buffer.registers[0].value = cam->params.vp_params.device_config &
778 (CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE ^ 0xFF);
779
780 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0);
781 cmd.buffer.registers[1].value =
782 cam->params.vp_params.system_ctrl | CPIA2_VP_SYSTEMCTRL_HK_CONTROL;
783
784 cmd.buffer.registers[0].index = CPIA2_VP_DEVICE_CONFIG;
785 cmd.buffer.registers[1].index = CPIA2_VP_SYSTEMCTRL;
786 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
787 cmd.reg_count = 2;
788 cmd.direction = TRANSFER_WRITE;
789
790 cpia2_send_command(cam, &cmd);
791
792 /* Set compression state */
793 cpia2_do_command(cam, CPIA2_CMD_GET_VC_CONTROL, TRANSFER_READ, 0);
794 if (cam->params.compression.inhibit_htables) {
795 tmp_reg = cam->params.vc_params.vc_control |
796 CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES;
797 } else {
798 tmp_reg = cam->params.vc_params.vc_control &
799 ~CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES;
800 }
801 cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg);
802
803 /* Set target size (kb) on vc */
804 cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB,
805 TRANSFER_WRITE, cam->params.vc_params.target_kb);
806
807 /* Wiggle VC Reset */
808 /***
809 * First read and wait a bit.
810 ***/
811 for (i = 0; i < 50; i++) {
812 cpia2_do_command(cam, CPIA2_CMD_GET_PW_CONTROL,
813 TRANSFER_READ, 0);
814 }
815
816 tmp_reg = cam->params.vc_params.pw_control;
817 tmp_reg &= ~CPIA2_VC_PW_CTRL_VC_RESET_N;
818
819 cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg);
820
821 tmp_reg |= CPIA2_VC_PW_CTRL_VC_RESET_N;
822 cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg);
823
824 cpia2_do_command(cam, CPIA2_CMD_SET_DEF_JPEG_OPT, TRANSFER_WRITE, 0);
825
826 cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0);
827 DBG("After VC RESET, user mode is 0x%0X\n",
828 cam->params.vp_params.video_mode);
829
830 return retval;
831}
832
833/******************************************************************************
834 *
835 * cpia2_set_high_power
836 *
837 *****************************************************************************/
838static int cpia2_set_high_power(struct camera_data *cam)
839{
840 int i;
841 for (i = 0; i <= 50; i++) {
842 /* Read system status */
843 cpia2_do_command(cam,CPIA2_CMD_GET_SYSTEM_CTRL,TRANSFER_READ,0);
844
845 /* If there is an error, clear it */
846 if(cam->params.camera_state.system_ctrl &
847 CPIA2_SYSTEM_CONTROL_V2W_ERR)
848 cpia2_do_command(cam, CPIA2_CMD_CLEAR_V2W_ERR,
849 TRANSFER_WRITE, 0);
850
851 /* Try to set high power mode */
852 cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL,
853 TRANSFER_WRITE, 1);
854
855 /* Try to read something in VP to check if everything is awake */
856 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_STATE,
857 TRANSFER_READ, 0);
858 if (cam->params.vp_params.system_state &
859 CPIA2_VP_SYSTEMSTATE_HK_ALIVE) {
860 break;
861 } else if (i == 50) {
862 cam->params.camera_state.power_mode = LO_POWER_MODE;
863 ERR("Camera did not wake up\n");
864 return -EIO;
865 }
866 }
867
868 DBG("System now in high power state\n");
869 cam->params.camera_state.power_mode = HI_POWER_MODE;
870 return 0;
871}
872
873/******************************************************************************
874 *
875 * cpia2_set_low_power
876 *
877 *****************************************************************************/
878int cpia2_set_low_power(struct camera_data *cam)
879{
880 cam->params.camera_state.power_mode = LO_POWER_MODE;
881 cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL, TRANSFER_WRITE, 0);
882 return 0;
883}
884
885/******************************************************************************
886 *
887 * apply_vp_patch
888 *
889 *****************************************************************************/
890static int cpia2_send_onebyte_command(struct camera_data *cam,
891 struct cpia2_command *cmd,
892 u8 start, u8 datum)
893{
894 cmd->buffer.block_data[0] = datum;
895 cmd->start = start;
896 cmd->reg_count = 1;
897 return cpia2_send_command(cam, cmd);
898}
899
900static int apply_vp_patch(struct camera_data *cam)
901{
902 const struct firmware *fw;
903 const char fw_name[] = "cpia2/stv0672_vp4.bin";
904 int i, ret;
905 struct cpia2_command cmd;
906
907 ret = request_firmware(&fw, fw_name, &cam->dev->dev);
908 if (ret) {
909 printk(KERN_ERR "cpia2: failed to load VP patch \"%s\"\n",
910 fw_name);
911 return ret;
912 }
913
914 cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP;
915 cmd.direction = TRANSFER_WRITE;
916
917 /* First send the start address... */
918 cpia2_send_onebyte_command(cam, &cmd, 0x0A, fw->data[0]); /* hi */
919 cpia2_send_onebyte_command(cam, &cmd, 0x0B, fw->data[1]); /* lo */
920
921 /* ... followed by the data payload */
922 for (i = 2; i < fw->size; i += 64) {
923 cmd.start = 0x0C; /* Data */
924 cmd.reg_count = min_t(int, 64, fw->size - i);
925 memcpy(cmd.buffer.block_data, &fw->data[i], cmd.reg_count);
926 cpia2_send_command(cam, &cmd);
927 }
928
929 /* Next send the start address... */
930 cpia2_send_onebyte_command(cam, &cmd, 0x0A, fw->data[0]); /* hi */
931 cpia2_send_onebyte_command(cam, &cmd, 0x0B, fw->data[1]); /* lo */
932
933 /* ... followed by the 'goto' command */
934 cpia2_send_onebyte_command(cam, &cmd, 0x0D, 1);
935
936 release_firmware(fw);
937 return 0;
938}
939
940/******************************************************************************
941 *
942 * set_default_user_mode
943 *
944 *****************************************************************************/
945static int set_default_user_mode(struct camera_data *cam)
946{
947 unsigned char user_mode;
948 unsigned char frame_rate;
949 int width = cam->params.roi.width;
950 int height = cam->params.roi.height;
951
952 switch (cam->params.version.sensor_flags) {
953 case CPIA2_VP_SENSOR_FLAGS_404:
954 case CPIA2_VP_SENSOR_FLAGS_407:
955 case CPIA2_VP_SENSOR_FLAGS_409:
956 case CPIA2_VP_SENSOR_FLAGS_410:
957 if ((width > STV_IMAGE_QCIF_COLS)
958 || (height > STV_IMAGE_QCIF_ROWS)) {
959 user_mode = CPIA2_VP_USER_MODE_CIF;
960 } else {
961 user_mode = CPIA2_VP_USER_MODE_QCIFDS;
962 }
963 frame_rate = CPIA2_VP_FRAMERATE_30;
964 break;
965 case CPIA2_VP_SENSOR_FLAGS_500:
966 if ((width > STV_IMAGE_CIF_COLS)
967 || (height > STV_IMAGE_CIF_ROWS)) {
968 user_mode = CPIA2_VP_USER_MODE_VGA;
969 } else {
970 user_mode = CPIA2_VP_USER_MODE_QVGADS;
971 }
972 if (cam->params.pnp_id.device_type == DEVICE_STV_672)
973 frame_rate = CPIA2_VP_FRAMERATE_15;
974 else
975 frame_rate = CPIA2_VP_FRAMERATE_30;
976 break;
977 default:
978 LOG("%s: Invalid sensor flag value 0x%0X\n",__func__,
979 cam->params.version.sensor_flags);
980 return -EINVAL;
981 }
982
983 DBG("Sensor flag = 0x%0x, user mode = 0x%0x, frame rate = 0x%X\n",
984 cam->params.version.sensor_flags, user_mode, frame_rate);
985 cpia2_do_command(cam, CPIA2_CMD_SET_USER_MODE, TRANSFER_WRITE,
986 user_mode);
987 if(cam->params.vp_params.frame_rate > 0 &&
988 frame_rate > cam->params.vp_params.frame_rate)
989 frame_rate = cam->params.vp_params.frame_rate;
990
991 cpia2_set_fps(cam, frame_rate);
992
993// if (cam->params.pnp_id.device_type == DEVICE_STV_676)
994// cpia2_do_command(cam,
995// CPIA2_CMD_SET_VP_SYSTEM_CTRL,
996// TRANSFER_WRITE,
997// CPIA2_VP_SYSTEMCTRL_HK_CONTROL |
998// CPIA2_VP_SYSTEMCTRL_POWER_CONTROL);
999
1000 return 0;
1001}
1002
1003/******************************************************************************
1004 *
1005 * cpia2_match_video_size
1006 *
1007 * return the best match, where 'best' is as always
1008 * the largest that is not bigger than what is requested.
1009 *****************************************************************************/
1010int cpia2_match_video_size(int width, int height)
1011{
1012 if (width >= STV_IMAGE_VGA_COLS && height >= STV_IMAGE_VGA_ROWS)
1013 return VIDEOSIZE_VGA;
1014
1015 if (width >= STV_IMAGE_CIF_COLS && height >= STV_IMAGE_CIF_ROWS)
1016 return VIDEOSIZE_CIF;
1017
1018 if (width >= STV_IMAGE_QVGA_COLS && height >= STV_IMAGE_QVGA_ROWS)
1019 return VIDEOSIZE_QVGA;
1020
1021 if (width >= 288 && height >= 216)
1022 return VIDEOSIZE_288_216;
1023
1024 if (width >= 256 && height >= 192)
1025 return VIDEOSIZE_256_192;
1026
1027 if (width >= 224 && height >= 168)
1028 return VIDEOSIZE_224_168;
1029
1030 if (width >= 192 && height >= 144)
1031 return VIDEOSIZE_192_144;
1032
1033 if (width >= STV_IMAGE_QCIF_COLS && height >= STV_IMAGE_QCIF_ROWS)
1034 return VIDEOSIZE_QCIF;
1035
1036 return -1;
1037}
1038
1039/******************************************************************************
1040 *
1041 * SetVideoSize
1042 *
1043 *****************************************************************************/
1044static int set_vw_size(struct camera_data *cam, int size)
1045{
1046 int retval = 0;
1047
1048 cam->params.vp_params.video_size = size;
1049
1050 switch (size) {
1051 case VIDEOSIZE_VGA:
1052 DBG("Setting size to VGA\n");
1053 cam->params.roi.width = STV_IMAGE_VGA_COLS;
1054 cam->params.roi.height = STV_IMAGE_VGA_ROWS;
1055 cam->width = STV_IMAGE_VGA_COLS;
1056 cam->height = STV_IMAGE_VGA_ROWS;
1057 break;
1058 case VIDEOSIZE_CIF:
1059 DBG("Setting size to CIF\n");
1060 cam->params.roi.width = STV_IMAGE_CIF_COLS;
1061 cam->params.roi.height = STV_IMAGE_CIF_ROWS;
1062 cam->width = STV_IMAGE_CIF_COLS;
1063 cam->height = STV_IMAGE_CIF_ROWS;
1064 break;
1065 case VIDEOSIZE_QVGA:
1066 DBG("Setting size to QVGA\n");
1067 cam->params.roi.width = STV_IMAGE_QVGA_COLS;
1068 cam->params.roi.height = STV_IMAGE_QVGA_ROWS;
1069 cam->width = STV_IMAGE_QVGA_COLS;
1070 cam->height = STV_IMAGE_QVGA_ROWS;
1071 break;
1072 case VIDEOSIZE_288_216:
1073 cam->params.roi.width = 288;
1074 cam->params.roi.height = 216;
1075 cam->width = 288;
1076 cam->height = 216;
1077 break;
1078 case VIDEOSIZE_256_192:
1079 cam->width = 256;
1080 cam->height = 192;
1081 cam->params.roi.width = 256;
1082 cam->params.roi.height = 192;
1083 break;
1084 case VIDEOSIZE_224_168:
1085 cam->width = 224;
1086 cam->height = 168;
1087 cam->params.roi.width = 224;
1088 cam->params.roi.height = 168;
1089 break;
1090 case VIDEOSIZE_192_144:
1091 cam->width = 192;
1092 cam->height = 144;
1093 cam->params.roi.width = 192;
1094 cam->params.roi.height = 144;
1095 break;
1096 case VIDEOSIZE_QCIF:
1097 DBG("Setting size to QCIF\n");
1098 cam->params.roi.width = STV_IMAGE_QCIF_COLS;
1099 cam->params.roi.height = STV_IMAGE_QCIF_ROWS;
1100 cam->width = STV_IMAGE_QCIF_COLS;
1101 cam->height = STV_IMAGE_QCIF_ROWS;
1102 break;
1103 default:
1104 retval = -EINVAL;
1105 }
1106 return retval;
1107}
1108
1109/******************************************************************************
1110 *
1111 * configure_sensor
1112 *
1113 *****************************************************************************/
1114static int configure_sensor(struct camera_data *cam,
1115 int req_width, int req_height)
1116{
1117 int retval;
1118
1119 switch (cam->params.version.sensor_flags) {
1120 case CPIA2_VP_SENSOR_FLAGS_404:
1121 case CPIA2_VP_SENSOR_FLAGS_407:
1122 case CPIA2_VP_SENSOR_FLAGS_409:
1123 case CPIA2_VP_SENSOR_FLAGS_410:
1124 retval = config_sensor_410(cam, req_width, req_height);
1125 break;
1126 case CPIA2_VP_SENSOR_FLAGS_500:
1127 retval = config_sensor_500(cam, req_width, req_height);
1128 break;
1129 default:
1130 return -EINVAL;
1131 }
1132
1133 return retval;
1134}
1135
1136/******************************************************************************
1137 *
1138 * config_sensor_410
1139 *
1140 *****************************************************************************/
1141static int config_sensor_410(struct camera_data *cam,
1142 int req_width, int req_height)
1143{
1144 struct cpia2_command cmd;
1145 int i = 0;
1146 int image_size;
1147 int image_type;
1148 int width = req_width;
1149 int height = req_height;
1150
1151 /***
1152 * Make sure size doesn't exceed CIF.
1153 ***/
1154 if (width > STV_IMAGE_CIF_COLS)
1155 width = STV_IMAGE_CIF_COLS;
1156 if (height > STV_IMAGE_CIF_ROWS)
1157 height = STV_IMAGE_CIF_ROWS;
1158
1159 image_size = cpia2_match_video_size(width, height);
1160
1161 DBG("Config 410: width = %d, height = %d\n", width, height);
1162 DBG("Image size returned is %d\n", image_size);
1163 if (image_size >= 0) {
1164 set_vw_size(cam, image_size);
1165 width = cam->params.roi.width;
1166 height = cam->params.roi.height;
1167
1168 DBG("After set_vw_size(), width = %d, height = %d\n",
1169 width, height);
1170 if (width <= 176 && height <= 144) {
1171 DBG("image type = VIDEOSIZE_QCIF\n");
1172 image_type = VIDEOSIZE_QCIF;
1173 }
1174 else if (width <= 320 && height <= 240) {
1175 DBG("image type = VIDEOSIZE_QVGA\n");
1176 image_type = VIDEOSIZE_QVGA;
1177 }
1178 else {
1179 DBG("image type = VIDEOSIZE_CIF\n");
1180 image_type = VIDEOSIZE_CIF;
1181 }
1182 } else {
1183 ERR("ConfigSensor410 failed\n");
1184 return -EINVAL;
1185 }
1186
1187 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
1188 cmd.direction = TRANSFER_WRITE;
1189
1190 /* VC Format */
1191 cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT;
1192 if (image_type == VIDEOSIZE_CIF) {
1193 cmd.buffer.registers[i++].value =
1194 (u8) (CPIA2_VC_VC_FORMAT_UFIRST |
1195 CPIA2_VC_VC_FORMAT_SHORTLINE);
1196 } else {
1197 cmd.buffer.registers[i++].value =
1198 (u8) CPIA2_VC_VC_FORMAT_UFIRST;
1199 }
1200
1201 /* VC Clocks */
1202 cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS;
1203 if (image_type == VIDEOSIZE_QCIF) {
1204 if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
1205 cmd.buffer.registers[i++].value=
1206 (u8)(CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 |
1207 CPIA2_VC_VC_672_CLOCKS_SCALING |
1208 CPIA2_VC_VC_CLOCKS_LOGDIV2);
1209 DBG("VC_Clocks (0xc4) should be B\n");
1210 }
1211 else {
1212 cmd.buffer.registers[i++].value=
1213 (u8)(CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 |
1214 CPIA2_VC_VC_CLOCKS_LOGDIV2);
1215 }
1216 } else {
1217 if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
1218 cmd.buffer.registers[i++].value =
1219 (u8) (CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 |
1220 CPIA2_VC_VC_CLOCKS_LOGDIV0);
1221 }
1222 else {
1223 cmd.buffer.registers[i++].value =
1224 (u8) (CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 |
1225 CPIA2_VC_VC_676_CLOCKS_SCALING |
1226 CPIA2_VC_VC_CLOCKS_LOGDIV0);
1227 }
1228 }
1229 DBG("VC_Clocks (0xc4) = 0x%0X\n", cmd.buffer.registers[i-1].value);
1230
1231 /* Input reqWidth from VC */
1232 cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO;
1233 if (image_type == VIDEOSIZE_QCIF)
1234 cmd.buffer.registers[i++].value =
1235 (u8) (STV_IMAGE_QCIF_COLS / 4);
1236 else
1237 cmd.buffer.registers[i++].value =
1238 (u8) (STV_IMAGE_CIF_COLS / 4);
1239
1240 /* Timings */
1241 cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI;
1242 if (image_type == VIDEOSIZE_QCIF)
1243 cmd.buffer.registers[i++].value = (u8) 0;
1244 else
1245 cmd.buffer.registers[i++].value = (u8) 1;
1246
1247 cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO;
1248 if (image_type == VIDEOSIZE_QCIF)
1249 cmd.buffer.registers[i++].value = (u8) 208;
1250 else
1251 cmd.buffer.registers[i++].value = (u8) 160;
1252
1253 cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI;
1254 if (image_type == VIDEOSIZE_QCIF)
1255 cmd.buffer.registers[i++].value = (u8) 0;
1256 else
1257 cmd.buffer.registers[i++].value = (u8) 1;
1258
1259 cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO;
1260 if (image_type == VIDEOSIZE_QCIF)
1261 cmd.buffer.registers[i++].value = (u8) 160;
1262 else
1263 cmd.buffer.registers[i++].value = (u8) 64;
1264
1265 /* Output Image Size */
1266 cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE;
1267 cmd.buffer.registers[i++].value = cam->params.roi.width / 4;
1268
1269 cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE;
1270 cmd.buffer.registers[i++].value = cam->params.roi.height / 4;
1271
1272 /* Cropping */
1273 cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP;
1274 if (image_type == VIDEOSIZE_QCIF)
1275 cmd.buffer.registers[i++].value =
1276 (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2);
1277 else
1278 cmd.buffer.registers[i++].value =
1279 (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2);
1280
1281 cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP;
1282 if (image_type == VIDEOSIZE_QCIF)
1283 cmd.buffer.registers[i++].value =
1284 (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2);
1285 else
1286 cmd.buffer.registers[i++].value =
1287 (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2);
1288
1289 /* Scaling registers (defaults) */
1290 cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE;
1291 cmd.buffer.registers[i++].value = (u8) 0;
1292
1293 cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE;
1294 cmd.buffer.registers[i++].value = (u8) 0;
1295
1296 cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN;
1297 cmd.buffer.registers[i++].value = (u8) 31;
1298
1299 cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN;
1300 cmd.buffer.registers[i++].value = (u8) 31;
1301
1302 cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP;
1303 cmd.buffer.registers[i++].value = (u8) 0;
1304
1305 cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP;
1306 cmd.buffer.registers[i++].value = (u8) 0;
1307
1308 cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT;
1309 cmd.buffer.registers[i++].value = (u8) 0x81; /* = 8/1 = 8 (HIBYTE/LOBYTE) */
1310
1311 cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT;
1312 cmd.buffer.registers[i++].value = (u8) 0x81; /* = 8/1 = 8 (HIBYTE/LOBYTE) */
1313
1314 cmd.reg_count = i;
1315
1316 cpia2_send_command(cam, &cmd);
1317
1318 return i;
1319}
1320
1321
1322/******************************************************************************
1323 *
1324 * config_sensor_500(cam)
1325 *
1326 *****************************************************************************/
1327static int config_sensor_500(struct camera_data *cam,
1328 int req_width, int req_height)
1329{
1330 struct cpia2_command cmd;
1331 int i = 0;
1332 int image_size = VIDEOSIZE_CIF;
1333 int image_type = VIDEOSIZE_VGA;
1334 int width = req_width;
1335 int height = req_height;
1336 unsigned int device = cam->params.pnp_id.device_type;
1337
1338 image_size = cpia2_match_video_size(width, height);
1339
1340 if (width > STV_IMAGE_CIF_COLS || height > STV_IMAGE_CIF_ROWS)
1341 image_type = VIDEOSIZE_VGA;
1342 else if (width > STV_IMAGE_QVGA_COLS || height > STV_IMAGE_QVGA_ROWS)
1343 image_type = VIDEOSIZE_CIF;
1344 else if (width > STV_IMAGE_QCIF_COLS || height > STV_IMAGE_QCIF_ROWS)
1345 image_type = VIDEOSIZE_QVGA;
1346 else
1347 image_type = VIDEOSIZE_QCIF;
1348
1349 if (image_size >= 0) {
1350 set_vw_size(cam, image_size);
1351 width = cam->params.roi.width;
1352 height = cam->params.roi.height;
1353 } else {
1354 ERR("ConfigSensor500 failed\n");
1355 return -EINVAL;
1356 }
1357
1358 DBG("image_size = %d, width = %d, height = %d, type = %d\n",
1359 image_size, width, height, image_type);
1360
1361 cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
1362 cmd.direction = TRANSFER_WRITE;
1363 i = 0;
1364
1365 /* VC Format */
1366 cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT;
1367 cmd.buffer.registers[i].value = (u8) CPIA2_VC_VC_FORMAT_UFIRST;
1368 if (image_type == VIDEOSIZE_QCIF)
1369 cmd.buffer.registers[i].value |= (u8) CPIA2_VC_VC_FORMAT_DECIMATING;
1370 i++;
1371
1372 /* VC Clocks */
1373 cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS;
1374 if (device == DEVICE_STV_672) {
1375 if (image_type == VIDEOSIZE_VGA)
1376 cmd.buffer.registers[i].value =
1377 (u8)CPIA2_VC_VC_CLOCKS_LOGDIV1;
1378 else
1379 cmd.buffer.registers[i].value =
1380 (u8)(CPIA2_VC_VC_672_CLOCKS_SCALING |
1381 CPIA2_VC_VC_CLOCKS_LOGDIV3);
1382 } else {
1383 if (image_type == VIDEOSIZE_VGA)
1384 cmd.buffer.registers[i].value =
1385 (u8)CPIA2_VC_VC_CLOCKS_LOGDIV0;
1386 else
1387 cmd.buffer.registers[i].value =
1388 (u8)(CPIA2_VC_VC_676_CLOCKS_SCALING |
1389 CPIA2_VC_VC_CLOCKS_LOGDIV2);
1390 }
1391 i++;
1392
1393 DBG("VC_CLOCKS = 0x%X\n", cmd.buffer.registers[i-1].value);
1394
1395 /* Input width from VP */
1396 cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO;
1397 if (image_type == VIDEOSIZE_VGA)
1398 cmd.buffer.registers[i].value =
1399 (u8) (STV_IMAGE_VGA_COLS / 4);
1400 else
1401 cmd.buffer.registers[i].value =
1402 (u8) (STV_IMAGE_QVGA_COLS / 4);
1403 i++;
1404 DBG("Input width = %d\n", cmd.buffer.registers[i-1].value);
1405
1406 /* Timings */
1407 cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI;
1408 if (image_type == VIDEOSIZE_VGA)
1409 cmd.buffer.registers[i++].value = (u8) 2;
1410 else
1411 cmd.buffer.registers[i++].value = (u8) 1;
1412
1413 cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO;
1414 if (image_type == VIDEOSIZE_VGA)
1415 cmd.buffer.registers[i++].value = (u8) 250;
1416 else if (image_type == VIDEOSIZE_QVGA)
1417 cmd.buffer.registers[i++].value = (u8) 125;
1418 else
1419 cmd.buffer.registers[i++].value = (u8) 160;
1420
1421 cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI;
1422 if (image_type == VIDEOSIZE_VGA)
1423 cmd.buffer.registers[i++].value = (u8) 2;
1424 else
1425 cmd.buffer.registers[i++].value = (u8) 1;
1426
1427 cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO;
1428 if (image_type == VIDEOSIZE_VGA)
1429 cmd.buffer.registers[i++].value = (u8) 12;
1430 else if (image_type == VIDEOSIZE_QVGA)
1431 cmd.buffer.registers[i++].value = (u8) 64;
1432 else
1433 cmd.buffer.registers[i++].value = (u8) 6;
1434
1435 /* Output Image Size */
1436 cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE;
1437 if (image_type == VIDEOSIZE_QCIF)
1438 cmd.buffer.registers[i++].value = STV_IMAGE_CIF_COLS / 4;
1439 else
1440 cmd.buffer.registers[i++].value = width / 4;
1441
1442 cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE;
1443 if (image_type == VIDEOSIZE_QCIF)
1444 cmd.buffer.registers[i++].value = STV_IMAGE_CIF_ROWS / 4;
1445 else
1446 cmd.buffer.registers[i++].value = height / 4;
1447
1448 /* Cropping */
1449 cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP;
1450 if (image_type == VIDEOSIZE_VGA)
1451 cmd.buffer.registers[i++].value =
1452 (u8) (((STV_IMAGE_VGA_COLS / 4) - (width / 4)) / 2);
1453 else if (image_type == VIDEOSIZE_QVGA)
1454 cmd.buffer.registers[i++].value =
1455 (u8) (((STV_IMAGE_QVGA_COLS / 4) - (width / 4)) / 2);
1456 else if (image_type == VIDEOSIZE_CIF)
1457 cmd.buffer.registers[i++].value =
1458 (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2);
1459 else /*if (image_type == VIDEOSIZE_QCIF)*/
1460 cmd.buffer.registers[i++].value =
1461 (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2);
1462
1463 cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP;
1464 if (image_type == VIDEOSIZE_VGA)
1465 cmd.buffer.registers[i++].value =
1466 (u8) (((STV_IMAGE_VGA_ROWS / 4) - (height / 4)) / 2);
1467 else if (image_type == VIDEOSIZE_QVGA)
1468 cmd.buffer.registers[i++].value =
1469 (u8) (((STV_IMAGE_QVGA_ROWS / 4) - (height / 4)) / 2);
1470 else if (image_type == VIDEOSIZE_CIF)
1471 cmd.buffer.registers[i++].value =
1472 (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2);
1473 else /*if (image_type == VIDEOSIZE_QCIF)*/
1474 cmd.buffer.registers[i++].value =
1475 (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2);
1476
1477 /* Scaling registers (defaults) */
1478 cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE;
1479 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1480 cmd.buffer.registers[i++].value = (u8) 36;
1481 else
1482 cmd.buffer.registers[i++].value = (u8) 0;
1483
1484 cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE;
1485 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1486 cmd.buffer.registers[i++].value = (u8) 32;
1487 else
1488 cmd.buffer.registers[i++].value = (u8) 0;
1489
1490 cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN;
1491 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1492 cmd.buffer.registers[i++].value = (u8) 26;
1493 else
1494 cmd.buffer.registers[i++].value = (u8) 31;
1495
1496 cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN;
1497 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1498 cmd.buffer.registers[i++].value = (u8) 21;
1499 else
1500 cmd.buffer.registers[i++].value = (u8) 31;
1501
1502 cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP;
1503 cmd.buffer.registers[i++].value = (u8) 0;
1504
1505 cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP;
1506 cmd.buffer.registers[i++].value = (u8) 0;
1507
1508 cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT;
1509 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1510 cmd.buffer.registers[i++].value = (u8) 0x2B; /* 2/11 */
1511 else
1512 cmd.buffer.registers[i++].value = (u8) 0x81; /* 8/1 */
1513
1514 cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT;
1515 if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
1516 cmd.buffer.registers[i++].value = (u8) 0x13; /* 1/3 */
1517 else
1518 cmd.buffer.registers[i++].value = (u8) 0x81; /* 8/1 */
1519
1520 cmd.reg_count = i;
1521
1522 cpia2_send_command(cam, &cmd);
1523
1524 return i;
1525}
1526
1527
1528/******************************************************************************
1529 *
1530 * setallproperties
1531 *
1532 * This sets all user changeable properties to the values in cam->params.
1533 *****************************************************************************/
1534static int set_all_properties(struct camera_data *cam)
1535{
1536 /**
1537 * Don't set target_kb here, it will be set later.
1538 * framerate and user_mode were already set (set_default_user_mode).
1539 **/
1540
1541 cpia2_set_color_params(cam);
1542
1543 cpia2_usb_change_streaming_alternate(cam,
1544 cam->params.camera_state.stream_mode);
1545
1546 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
1547 cam->params.vp_params.user_effects);
1548
1549 cpia2_set_flicker_mode(cam,
1550 cam->params.flicker_control.flicker_mode_req);
1551
1552 cpia2_do_command(cam,
1553 CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
1554 TRANSFER_WRITE, cam->params.vp_params.gpio_direction);
1555 cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, TRANSFER_WRITE,
1556 cam->params.vp_params.gpio_data);
1557
1558 wake_system(cam);
1559
1560 set_lowlight_boost(cam);
1561
1562 return 0;
1563}
1564
1565/******************************************************************************
1566 *
1567 * cpia2_save_camera_state
1568 *
1569 *****************************************************************************/
1570void cpia2_save_camera_state(struct camera_data *cam)
1571{
1572 get_color_params(cam);
1573 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
1574 cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, TRANSFER_READ,
1575 0);
1576 cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DATA, TRANSFER_READ, 0);
1577 /* Don't get framerate or target_kb. Trust the values we already have */
1578}
1579
1580/******************************************************************************
1581 *
1582 * get_color_params
1583 *
1584 *****************************************************************************/
1585static void get_color_params(struct camera_data *cam)
1586{
1587 cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, TRANSFER_READ, 0);
1588 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, TRANSFER_READ, 0);
1589 cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST, TRANSFER_READ, 0);
1590}
1591
1592/******************************************************************************
1593 *
1594 * cpia2_set_color_params
1595 *
1596 *****************************************************************************/
1597void cpia2_set_color_params(struct camera_data *cam)
1598{
1599 DBG("Setting color params\n");
1600 cpia2_set_brightness(cam, cam->params.color_params.brightness);
1601 cpia2_set_contrast(cam, cam->params.color_params.contrast);
1602 cpia2_set_saturation(cam, cam->params.color_params.saturation);
1603}
1604
1605/******************************************************************************
1606 *
1607 * cpia2_set_flicker_mode
1608 *
1609 *****************************************************************************/
1610int cpia2_set_flicker_mode(struct camera_data *cam, int mode)
1611{
1612 unsigned char cam_reg;
1613 int err = 0;
1614
1615 if(cam->params.pnp_id.device_type != DEVICE_STV_672)
1616 return -EINVAL;
1617
1618 /* Set the appropriate bits in FLICKER_MODES, preserving the rest */
1619 if((err = cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES,
1620 TRANSFER_READ, 0)))
1621 return err;
1622 cam_reg = cam->params.flicker_control.cam_register;
1623
1624 switch(mode) {
1625 case NEVER_FLICKER:
1626 cam_reg |= CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
1627 cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ;
1628 break;
1629 case FLICKER_60:
1630 cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
1631 cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ;
1632 break;
1633 case FLICKER_50:
1634 cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
1635 cam_reg |= CPIA2_VP_FLICKER_MODES_50HZ;
1636 break;
1637 default:
1638 return -EINVAL;
1639 }
1640
1641 if((err = cpia2_do_command(cam, CPIA2_CMD_SET_FLICKER_MODES,
1642 TRANSFER_WRITE, cam_reg)))
1643 return err;
1644
1645 /* Set the appropriate bits in EXP_MODES, preserving the rest */
1646 if((err = cpia2_do_command(cam, CPIA2_CMD_GET_VP_EXP_MODES,
1647 TRANSFER_READ, 0)))
1648 return err;
1649 cam_reg = cam->params.vp_params.exposure_modes;
1650
1651 if (mode == NEVER_FLICKER) {
1652 cam_reg |= CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER;
1653 } else {
1654 cam_reg &= ~CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER;
1655 }
1656
1657 if((err = cpia2_do_command(cam, CPIA2_CMD_SET_VP_EXP_MODES,
1658 TRANSFER_WRITE, cam_reg)))
1659 return err;
1660
1661 if((err = cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4,
1662 TRANSFER_WRITE, 1)))
1663 return err;
1664
1665 switch(mode) {
1666 case NEVER_FLICKER:
1667 cam->params.flicker_control.flicker_mode_req = mode;
1668 break;
1669 case FLICKER_60:
1670 cam->params.flicker_control.flicker_mode_req = mode;
1671 cam->params.flicker_control.mains_frequency = 60;
1672 break;
1673 case FLICKER_50:
1674 cam->params.flicker_control.flicker_mode_req = mode;
1675 cam->params.flicker_control.mains_frequency = 50;
1676 break;
1677 default:
1678 err = -EINVAL;
1679 }
1680
1681 return err;
1682}
1683
1684/******************************************************************************
1685 *
1686 * cpia2_set_property_flip
1687 *
1688 *****************************************************************************/
1689void cpia2_set_property_flip(struct camera_data *cam, int prop_val)
1690{
1691 unsigned char cam_reg;
1692
1693 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
1694 cam_reg = cam->params.vp_params.user_effects;
1695
1696 if (prop_val)
1697 {
1698 cam_reg |= CPIA2_VP_USER_EFFECTS_FLIP;
1699 }
1700 else
1701 {
1702 cam_reg &= ~CPIA2_VP_USER_EFFECTS_FLIP;
1703 }
1704 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
1705 cam_reg);
1706}
1707
1708/******************************************************************************
1709 *
1710 * cpia2_set_property_mirror
1711 *
1712 *****************************************************************************/
1713void cpia2_set_property_mirror(struct camera_data *cam, int prop_val)
1714{
1715 unsigned char cam_reg;
1716
1717 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
1718 cam_reg = cam->params.vp_params.user_effects;
1719
1720 if (prop_val)
1721 {
1722 cam_reg |= CPIA2_VP_USER_EFFECTS_MIRROR;
1723 }
1724 else
1725 {
1726 cam_reg &= ~CPIA2_VP_USER_EFFECTS_MIRROR;
1727 }
1728 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
1729 cam_reg);
1730}
1731
1732/******************************************************************************
1733 *
1734 * set_target_kb
1735 *
1736 * The new Target KB is set in cam->params.vc_params.target_kb and
1737 * activates on reset.
1738 *****************************************************************************/
1739
1740int cpia2_set_target_kb(struct camera_data *cam, unsigned char value)
1741{
1742 DBG("Requested target_kb = %d\n", value);
1743 if (value != cam->params.vc_params.target_kb) {
1744
1745 cpia2_usb_stream_pause(cam);
1746
1747 /* reset camera for new target_kb */
1748 cam->params.vc_params.target_kb = value;
1749 cpia2_reset_camera(cam);
1750
1751 cpia2_usb_stream_resume(cam);
1752 }
1753
1754 return 0;
1755}
1756
1757/******************************************************************************
1758 *
1759 * cpia2_set_gpio
1760 *
1761 *****************************************************************************/
1762int cpia2_set_gpio(struct camera_data *cam, unsigned char setting)
1763{
1764 int ret;
1765
1766 /* Set the microport direction (register 0x90, should be defined
1767 * already) to 1 (user output), and set the microport data (0x91) to
1768 * the value in the ioctl argument.
1769 */
1770
1771 ret = cpia2_do_command(cam,
1772 CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
1773 CPIA2_VC_MP_DIR_OUTPUT,
1774 255);
1775 if (ret < 0)
1776 return ret;
1777 cam->params.vp_params.gpio_direction = 255;
1778
1779 ret = cpia2_do_command(cam,
1780 CPIA2_CMD_SET_VC_MP_GPIO_DATA,
1781 CPIA2_VC_MP_DIR_OUTPUT,
1782 setting);
1783 if (ret < 0)
1784 return ret;
1785 cam->params.vp_params.gpio_data = setting;
1786
1787 return 0;
1788}
1789
1790/******************************************************************************
1791 *
1792 * cpia2_set_fps
1793 *
1794 *****************************************************************************/
1795int cpia2_set_fps(struct camera_data *cam, int framerate)
1796{
1797 int retval;
1798
1799 switch(framerate) {
1800 case CPIA2_VP_FRAMERATE_30:
1801 case CPIA2_VP_FRAMERATE_25:
1802 if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
1803 cam->params.version.sensor_flags ==
1804 CPIA2_VP_SENSOR_FLAGS_500) {
1805 return -EINVAL;
1806 }
1807 /* Fall through */
1808 case CPIA2_VP_FRAMERATE_15:
1809 case CPIA2_VP_FRAMERATE_12_5:
1810 case CPIA2_VP_FRAMERATE_7_5:
1811 case CPIA2_VP_FRAMERATE_6_25:
1812 break;
1813 default:
1814 return -EINVAL;
1815 }
1816
1817 if (cam->params.pnp_id.device_type == DEVICE_STV_672 &&
1818 framerate == CPIA2_VP_FRAMERATE_15)
1819 framerate = 0; /* Work around bug in VP4 */
1820
1821 retval = cpia2_do_command(cam,
1822 CPIA2_CMD_FRAMERATE_REQ,
1823 TRANSFER_WRITE,
1824 framerate);
1825
1826 if(retval == 0)
1827 cam->params.vp_params.frame_rate = framerate;
1828
1829 return retval;
1830}
1831
1832/******************************************************************************
1833 *
1834 * cpia2_set_brightness
1835 *
1836 *****************************************************************************/
1837void cpia2_set_brightness(struct camera_data *cam, unsigned char value)
1838{
1839 /***
1840 * Don't let the register be set to zero - bug in VP4 - flash of full
1841 * brightness
1842 ***/
1843 if (cam->params.pnp_id.device_type == DEVICE_STV_672 && value == 0)
1844 value++;
1845 DBG("Setting brightness to %d (0x%0x)\n", value, value);
1846 cpia2_do_command(cam,CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE,value);
1847}
1848
1849/******************************************************************************
1850 *
1851 * cpia2_set_contrast
1852 *
1853 *****************************************************************************/
1854void cpia2_set_contrast(struct camera_data *cam, unsigned char value)
1855{
1856 DBG("Setting contrast to %d (0x%0x)\n", value, value);
1857 cam->params.color_params.contrast = value;
1858 cpia2_do_command(cam, CPIA2_CMD_SET_CONTRAST, TRANSFER_WRITE, value);
1859}
1860
1861/******************************************************************************
1862 *
1863 * cpia2_set_saturation
1864 *
1865 *****************************************************************************/
1866void cpia2_set_saturation(struct camera_data *cam, unsigned char value)
1867{
1868 DBG("Setting saturation to %d (0x%0x)\n", value, value);
1869 cam->params.color_params.saturation = value;
1870 cpia2_do_command(cam,CPIA2_CMD_SET_VP_SATURATION, TRANSFER_WRITE,value);
1871}
1872
1873/******************************************************************************
1874 *
1875 * wake_system
1876 *
1877 *****************************************************************************/
1878static void wake_system(struct camera_data *cam)
1879{
1880 cpia2_do_command(cam, CPIA2_CMD_SET_WAKEUP, TRANSFER_WRITE, 0);
1881}
1882
1883/******************************************************************************
1884 *
1885 * set_lowlight_boost
1886 *
1887 * Valid for STV500 sensor only
1888 *****************************************************************************/
1889static void set_lowlight_boost(struct camera_data *cam)
1890{
1891 struct cpia2_command cmd;
1892
1893 if (cam->params.pnp_id.device_type != DEVICE_STV_672 ||
1894 cam->params.version.sensor_flags != CPIA2_VP_SENSOR_FLAGS_500)
1895 return;
1896
1897 cmd.direction = TRANSFER_WRITE;
1898 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
1899 cmd.reg_count = 3;
1900 cmd.start = CPIA2_VP_RAM_ADDR_H;
1901
1902 cmd.buffer.block_data[0] = 0; /* High byte of address to write to */
1903 cmd.buffer.block_data[1] = 0x59; /* Low byte of address to write to */
1904 cmd.buffer.block_data[2] = 0; /* High byte of data to write */
1905
1906 cpia2_send_command(cam, &cmd);
1907
1908 if (cam->params.vp_params.lowlight_boost) {
1909 cmd.buffer.block_data[0] = 0x02; /* Low byte data to write */
1910 } else {
1911 cmd.buffer.block_data[0] = 0x06;
1912 }
1913 cmd.start = CPIA2_VP_RAM_DATA;
1914 cmd.reg_count = 1;
1915 cpia2_send_command(cam, &cmd);
1916
1917 /* Rehash the VP4 values */
1918 cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4, TRANSFER_WRITE, 1);
1919}
1920
1921/******************************************************************************
1922 *
1923 * cpia2_set_format
1924 *
1925 * Assumes that new size is already set in param struct.
1926 *****************************************************************************/
1927void cpia2_set_format(struct camera_data *cam)
1928{
1929 cam->flush = true;
1930
1931 cpia2_usb_stream_pause(cam);
1932
1933 /* reset camera to new size */
1934 cpia2_set_low_power(cam);
1935 cpia2_reset_camera(cam);
1936 cam->flush = false;
1937
1938 cpia2_dbg_dump_registers(cam);
1939
1940 cpia2_usb_stream_resume(cam);
1941}
1942
1943/******************************************************************************
1944 *
1945 * cpia2_dbg_dump_registers
1946 *
1947 *****************************************************************************/
1948void cpia2_dbg_dump_registers(struct camera_data *cam)
1949{
1950#ifdef _CPIA2_DEBUG_
1951 struct cpia2_command cmd;
1952
1953 if (!(debugs_on & DEBUG_DUMP_REGS))
1954 return;
1955
1956 cmd.direction = TRANSFER_READ;
1957
1958 /* Start with bank 0 (SYSTEM) */
1959 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
1960 cmd.reg_count = 3;
1961 cmd.start = 0;
1962 cpia2_send_command(cam, &cmd);
1963 printk(KERN_DEBUG "System Device Hi = 0x%X\n",
1964 cmd.buffer.block_data[0]);
1965 printk(KERN_DEBUG "System Device Lo = 0x%X\n",
1966 cmd.buffer.block_data[1]);
1967 printk(KERN_DEBUG "System_system control = 0x%X\n",
1968 cmd.buffer.block_data[2]);
1969
1970 /* Bank 1 (VC) */
1971 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
1972 cmd.reg_count = 4;
1973 cmd.start = 0x80;
1974 cpia2_send_command(cam, &cmd);
1975 printk(KERN_DEBUG "ASIC_ID = 0x%X\n",
1976 cmd.buffer.block_data[0]);
1977 printk(KERN_DEBUG "ASIC_REV = 0x%X\n",
1978 cmd.buffer.block_data[1]);
1979 printk(KERN_DEBUG "PW_CONTRL = 0x%X\n",
1980 cmd.buffer.block_data[2]);
1981 printk(KERN_DEBUG "WAKEUP = 0x%X\n",
1982 cmd.buffer.block_data[3]);
1983
1984 cmd.start = 0xA0; /* ST_CTRL */
1985 cmd.reg_count = 1;
1986 cpia2_send_command(cam, &cmd);
1987 printk(KERN_DEBUG "Stream ctrl = 0x%X\n",
1988 cmd.buffer.block_data[0]);
1989
1990 cmd.start = 0xA4; /* Stream status */
1991 cpia2_send_command(cam, &cmd);
1992 printk(KERN_DEBUG "Stream status = 0x%X\n",
1993 cmd.buffer.block_data[0]);
1994
1995 cmd.start = 0xA8; /* USB status */
1996 cmd.reg_count = 3;
1997 cpia2_send_command(cam, &cmd);
1998 printk(KERN_DEBUG "USB_CTRL = 0x%X\n",
1999 cmd.buffer.block_data[0]);
2000 printk(KERN_DEBUG "USB_STRM = 0x%X\n",
2001 cmd.buffer.block_data[1]);
2002 printk(KERN_DEBUG "USB_STATUS = 0x%X\n",
2003 cmd.buffer.block_data[2]);
2004
2005 cmd.start = 0xAF; /* USB settings */
2006 cmd.reg_count = 1;
2007 cpia2_send_command(cam, &cmd);
2008 printk(KERN_DEBUG "USB settings = 0x%X\n",
2009 cmd.buffer.block_data[0]);
2010
2011 cmd.start = 0xC0; /* VC stuff */
2012 cmd.reg_count = 26;
2013 cpia2_send_command(cam, &cmd);
2014 printk(KERN_DEBUG "VC Control = 0x%0X\n",
2015 cmd.buffer.block_data[0]);
2016 printk(KERN_DEBUG "VC Format = 0x%0X\n",
2017 cmd.buffer.block_data[3]);
2018 printk(KERN_DEBUG "VC Clocks = 0x%0X\n",
2019 cmd.buffer.block_data[4]);
2020 printk(KERN_DEBUG "VC IHSize = 0x%0X\n",
2021 cmd.buffer.block_data[5]);
2022 printk(KERN_DEBUG "VC Xlim Hi = 0x%0X\n",
2023 cmd.buffer.block_data[6]);
2024 printk(KERN_DEBUG "VC XLim Lo = 0x%0X\n",
2025 cmd.buffer.block_data[7]);
2026 printk(KERN_DEBUG "VC YLim Hi = 0x%0X\n",
2027 cmd.buffer.block_data[8]);
2028 printk(KERN_DEBUG "VC YLim Lo = 0x%0X\n",
2029 cmd.buffer.block_data[9]);
2030 printk(KERN_DEBUG "VC OHSize = 0x%0X\n",
2031 cmd.buffer.block_data[10]);
2032 printk(KERN_DEBUG "VC OVSize = 0x%0X\n",
2033 cmd.buffer.block_data[11]);
2034 printk(KERN_DEBUG "VC HCrop = 0x%0X\n",
2035 cmd.buffer.block_data[12]);
2036 printk(KERN_DEBUG "VC VCrop = 0x%0X\n",
2037 cmd.buffer.block_data[13]);
2038 printk(KERN_DEBUG "VC HPhase = 0x%0X\n",
2039 cmd.buffer.block_data[14]);
2040 printk(KERN_DEBUG "VC VPhase = 0x%0X\n",
2041 cmd.buffer.block_data[15]);
2042 printk(KERN_DEBUG "VC HIspan = 0x%0X\n",
2043 cmd.buffer.block_data[16]);
2044 printk(KERN_DEBUG "VC VIspan = 0x%0X\n",
2045 cmd.buffer.block_data[17]);
2046 printk(KERN_DEBUG "VC HiCrop = 0x%0X\n",
2047 cmd.buffer.block_data[18]);
2048 printk(KERN_DEBUG "VC ViCrop = 0x%0X\n",
2049 cmd.buffer.block_data[19]);
2050 printk(KERN_DEBUG "VC HiFract = 0x%0X\n",
2051 cmd.buffer.block_data[20]);
2052 printk(KERN_DEBUG "VC ViFract = 0x%0X\n",
2053 cmd.buffer.block_data[21]);
2054 printk(KERN_DEBUG "VC JPeg Opt = 0x%0X\n",
2055 cmd.buffer.block_data[22]);
2056 printk(KERN_DEBUG "VC Creep Per = 0x%0X\n",
2057 cmd.buffer.block_data[23]);
2058 printk(KERN_DEBUG "VC User Sq. = 0x%0X\n",
2059 cmd.buffer.block_data[24]);
2060 printk(KERN_DEBUG "VC Target KB = 0x%0X\n",
2061 cmd.buffer.block_data[25]);
2062
2063 /*** VP ***/
2064 cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
2065 cmd.reg_count = 14;
2066 cmd.start = 0;
2067 cpia2_send_command(cam, &cmd);
2068
2069 printk(KERN_DEBUG "VP Dev Hi = 0x%0X\n",
2070 cmd.buffer.block_data[0]);
2071 printk(KERN_DEBUG "VP Dev Lo = 0x%0X\n",
2072 cmd.buffer.block_data[1]);
2073 printk(KERN_DEBUG "VP Sys State = 0x%0X\n",
2074 cmd.buffer.block_data[2]);
2075 printk(KERN_DEBUG "VP Sys Ctrl = 0x%0X\n",
2076 cmd.buffer.block_data[3]);
2077 printk(KERN_DEBUG "VP Sensor flg = 0x%0X\n",
2078 cmd.buffer.block_data[5]);
2079 printk(KERN_DEBUG "VP Sensor Rev = 0x%0X\n",
2080 cmd.buffer.block_data[6]);
2081 printk(KERN_DEBUG "VP Dev Config = 0x%0X\n",
2082 cmd.buffer.block_data[7]);
2083 printk(KERN_DEBUG "VP GPIO_DIR = 0x%0X\n",
2084 cmd.buffer.block_data[8]);
2085 printk(KERN_DEBUG "VP GPIO_DATA = 0x%0X\n",
2086 cmd.buffer.block_data[9]);
2087 printk(KERN_DEBUG "VP Ram ADDR H = 0x%0X\n",
2088 cmd.buffer.block_data[10]);
2089 printk(KERN_DEBUG "VP Ram ADDR L = 0x%0X\n",
2090 cmd.buffer.block_data[11]);
2091 printk(KERN_DEBUG "VP RAM Data = 0x%0X\n",
2092 cmd.buffer.block_data[12]);
2093 printk(KERN_DEBUG "Do Call = 0x%0X\n",
2094 cmd.buffer.block_data[13]);
2095
2096 if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
2097 cmd.reg_count = 9;
2098 cmd.start = 0x0E;
2099 cpia2_send_command(cam, &cmd);
2100 printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n",
2101 cmd.buffer.block_data[0]);
2102 printk(KERN_DEBUG "VP Patch Rev = 0x%0X\n",
2103 cmd.buffer.block_data[1]);
2104 printk(KERN_DEBUG "VP Vid Mode = 0x%0X\n",
2105 cmd.buffer.block_data[2]);
2106 printk(KERN_DEBUG "VP Framerate = 0x%0X\n",
2107 cmd.buffer.block_data[3]);
2108 printk(KERN_DEBUG "VP UserEffect = 0x%0X\n",
2109 cmd.buffer.block_data[4]);
2110 printk(KERN_DEBUG "VP White Bal = 0x%0X\n",
2111 cmd.buffer.block_data[5]);
2112 printk(KERN_DEBUG "VP WB thresh = 0x%0X\n",
2113 cmd.buffer.block_data[6]);
2114 printk(KERN_DEBUG "VP Exp Modes = 0x%0X\n",
2115 cmd.buffer.block_data[7]);
2116 printk(KERN_DEBUG "VP Exp Target = 0x%0X\n",
2117 cmd.buffer.block_data[8]);
2118
2119 cmd.reg_count = 1;
2120 cmd.start = 0x1B;
2121 cpia2_send_command(cam, &cmd);
2122 printk(KERN_DEBUG "VP FlickerMds = 0x%0X\n",
2123 cmd.buffer.block_data[0]);
2124 } else {
2125 cmd.reg_count = 8 ;
2126 cmd.start = 0x0E;
2127 cpia2_send_command(cam, &cmd);
2128 printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n",
2129 cmd.buffer.block_data[0]);
2130 printk(KERN_DEBUG "VP Patch Rev = 0x%0X\n",
2131 cmd.buffer.block_data[1]);
2132 printk(KERN_DEBUG "VP Vid Mode = 0x%0X\n",
2133 cmd.buffer.block_data[5]);
2134 printk(KERN_DEBUG "VP Framerate = 0x%0X\n",
2135 cmd.buffer.block_data[6]);
2136 printk(KERN_DEBUG "VP UserEffect = 0x%0X\n",
2137 cmd.buffer.block_data[7]);
2138
2139 cmd.reg_count = 1;
2140 cmd.start = CPIA2_VP5_EXPOSURE_TARGET;
2141 cpia2_send_command(cam, &cmd);
2142 printk(KERN_DEBUG "VP5 Exp Target= 0x%0X\n",
2143 cmd.buffer.block_data[0]);
2144
2145 cmd.reg_count = 4;
2146 cmd.start = 0x3A;
2147 cpia2_send_command(cam, &cmd);
2148 printk(KERN_DEBUG "VP5 MY Black = 0x%0X\n",
2149 cmd.buffer.block_data[0]);
2150 printk(KERN_DEBUG "VP5 MCY Range = 0x%0X\n",
2151 cmd.buffer.block_data[1]);
2152 printk(KERN_DEBUG "VP5 MYCEILING = 0x%0X\n",
2153 cmd.buffer.block_data[2]);
2154 printk(KERN_DEBUG "VP5 MCUV Sat = 0x%0X\n",
2155 cmd.buffer.block_data[3]);
2156 }
2157#endif
2158}
2159
2160/******************************************************************************
2161 *
2162 * reset_camera_struct
2163 *
2164 * Sets all values to the defaults
2165 *****************************************************************************/
2166static void reset_camera_struct(struct camera_data *cam)
2167{
2168 /***
2169 * The following parameter values are the defaults from the register map.
2170 ***/
2171 cam->params.color_params.brightness = DEFAULT_BRIGHTNESS;
2172 cam->params.color_params.contrast = DEFAULT_CONTRAST;
2173 cam->params.color_params.saturation = DEFAULT_SATURATION;
2174 cam->params.vp_params.lowlight_boost = 0;
2175
2176 /* FlickerModes */
2177 cam->params.flicker_control.flicker_mode_req = NEVER_FLICKER;
2178 cam->params.flicker_control.mains_frequency = 60;
2179
2180 /* jpeg params */
2181 cam->params.compression.jpeg_options = CPIA2_VC_VC_JPEG_OPT_DEFAULT;
2182 cam->params.compression.creep_period = 2;
2183 cam->params.compression.user_squeeze = 20;
2184 cam->params.compression.inhibit_htables = false;
2185
2186 /* gpio params */
2187 cam->params.vp_params.gpio_direction = 0; /* write, the default safe mode */
2188 cam->params.vp_params.gpio_data = 0;
2189
2190 /* Target kb params */
2191 cam->params.vc_params.target_kb = DEFAULT_TARGET_KB;
2192
2193 /***
2194 * Set Sensor FPS as fast as possible.
2195 ***/
2196 if(cam->params.pnp_id.device_type == DEVICE_STV_672) {
2197 if(cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500)
2198 cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_15;
2199 else
2200 cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30;
2201 } else {
2202 cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30;
2203 }
2204
2205 /***
2206 * Set default video mode as large as possible :
2207 * for vga sensor set to vga, for cif sensor set to CIF.
2208 ***/
2209 if (cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500) {
2210 cam->sensor_type = CPIA2_SENSOR_500;
2211 cam->video_size = VIDEOSIZE_VGA;
2212 cam->params.roi.width = STV_IMAGE_VGA_COLS;
2213 cam->params.roi.height = STV_IMAGE_VGA_ROWS;
2214 } else {
2215 cam->sensor_type = CPIA2_SENSOR_410;
2216 cam->video_size = VIDEOSIZE_CIF;
2217 cam->params.roi.width = STV_IMAGE_CIF_COLS;
2218 cam->params.roi.height = STV_IMAGE_CIF_ROWS;
2219 }
2220
2221 cam->width = cam->params.roi.width;
2222 cam->height = cam->params.roi.height;
2223}
2224
2225/******************************************************************************
2226 *
2227 * cpia2_init_camera_struct
2228 *
2229 * Initializes camera struct, does not call reset to fill in defaults.
2230 *****************************************************************************/
2231struct camera_data *cpia2_init_camera_struct(void)
2232{
2233 struct camera_data *cam;
2234
2235 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
2236
2237 if (!cam) {
2238 ERR("couldn't kmalloc cpia2 struct\n");
2239 return NULL;
2240 }
2241
2242
2243 cam->present = 1;
2244 mutex_init(&cam->v4l2_lock);
2245 init_waitqueue_head(&cam->wq_stream);
2246
2247 return cam;
2248}
2249
2250/******************************************************************************
2251 *
2252 * cpia2_init_camera
2253 *
2254 * Initializes camera.
2255 *****************************************************************************/
2256int cpia2_init_camera(struct camera_data *cam)
2257{
2258 DBG("Start\n");
2259
2260 cam->mmapped = false;
2261
2262 /* Get sensor and asic types before reset. */
2263 cpia2_set_high_power(cam);
2264 cpia2_get_version_info(cam);
2265 if (cam->params.version.asic_id != CPIA2_ASIC_672) {
2266 ERR("Device IO error (asicID has incorrect value of 0x%X\n",
2267 cam->params.version.asic_id);
2268 return -ENODEV;
2269 }
2270
2271 /* Set GPIO direction and data to a safe state. */
2272 cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
2273 TRANSFER_WRITE, 0);
2274 cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA,
2275 TRANSFER_WRITE, 0);
2276
2277 /* resetting struct requires version info for sensor and asic types */
2278 reset_camera_struct(cam);
2279
2280 cpia2_set_low_power(cam);
2281
2282 DBG("End\n");
2283
2284 return 0;
2285}
2286
2287/******************************************************************************
2288 *
2289 * cpia2_allocate_buffers
2290 *
2291 *****************************************************************************/
2292int cpia2_allocate_buffers(struct camera_data *cam)
2293{
2294 int i;
2295
2296 if(!cam->buffers) {
2297 u32 size = cam->num_frames*sizeof(struct framebuf);
2298 cam->buffers = kmalloc(size, GFP_KERNEL);
2299 if(!cam->buffers) {
2300 ERR("couldn't kmalloc frame buffer structures\n");
2301 return -ENOMEM;
2302 }
2303 }
2304
2305 if(!cam->frame_buffer) {
2306 cam->frame_buffer = rvmalloc(cam->frame_size*cam->num_frames);
2307 if (!cam->frame_buffer) {
2308 ERR("couldn't vmalloc frame buffer data area\n");
2309 kfree(cam->buffers);
2310 cam->buffers = NULL;
2311 return -ENOMEM;
2312 }
2313 }
2314
2315 for(i=0; i<cam->num_frames-1; ++i) {
2316 cam->buffers[i].next = &cam->buffers[i+1];
2317 cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size;
2318 cam->buffers[i].status = FRAME_EMPTY;
2319 cam->buffers[i].length = 0;
2320 cam->buffers[i].max_length = 0;
2321 cam->buffers[i].num = i;
2322 }
2323 cam->buffers[i].next = cam->buffers;
2324 cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size;
2325 cam->buffers[i].status = FRAME_EMPTY;
2326 cam->buffers[i].length = 0;
2327 cam->buffers[i].max_length = 0;
2328 cam->buffers[i].num = i;
2329 cam->curbuff = cam->buffers;
2330 cam->workbuff = cam->curbuff->next;
2331 DBG("buffers=%p, curbuff=%p, workbuff=%p\n", cam->buffers, cam->curbuff,
2332 cam->workbuff);
2333 return 0;
2334}
2335
2336/******************************************************************************
2337 *
2338 * cpia2_free_buffers
2339 *
2340 *****************************************************************************/
2341void cpia2_free_buffers(struct camera_data *cam)
2342{
2343 if(cam->buffers) {
2344 kfree(cam->buffers);
2345 cam->buffers = NULL;
2346 }
2347 if(cam->frame_buffer) {
2348 rvfree(cam->frame_buffer, cam->frame_size*cam->num_frames);
2349 cam->frame_buffer = NULL;
2350 }
2351}
2352
2353/******************************************************************************
2354 *
2355 * cpia2_read
2356 *
2357 *****************************************************************************/
2358long cpia2_read(struct camera_data *cam,
2359 char __user *buf, unsigned long count, int noblock)
2360{
2361 struct framebuf *frame;
2362
2363 if (!count)
2364 return 0;
2365
2366 if (!buf) {
2367 ERR("%s: buffer NULL\n",__func__);
2368 return -EINVAL;
2369 }
2370
2371 if (!cam) {
2372 ERR("%s: Internal error, camera_data NULL!\n",__func__);
2373 return -EINVAL;
2374 }
2375
2376 if (!cam->present) {
2377 LOG("%s: camera removed\n",__func__);
2378 return 0; /* EOF */
2379 }
2380
2381 if (!cam->streaming) {
2382 /* Start streaming */
2383 cpia2_usb_stream_start(cam,
2384 cam->params.camera_state.stream_mode);
2385 }
2386
2387 /* Copy cam->curbuff in case it changes while we're processing */
2388 frame = cam->curbuff;
2389 if (noblock && frame->status != FRAME_READY) {
2390 return -EAGAIN;
2391 }
2392
2393 if (frame->status != FRAME_READY) {
2394 mutex_unlock(&cam->v4l2_lock);
2395 wait_event_interruptible(cam->wq_stream,
2396 !cam->present ||
2397 (frame = cam->curbuff)->status == FRAME_READY);
2398 mutex_lock(&cam->v4l2_lock);
2399 if (signal_pending(current))
2400 return -ERESTARTSYS;
2401 if (!cam->present)
2402 return 0;
2403 }
2404
2405 /* copy data to user space */
2406 if (frame->length > count)
2407 return -EFAULT;
2408 if (copy_to_user(buf, frame->data, frame->length))
2409 return -EFAULT;
2410
2411 count = frame->length;
2412
2413 frame->status = FRAME_EMPTY;
2414
2415 return count;
2416}
2417
2418/******************************************************************************
2419 *
2420 * cpia2_poll
2421 *
2422 *****************************************************************************/
2423unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
2424 poll_table *wait)
2425{
2426 unsigned int status=0;
2427
2428 if (!cam) {
2429 ERR("%s: Internal error, camera_data not found!\n",__func__);
2430 return POLLERR;
2431 }
2432
2433 if (!cam->present)
2434 return POLLHUP;
2435
2436 if(!cam->streaming) {
2437 /* Start streaming */
2438 cpia2_usb_stream_start(cam,
2439 cam->params.camera_state.stream_mode);
2440 }
2441
2442 poll_wait(filp, &cam->wq_stream, wait);
2443
2444 if(!cam->present)
2445 status = POLLHUP;
2446 else if(cam->curbuff->status == FRAME_READY)
2447 status = POLLIN | POLLRDNORM;
2448
2449 return status;
2450}
2451
2452/******************************************************************************
2453 *
2454 * cpia2_remap_buffer
2455 *
2456 *****************************************************************************/
2457int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
2458{
2459 const char *adr = (const char *)vma->vm_start;
2460 unsigned long size = vma->vm_end-vma->vm_start;
2461 unsigned long start_offset = vma->vm_pgoff << PAGE_SHIFT;
2462 unsigned long start = (unsigned long) adr;
2463 unsigned long page, pos;
2464
2465 if (!cam)
2466 return -ENODEV;
2467
2468 DBG("mmap offset:%ld size:%ld\n", start_offset, size);
2469
2470 if (!cam->present)
2471 return -ENODEV;
2472
2473 if (size > cam->frame_size*cam->num_frames ||
2474 (start_offset % cam->frame_size) != 0 ||
2475 (start_offset+size > cam->frame_size*cam->num_frames))
2476 return -EINVAL;
2477
2478 pos = ((unsigned long) (cam->frame_buffer)) + start_offset;
2479 while (size > 0) {
2480 page = kvirt_to_pa(pos);
2481 if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED))
2482 return -EAGAIN;
2483 start += PAGE_SIZE;
2484 pos += PAGE_SIZE;
2485 if (size > PAGE_SIZE)
2486 size -= PAGE_SIZE;
2487 else
2488 size = 0;
2489 }
2490
2491 cam->mmapped = true;
2492 return 0;
2493}
diff --git a/drivers/media/video/cpia2/cpia2_registers.h b/drivers/media/video/cpia2/cpia2_registers.h
new file mode 100644
index 00000000000..3bbec514a96
--- /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 00000000000..dc5b07a20f6
--- /dev/null
+++ b/drivers/media/video/cpia2/cpia2_usb.c
@@ -0,0 +1,914 @@
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@lxorguk.ukuu.org.uk>
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);
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;
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)
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 *****************************************************************************/
481static int 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, j;
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 while (--i >= 0) {
644 kfree(cam->sbuf[i].data);
645 cam->sbuf[i].data = NULL;
646 }
647 return -ENOMEM;
648 }
649 }
650
651 /* We double buffer the Isoc lists, and also know the polling
652 * interval is every frame (1 == (1 << (bInterval -1))).
653 */
654 for(i=0; i<NUM_SBUF; ++i) {
655 if(cam->sbuf[i].urb) {
656 continue;
657 }
658 urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
659 if (!urb) {
660 ERR("%s: usb_alloc_urb error!\n", __func__);
661 for (j = 0; j < i; j++)
662 usb_free_urb(cam->sbuf[j].urb);
663 return -ENOMEM;
664 }
665
666 cam->sbuf[i].urb = urb;
667 urb->dev = cam->dev;
668 urb->context = cam;
669 urb->pipe = usb_rcvisocpipe(cam->dev, 1 /*ISOC endpoint*/);
670 urb->transfer_flags = URB_ISO_ASAP;
671 urb->transfer_buffer = cam->sbuf[i].data;
672 urb->complete = cpia2_usb_complete;
673 urb->number_of_packets = FRAMES_PER_DESC;
674 urb->interval = 1;
675 urb->transfer_buffer_length =
676 FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
677
678 for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
679 urb->iso_frame_desc[fx].offset =
680 FRAME_SIZE_PER_DESC * fx;
681 urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
682 }
683 }
684
685
686 /* Queue the ISO urbs, and resubmit in the completion handler */
687 for(i=0; i<NUM_SBUF; ++i) {
688 err = usb_submit_urb(cam->sbuf[i].urb, GFP_KERNEL);
689 if (err) {
690 ERR("usb_submit_urb[%d]() = %d\n", i, err);
691 return err;
692 }
693 }
694
695 return 0;
696}
697
698/******************************************************************************
699 *
700 * cpia2_usb_stream_start
701 *
702 *****************************************************************************/
703int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate)
704{
705 int ret;
706 int old_alt;
707
708 if(cam->streaming)
709 return 0;
710
711 if (cam->flush) {
712 int i;
713 DBG("Flushing buffers\n");
714 for(i=0; i<cam->num_frames; ++i) {
715 cam->buffers[i].status = FRAME_EMPTY;
716 cam->buffers[i].length = 0;
717 }
718 cam->curbuff = &cam->buffers[0];
719 cam->workbuff = cam->curbuff->next;
720 cam->flush = false;
721 }
722
723 old_alt = cam->params.camera_state.stream_mode;
724 cam->params.camera_state.stream_mode = 0;
725 ret = cpia2_usb_change_streaming_alternate(cam, alternate);
726 if (ret < 0) {
727 int ret2;
728 ERR("cpia2_usb_change_streaming_alternate() = %d!\n", ret);
729 cam->params.camera_state.stream_mode = old_alt;
730 ret2 = set_alternate(cam, USBIF_CMDONLY);
731 if (ret2 < 0) {
732 ERR("cpia2_usb_change_streaming_alternate(%d) =%d has already "
733 "failed. Then tried to call "
734 "set_alternate(USBIF_CMDONLY) = %d.\n",
735 alternate, ret, ret2);
736 }
737 } else {
738 cam->frame_count = 0;
739 cam->streaming = 1;
740 ret = cpia2_usb_stream_resume(cam);
741 }
742 return ret;
743}
744
745/******************************************************************************
746 *
747 * cpia2_usb_stream_pause
748 *
749 *****************************************************************************/
750int cpia2_usb_stream_pause(struct camera_data *cam)
751{
752 int ret = 0;
753 if(cam->streaming) {
754 ret = set_alternate(cam, USBIF_CMDONLY);
755 free_sbufs(cam);
756 }
757 return ret;
758}
759
760/******************************************************************************
761 *
762 * cpia2_usb_stream_resume
763 *
764 *****************************************************************************/
765int cpia2_usb_stream_resume(struct camera_data *cam)
766{
767 int ret = 0;
768 if(cam->streaming) {
769 cam->first_image_seen = 0;
770 ret = set_alternate(cam, cam->params.camera_state.stream_mode);
771 if(ret == 0) {
772 ret = submit_urbs(cam);
773 }
774 }
775 return ret;
776}
777
778/******************************************************************************
779 *
780 * cpia2_usb_stream_stop
781 *
782 *****************************************************************************/
783int cpia2_usb_stream_stop(struct camera_data *cam)
784{
785 int ret;
786 ret = cpia2_usb_stream_pause(cam);
787 cam->streaming = 0;
788 configure_transfer_mode(cam, 0);
789 return ret;
790}
791
792/******************************************************************************
793 *
794 * cpia2_usb_probe
795 *
796 * Probe and initialize.
797 *****************************************************************************/
798static int cpia2_usb_probe(struct usb_interface *intf,
799 const struct usb_device_id *id)
800{
801 struct usb_device *udev = interface_to_usbdev(intf);
802 struct usb_interface_descriptor *interface;
803 struct camera_data *cam;
804 int ret;
805
806 /* A multi-config CPiA2 camera? */
807 if (udev->descriptor.bNumConfigurations != 1)
808 return -ENODEV;
809 interface = &intf->cur_altsetting->desc;
810
811 /* If we get to this point, we found a CPiA2 camera */
812 LOG("CPiA2 USB camera found\n");
813
814 if((cam = cpia2_init_camera_struct()) == NULL)
815 return -ENOMEM;
816
817 cam->dev = udev;
818 cam->iface = interface->bInterfaceNumber;
819
820 ret = set_alternate(cam, USBIF_CMDONLY);
821 if (ret < 0) {
822 ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret);
823 kfree(cam);
824 return ret;
825 }
826
827 if ((ret = cpia2_register_camera(cam)) < 0) {
828 ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret);
829 kfree(cam);
830 return ret;
831 }
832
833
834 if((ret = cpia2_init_camera(cam)) < 0) {
835 ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret);
836 cpia2_unregister_camera(cam);
837 kfree(cam);
838 return ret;
839 }
840 LOG(" CPiA Version: %d.%02d (%d.%d)\n",
841 cam->params.version.firmware_revision_hi,
842 cam->params.version.firmware_revision_lo,
843 cam->params.version.asic_id,
844 cam->params.version.asic_rev);
845 LOG(" CPiA PnP-ID: %04x:%04x:%04x\n",
846 cam->params.pnp_id.vendor,
847 cam->params.pnp_id.product,
848 cam->params.pnp_id.device_revision);
849 LOG(" SensorID: %d.(version %d)\n",
850 cam->params.version.sensor_flags,
851 cam->params.version.sensor_rev);
852
853 usb_set_intfdata(intf, cam);
854
855 return 0;
856}
857
858/******************************************************************************
859 *
860 * cpia2_disconnect
861 *
862 *****************************************************************************/
863static void cpia2_usb_disconnect(struct usb_interface *intf)
864{
865 struct camera_data *cam = usb_get_intfdata(intf);
866 usb_set_intfdata(intf, NULL);
867 cam->present = 0;
868
869 DBG("Stopping stream\n");
870 cpia2_usb_stream_stop(cam);
871
872 DBG("Unregistering camera\n");
873 cpia2_unregister_camera(cam);
874
875 if(cam->buffers) {
876 DBG("Wakeup waiting processes\n");
877 cam->curbuff->status = FRAME_READY;
878 cam->curbuff->length = 0;
879 if (waitqueue_active(&cam->wq_stream))
880 wake_up_interruptible(&cam->wq_stream);
881 }
882
883 DBG("Releasing interface\n");
884 usb_driver_release_interface(&cpia2_driver, intf);
885
886 if (cam->open_count == 0) {
887 DBG("Freeing camera structure\n");
888 kfree(cam);
889 }
890
891 LOG("CPiA2 camera disconnected.\n");
892}
893
894
895/******************************************************************************
896 *
897 * usb_cpia2_init
898 *
899 *****************************************************************************/
900int cpia2_usb_init(void)
901{
902 return usb_register(&cpia2_driver);
903}
904
905/******************************************************************************
906 *
907 * usb_cpia_cleanup
908 *
909 *****************************************************************************/
910void cpia2_usb_cleanup(void)
911{
912 schedule_timeout(2 * HZ);
913 usb_deregister(&cpia2_driver);
914}
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
new file mode 100644
index 00000000000..077eb1db80a
--- /dev/null
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -0,0 +1,1578 @@
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@lxorguk.ukuu.org.uk>
30 ****************************************************************************/
31
32#define CPIA_VERSION "3.0.1"
33
34#include <linux/module.h>
35#include <linux/time.h>
36#include <linux/sched.h>
37#include <linux/slab.h>
38#include <linux/init.h>
39#include <linux/videodev2.h>
40#include <linux/stringify.h>
41#include <media/v4l2-ioctl.h>
42
43#include "cpia2.h"
44#include "cpia2dev.h"
45
46static int video_nr = -1;
47module_param(video_nr, int, 0);
48MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)");
49
50static int buffer_size = 68*1024;
51module_param(buffer_size, int, 0);
52MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)");
53
54static int num_buffers = 3;
55module_param(num_buffers, int, 0);
56MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-"
57 __stringify(VIDEO_MAX_FRAME) ", default 3)");
58
59static int alternate = DEFAULT_ALT;
60module_param(alternate, int, 0);
61MODULE_PARM_DESC(alternate, "USB Alternate (" __stringify(USBIF_ISO_1) "-"
62 __stringify(USBIF_ISO_6) ", default "
63 __stringify(DEFAULT_ALT) ")");
64
65static int flicker_freq = 60;
66module_param(flicker_freq, int, 0);
67MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" __stringify(50) "or"
68 __stringify(60) ", default "
69 __stringify(60) ")");
70
71static int flicker_mode = NEVER_FLICKER;
72module_param(flicker_mode, int, 0);
73MODULE_PARM_DESC(flicker_mode,
74 "Flicker supression (" __stringify(NEVER_FLICKER) "or"
75 __stringify(ANTI_FLICKER_ON) ", default "
76 __stringify(NEVER_FLICKER) ")");
77
78MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>");
79MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras");
80MODULE_SUPPORTED_DEVICE("video");
81MODULE_LICENSE("GPL");
82MODULE_VERSION(CPIA_VERSION);
83
84#define ABOUT "V4L-Driver for Vision CPiA2 based cameras"
85
86struct control_menu_info {
87 int value;
88 char name[32];
89};
90
91static struct control_menu_info framerate_controls[] =
92{
93 { CPIA2_VP_FRAMERATE_6_25, "6.25 fps" },
94 { CPIA2_VP_FRAMERATE_7_5, "7.5 fps" },
95 { CPIA2_VP_FRAMERATE_12_5, "12.5 fps" },
96 { CPIA2_VP_FRAMERATE_15, "15 fps" },
97 { CPIA2_VP_FRAMERATE_25, "25 fps" },
98 { CPIA2_VP_FRAMERATE_30, "30 fps" },
99};
100#define NUM_FRAMERATE_CONTROLS (ARRAY_SIZE(framerate_controls))
101
102static struct control_menu_info flicker_controls[] =
103{
104 { NEVER_FLICKER, "Off" },
105 { FLICKER_50, "50 Hz" },
106 { FLICKER_60, "60 Hz" },
107};
108#define NUM_FLICKER_CONTROLS (ARRAY_SIZE(flicker_controls))
109
110static struct control_menu_info lights_controls[] =
111{
112 { 0, "Off" },
113 { 64, "Top" },
114 { 128, "Bottom" },
115 { 192, "Both" },
116};
117#define NUM_LIGHTS_CONTROLS (ARRAY_SIZE(lights_controls))
118#define GPIO_LIGHTS_MASK 192
119
120static struct v4l2_queryctrl controls[] = {
121 {
122 .id = V4L2_CID_BRIGHTNESS,
123 .type = V4L2_CTRL_TYPE_INTEGER,
124 .name = "Brightness",
125 .minimum = 0,
126 .maximum = 255,
127 .step = 1,
128 .default_value = DEFAULT_BRIGHTNESS,
129 },
130 {
131 .id = V4L2_CID_CONTRAST,
132 .type = V4L2_CTRL_TYPE_INTEGER,
133 .name = "Contrast",
134 .minimum = 0,
135 .maximum = 255,
136 .step = 1,
137 .default_value = DEFAULT_CONTRAST,
138 },
139 {
140 .id = V4L2_CID_SATURATION,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "Saturation",
143 .minimum = 0,
144 .maximum = 255,
145 .step = 1,
146 .default_value = DEFAULT_SATURATION,
147 },
148 {
149 .id = V4L2_CID_HFLIP,
150 .type = V4L2_CTRL_TYPE_BOOLEAN,
151 .name = "Mirror Horizontally",
152 .minimum = 0,
153 .maximum = 1,
154 .step = 1,
155 .default_value = 0,
156 },
157 {
158 .id = V4L2_CID_VFLIP,
159 .type = V4L2_CTRL_TYPE_BOOLEAN,
160 .name = "Flip Vertically",
161 .minimum = 0,
162 .maximum = 1,
163 .step = 1,
164 .default_value = 0,
165 },
166 {
167 .id = CPIA2_CID_TARGET_KB,
168 .type = V4L2_CTRL_TYPE_INTEGER,
169 .name = "Target KB",
170 .minimum = 0,
171 .maximum = 255,
172 .step = 1,
173 .default_value = DEFAULT_TARGET_KB,
174 },
175 {
176 .id = CPIA2_CID_GPIO,
177 .type = V4L2_CTRL_TYPE_INTEGER,
178 .name = "GPIO",
179 .minimum = 0,
180 .maximum = 255,
181 .step = 1,
182 .default_value = 0,
183 },
184 {
185 .id = CPIA2_CID_FLICKER_MODE,
186 .type = V4L2_CTRL_TYPE_MENU,
187 .name = "Flicker Reduction",
188 .minimum = 0,
189 .maximum = NUM_FLICKER_CONTROLS-1,
190 .step = 1,
191 .default_value = 0,
192 },
193 {
194 .id = CPIA2_CID_FRAMERATE,
195 .type = V4L2_CTRL_TYPE_MENU,
196 .name = "Framerate",
197 .minimum = 0,
198 .maximum = NUM_FRAMERATE_CONTROLS-1,
199 .step = 1,
200 .default_value = NUM_FRAMERATE_CONTROLS-1,
201 },
202 {
203 .id = CPIA2_CID_USB_ALT,
204 .type = V4L2_CTRL_TYPE_INTEGER,
205 .name = "USB Alternate",
206 .minimum = USBIF_ISO_1,
207 .maximum = USBIF_ISO_6,
208 .step = 1,
209 .default_value = DEFAULT_ALT,
210 },
211 {
212 .id = CPIA2_CID_LIGHTS,
213 .type = V4L2_CTRL_TYPE_MENU,
214 .name = "Lights",
215 .minimum = 0,
216 .maximum = NUM_LIGHTS_CONTROLS-1,
217 .step = 1,
218 .default_value = 0,
219 },
220 {
221 .id = CPIA2_CID_RESET_CAMERA,
222 .type = V4L2_CTRL_TYPE_BUTTON,
223 .name = "Reset Camera",
224 .minimum = 0,
225 .maximum = 0,
226 .step = 0,
227 .default_value = 0,
228 },
229};
230#define NUM_CONTROLS (ARRAY_SIZE(controls))
231
232
233/******************************************************************************
234 *
235 * cpia2_open
236 *
237 *****************************************************************************/
238static int cpia2_open(struct file *file)
239{
240 struct camera_data *cam = video_drvdata(file);
241 struct cpia2_fh *fh;
242
243 if (!cam) {
244 ERR("Internal error, camera_data not found!\n");
245 return -ENODEV;
246 }
247
248 if (!cam->present)
249 return -ENODEV;
250
251 if (cam->open_count == 0) {
252 if (cpia2_allocate_buffers(cam))
253 return -ENOMEM;
254
255 /* reset the camera */
256 if (cpia2_reset_camera(cam) < 0)
257 return -EIO;
258
259 cam->APP_len = 0;
260 cam->COM_len = 0;
261 }
262
263 fh = kmalloc(sizeof(*fh), GFP_KERNEL);
264 if (!fh)
265 return -ENOMEM;
266 file->private_data = fh;
267 fh->prio = V4L2_PRIORITY_UNSET;
268 v4l2_prio_open(&cam->prio, &fh->prio);
269 fh->mmapped = 0;
270
271 ++cam->open_count;
272
273 cpia2_dbg_dump_registers(cam);
274 return 0;
275}
276
277/******************************************************************************
278 *
279 * cpia2_close
280 *
281 *****************************************************************************/
282static int cpia2_close(struct file *file)
283{
284 struct video_device *dev = video_devdata(file);
285 struct camera_data *cam = video_get_drvdata(dev);
286 struct cpia2_fh *fh = file->private_data;
287
288 if (cam->present &&
289 (cam->open_count == 1 || fh->prio == V4L2_PRIORITY_RECORD)) {
290 cpia2_usb_stream_stop(cam);
291
292 if (cam->open_count == 1) {
293 /* save camera state for later open */
294 cpia2_save_camera_state(cam);
295
296 cpia2_set_low_power(cam);
297 cpia2_free_buffers(cam);
298 }
299 }
300
301 if (fh->mmapped)
302 cam->mmapped = 0;
303 v4l2_prio_close(&cam->prio, fh->prio);
304 file->private_data = NULL;
305 kfree(fh);
306
307 if (--cam->open_count == 0) {
308 cpia2_free_buffers(cam);
309 if (!cam->present) {
310 video_unregister_device(dev);
311 kfree(cam);
312 return 0;
313 }
314 }
315
316 return 0;
317}
318
319/******************************************************************************
320 *
321 * cpia2_v4l_read
322 *
323 *****************************************************************************/
324static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count,
325 loff_t *off)
326{
327 struct camera_data *cam = video_drvdata(file);
328 int noblock = file->f_flags&O_NONBLOCK;
329
330 struct cpia2_fh *fh = file->private_data;
331
332 if(!cam)
333 return -EINVAL;
334
335 /* Priority check */
336 if(fh->prio != V4L2_PRIORITY_RECORD) {
337 return -EBUSY;
338 }
339
340 return cpia2_read(cam, buf, count, noblock);
341}
342
343
344/******************************************************************************
345 *
346 * cpia2_v4l_poll
347 *
348 *****************************************************************************/
349static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait)
350{
351 struct camera_data *cam = video_drvdata(filp);
352 struct cpia2_fh *fh = filp->private_data;
353
354 if(!cam)
355 return POLLERR;
356
357 /* Priority check */
358 if(fh->prio != V4L2_PRIORITY_RECORD) {
359 return POLLERR;
360 }
361
362 return cpia2_poll(cam, filp, wait);
363}
364
365
366static int sync(struct camera_data *cam, int frame_nr)
367{
368 struct framebuf *frame = &cam->buffers[frame_nr];
369
370 while (1) {
371 if (frame->status == FRAME_READY)
372 return 0;
373
374 if (!cam->streaming) {
375 frame->status = FRAME_READY;
376 frame->length = 0;
377 return 0;
378 }
379
380 mutex_unlock(&cam->v4l2_lock);
381 wait_event_interruptible(cam->wq_stream,
382 !cam->streaming ||
383 frame->status == FRAME_READY);
384 mutex_lock(&cam->v4l2_lock);
385 if (signal_pending(current))
386 return -ERESTARTSYS;
387 if(!cam->present)
388 return -ENOTTY;
389 }
390}
391
392/******************************************************************************
393 *
394 * ioctl_set_gpio
395 *
396 *****************************************************************************/
397
398static long cpia2_default(struct file *file, void *fh, bool valid_prio,
399 int cmd, void *arg)
400{
401 struct camera_data *cam = video_drvdata(file);
402 __u32 gpio_val;
403
404 if (cmd != CPIA2_CID_GPIO)
405 return -EINVAL;
406
407 gpio_val = *(__u32*) arg;
408
409 if (gpio_val &~ 0xFFU)
410 return -EINVAL;
411
412 return cpia2_set_gpio(cam, (unsigned char)gpio_val);
413}
414
415/******************************************************************************
416 *
417 * ioctl_querycap
418 *
419 * V4L2 device capabilities
420 *
421 *****************************************************************************/
422
423static int cpia2_querycap(struct file *file, void *fh, struct v4l2_capability *vc)
424{
425 struct camera_data *cam = video_drvdata(file);
426
427 strcpy(vc->driver, "cpia2");
428
429 if (cam->params.pnp_id.product == 0x151)
430 strcpy(vc->card, "QX5 Microscope");
431 else
432 strcpy(vc->card, "CPiA2 Camera");
433 switch (cam->params.pnp_id.device_type) {
434 case DEVICE_STV_672:
435 strcat(vc->card, " (672/");
436 break;
437 case DEVICE_STV_676:
438 strcat(vc->card, " (676/");
439 break;
440 default:
441 strcat(vc->card, " (XXX/");
442 break;
443 }
444 switch (cam->params.version.sensor_flags) {
445 case CPIA2_VP_SENSOR_FLAGS_404:
446 strcat(vc->card, "404)");
447 break;
448 case CPIA2_VP_SENSOR_FLAGS_407:
449 strcat(vc->card, "407)");
450 break;
451 case CPIA2_VP_SENSOR_FLAGS_409:
452 strcat(vc->card, "409)");
453 break;
454 case CPIA2_VP_SENSOR_FLAGS_410:
455 strcat(vc->card, "410)");
456 break;
457 case CPIA2_VP_SENSOR_FLAGS_500:
458 strcat(vc->card, "500)");
459 break;
460 default:
461 strcat(vc->card, "XXX)");
462 break;
463 }
464
465 if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0)
466 memset(vc->bus_info,0, sizeof(vc->bus_info));
467
468 vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
469 V4L2_CAP_READWRITE |
470 V4L2_CAP_STREAMING;
471
472 return 0;
473}
474
475/******************************************************************************
476 *
477 * ioctl_input
478 *
479 * V4L2 input get/set/enumerate
480 *
481 *****************************************************************************/
482
483static int cpia2_enum_input(struct file *file, void *fh, struct v4l2_input *i)
484{
485 if (i->index)
486 return -EINVAL;
487 strcpy(i->name, "Camera");
488 i->type = V4L2_INPUT_TYPE_CAMERA;
489 return 0;
490}
491
492static int cpia2_g_input(struct file *file, void *fh, unsigned int *i)
493{
494 *i = 0;
495 return 0;
496}
497
498static int cpia2_s_input(struct file *file, void *fh, unsigned int i)
499{
500 return i ? -EINVAL : 0;
501}
502
503/******************************************************************************
504 *
505 * ioctl_enum_fmt
506 *
507 * V4L2 format enumerate
508 *
509 *****************************************************************************/
510
511static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh,
512 struct v4l2_fmtdesc *f)
513{
514 int index = f->index;
515
516 if (index < 0 || index > 1)
517 return -EINVAL;
518
519 memset(f, 0, sizeof(*f));
520 f->index = index;
521 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
522 f->flags = V4L2_FMT_FLAG_COMPRESSED;
523 switch(index) {
524 case 0:
525 strcpy(f->description, "MJPEG");
526 f->pixelformat = V4L2_PIX_FMT_MJPEG;
527 break;
528 case 1:
529 strcpy(f->description, "JPEG");
530 f->pixelformat = V4L2_PIX_FMT_JPEG;
531 break;
532 default:
533 return -EINVAL;
534 }
535
536 return 0;
537}
538
539/******************************************************************************
540 *
541 * ioctl_try_fmt
542 *
543 * V4L2 format try
544 *
545 *****************************************************************************/
546
547static int cpia2_try_fmt_vid_cap(struct file *file, void *fh,
548 struct v4l2_format *f)
549{
550 struct camera_data *cam = video_drvdata(file);
551
552 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
553 f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
554 return -EINVAL;
555
556 f->fmt.pix.field = V4L2_FIELD_NONE;
557 f->fmt.pix.bytesperline = 0;
558 f->fmt.pix.sizeimage = cam->frame_size;
559 f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
560 f->fmt.pix.priv = 0;
561
562 switch (cpia2_match_video_size(f->fmt.pix.width, f->fmt.pix.height)) {
563 case VIDEOSIZE_VGA:
564 f->fmt.pix.width = 640;
565 f->fmt.pix.height = 480;
566 break;
567 case VIDEOSIZE_CIF:
568 f->fmt.pix.width = 352;
569 f->fmt.pix.height = 288;
570 break;
571 case VIDEOSIZE_QVGA:
572 f->fmt.pix.width = 320;
573 f->fmt.pix.height = 240;
574 break;
575 case VIDEOSIZE_288_216:
576 f->fmt.pix.width = 288;
577 f->fmt.pix.height = 216;
578 break;
579 case VIDEOSIZE_256_192:
580 f->fmt.pix.width = 256;
581 f->fmt.pix.height = 192;
582 break;
583 case VIDEOSIZE_224_168:
584 f->fmt.pix.width = 224;
585 f->fmt.pix.height = 168;
586 break;
587 case VIDEOSIZE_192_144:
588 f->fmt.pix.width = 192;
589 f->fmt.pix.height = 144;
590 break;
591 case VIDEOSIZE_QCIF:
592 default:
593 f->fmt.pix.width = 176;
594 f->fmt.pix.height = 144;
595 break;
596 }
597
598 return 0;
599}
600
601/******************************************************************************
602 *
603 * ioctl_set_fmt
604 *
605 * V4L2 format set
606 *
607 *****************************************************************************/
608
609static int cpia2_s_fmt_vid_cap(struct file *file, void *_fh,
610 struct v4l2_format *f)
611{
612 struct camera_data *cam = video_drvdata(file);
613 struct cpia2_fh *fh = _fh;
614 int err, frame;
615
616 err = v4l2_prio_check(&cam->prio, fh->prio);
617 if (err)
618 return err;
619 err = cpia2_try_fmt_vid_cap(file, _fh, f);
620 if(err != 0)
621 return err;
622
623 /* Ensure that only this process can change the format. */
624 err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD);
625 if(err != 0) {
626 return err;
627 }
628
629 cam->pixelformat = f->fmt.pix.pixelformat;
630
631 /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle
632 * the missing Huffman table properly. */
633 cam->params.compression.inhibit_htables = 0;
634 /*f->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG;*/
635
636 /* we set the video window to something smaller or equal to what
637 * is requested by the user???
638 */
639 DBG("Requested width = %d, height = %d\n",
640 f->fmt.pix.width, f->fmt.pix.height);
641 if (f->fmt.pix.width != cam->width ||
642 f->fmt.pix.height != cam->height) {
643 cam->width = f->fmt.pix.width;
644 cam->height = f->fmt.pix.height;
645 cam->params.roi.width = f->fmt.pix.width;
646 cam->params.roi.height = f->fmt.pix.height;
647 cpia2_set_format(cam);
648 }
649
650 for (frame = 0; frame < cam->num_frames; ++frame) {
651 if (cam->buffers[frame].status == FRAME_READING)
652 if ((err = sync(cam, frame)) < 0)
653 return err;
654
655 cam->buffers[frame].status = FRAME_EMPTY;
656 }
657
658 return 0;
659}
660
661/******************************************************************************
662 *
663 * ioctl_get_fmt
664 *
665 * V4L2 format get
666 *
667 *****************************************************************************/
668
669static int cpia2_g_fmt_vid_cap(struct file *file, void *fh,
670 struct v4l2_format *f)
671{
672 struct camera_data *cam = video_drvdata(file);
673
674 f->fmt.pix.width = cam->width;
675 f->fmt.pix.height = cam->height;
676 f->fmt.pix.pixelformat = cam->pixelformat;
677 f->fmt.pix.field = V4L2_FIELD_NONE;
678 f->fmt.pix.bytesperline = 0;
679 f->fmt.pix.sizeimage = cam->frame_size;
680 f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
681 f->fmt.pix.priv = 0;
682
683 return 0;
684}
685
686/******************************************************************************
687 *
688 * ioctl_cropcap
689 *
690 * V4L2 query cropping capabilities
691 * NOTE: cropping is currently disabled
692 *
693 *****************************************************************************/
694
695static int cpia2_cropcap(struct file *file, void *fh, struct v4l2_cropcap *c)
696{
697 struct camera_data *cam = video_drvdata(file);
698
699 if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
700 return -EINVAL;
701
702 c->bounds.left = 0;
703 c->bounds.top = 0;
704 c->bounds.width = cam->width;
705 c->bounds.height = cam->height;
706 c->defrect.left = 0;
707 c->defrect.top = 0;
708 c->defrect.width = cam->width;
709 c->defrect.height = cam->height;
710 c->pixelaspect.numerator = 1;
711 c->pixelaspect.denominator = 1;
712
713 return 0;
714}
715
716/******************************************************************************
717 *
718 * ioctl_queryctrl
719 *
720 * V4L2 query possible control variables
721 *
722 *****************************************************************************/
723
724static int cpia2_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
725{
726 struct camera_data *cam = video_drvdata(file);
727 int i;
728
729 for(i=0; i<NUM_CONTROLS; ++i) {
730 if(c->id == controls[i].id) {
731 memcpy(c, controls+i, sizeof(*c));
732 break;
733 }
734 }
735
736 if(i == NUM_CONTROLS)
737 return -EINVAL;
738
739 /* Some devices have additional limitations */
740 switch(c->id) {
741 case V4L2_CID_BRIGHTNESS:
742 /***
743 * Don't let the register be set to zero - bug in VP4
744 * flash of full brightness
745 ***/
746 if (cam->params.pnp_id.device_type == DEVICE_STV_672)
747 c->minimum = 1;
748 break;
749 case V4L2_CID_VFLIP:
750 // VP5 Only
751 if(cam->params.pnp_id.device_type == DEVICE_STV_672)
752 c->flags |= V4L2_CTRL_FLAG_DISABLED;
753 break;
754 case CPIA2_CID_FRAMERATE:
755 if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
756 cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
757 // Maximum 15fps
758 for(i=0; i<c->maximum; ++i) {
759 if(framerate_controls[i].value ==
760 CPIA2_VP_FRAMERATE_15) {
761 c->maximum = i;
762 c->default_value = i;
763 }
764 }
765 }
766 break;
767 case CPIA2_CID_FLICKER_MODE:
768 // Flicker control only valid for 672.
769 if(cam->params.pnp_id.device_type != DEVICE_STV_672)
770 c->flags |= V4L2_CTRL_FLAG_DISABLED;
771 break;
772 case CPIA2_CID_LIGHTS:
773 // Light control only valid for the QX5 Microscope.
774 if(cam->params.pnp_id.product != 0x151)
775 c->flags |= V4L2_CTRL_FLAG_DISABLED;
776 break;
777 default:
778 break;
779 }
780
781 return 0;
782}
783
784/******************************************************************************
785 *
786 * ioctl_querymenu
787 *
788 * V4L2 query possible control variables
789 *
790 *****************************************************************************/
791
792static int cpia2_querymenu(struct file *file, void *fh, struct v4l2_querymenu *m)
793{
794 struct camera_data *cam = video_drvdata(file);
795
796 switch(m->id) {
797 case CPIA2_CID_FLICKER_MODE:
798 if (m->index >= NUM_FLICKER_CONTROLS)
799 return -EINVAL;
800
801 strcpy(m->name, flicker_controls[m->index].name);
802 break;
803 case CPIA2_CID_FRAMERATE:
804 {
805 int maximum = NUM_FRAMERATE_CONTROLS - 1;
806 if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
807 cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
808 // Maximum 15fps
809 int i;
810 for(i=0; i<maximum; ++i) {
811 if(framerate_controls[i].value ==
812 CPIA2_VP_FRAMERATE_15)
813 maximum = i;
814 }
815 }
816 if (m->index > maximum)
817 return -EINVAL;
818
819 strcpy(m->name, framerate_controls[m->index].name);
820 break;
821 }
822 case CPIA2_CID_LIGHTS:
823 if (m->index >= NUM_LIGHTS_CONTROLS)
824 return -EINVAL;
825
826 strcpy(m->name, lights_controls[m->index].name);
827 break;
828 default:
829 return -EINVAL;
830 }
831
832 return 0;
833}
834
835/******************************************************************************
836 *
837 * ioctl_g_ctrl
838 *
839 * V4L2 get the value of a control variable
840 *
841 *****************************************************************************/
842
843static int cpia2_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
844{
845 struct camera_data *cam = video_drvdata(file);
846
847 switch(c->id) {
848 case V4L2_CID_BRIGHTNESS:
849 cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS,
850 TRANSFER_READ, 0);
851 c->value = cam->params.color_params.brightness;
852 break;
853 case V4L2_CID_CONTRAST:
854 cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST,
855 TRANSFER_READ, 0);
856 c->value = cam->params.color_params.contrast;
857 break;
858 case V4L2_CID_SATURATION:
859 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION,
860 TRANSFER_READ, 0);
861 c->value = cam->params.color_params.saturation;
862 break;
863 case V4L2_CID_HFLIP:
864 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS,
865 TRANSFER_READ, 0);
866 c->value = (cam->params.vp_params.user_effects &
867 CPIA2_VP_USER_EFFECTS_MIRROR) != 0;
868 break;
869 case V4L2_CID_VFLIP:
870 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS,
871 TRANSFER_READ, 0);
872 c->value = (cam->params.vp_params.user_effects &
873 CPIA2_VP_USER_EFFECTS_FLIP) != 0;
874 break;
875 case CPIA2_CID_TARGET_KB:
876 c->value = cam->params.vc_params.target_kb;
877 break;
878 case CPIA2_CID_GPIO:
879 cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA,
880 TRANSFER_READ, 0);
881 c->value = cam->params.vp_params.gpio_data;
882 break;
883 case CPIA2_CID_FLICKER_MODE:
884 {
885 int i, mode;
886 cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES,
887 TRANSFER_READ, 0);
888 if(cam->params.flicker_control.cam_register &
889 CPIA2_VP_FLICKER_MODES_NEVER_FLICKER) {
890 mode = NEVER_FLICKER;
891 } else {
892 if(cam->params.flicker_control.cam_register &
893 CPIA2_VP_FLICKER_MODES_50HZ) {
894 mode = FLICKER_50;
895 } else {
896 mode = FLICKER_60;
897 }
898 }
899 for(i=0; i<NUM_FLICKER_CONTROLS; i++) {
900 if(flicker_controls[i].value == mode) {
901 c->value = i;
902 break;
903 }
904 }
905 if(i == NUM_FLICKER_CONTROLS)
906 return -EINVAL;
907 break;
908 }
909 case CPIA2_CID_FRAMERATE:
910 {
911 int maximum = NUM_FRAMERATE_CONTROLS - 1;
912 int i;
913 for(i=0; i<= maximum; i++) {
914 if(cam->params.vp_params.frame_rate ==
915 framerate_controls[i].value)
916 break;
917 }
918 if(i > maximum)
919 return -EINVAL;
920 c->value = i;
921 break;
922 }
923 case CPIA2_CID_USB_ALT:
924 c->value = cam->params.camera_state.stream_mode;
925 break;
926 case CPIA2_CID_LIGHTS:
927 {
928 int i;
929 cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA,
930 TRANSFER_READ, 0);
931 for(i=0; i<NUM_LIGHTS_CONTROLS; i++) {
932 if((cam->params.vp_params.gpio_data&GPIO_LIGHTS_MASK) ==
933 lights_controls[i].value) {
934 break;
935 }
936 }
937 if(i == NUM_LIGHTS_CONTROLS)
938 return -EINVAL;
939 c->value = i;
940 break;
941 }
942 case CPIA2_CID_RESET_CAMERA:
943 return -EINVAL;
944 default:
945 return -EINVAL;
946 }
947
948 DBG("Get control id:%d, value:%d\n", c->id, c->value);
949
950 return 0;
951}
952
953/******************************************************************************
954 *
955 * ioctl_s_ctrl
956 *
957 * V4L2 set the value of a control variable
958 *
959 *****************************************************************************/
960
961static int cpia2_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
962{
963 struct camera_data *cam = video_drvdata(file);
964 int i;
965 int retval = 0;
966
967 DBG("Set control id:%d, value:%d\n", c->id, c->value);
968
969 /* Check that the value is in range */
970 for(i=0; i<NUM_CONTROLS; i++) {
971 if(c->id == controls[i].id) {
972 if(c->value < controls[i].minimum ||
973 c->value > controls[i].maximum) {
974 return -EINVAL;
975 }
976 break;
977 }
978 }
979 if(i == NUM_CONTROLS)
980 return -EINVAL;
981
982 switch(c->id) {
983 case V4L2_CID_BRIGHTNESS:
984 cpia2_set_brightness(cam, c->value);
985 break;
986 case V4L2_CID_CONTRAST:
987 cpia2_set_contrast(cam, c->value);
988 break;
989 case V4L2_CID_SATURATION:
990 cpia2_set_saturation(cam, c->value);
991 break;
992 case V4L2_CID_HFLIP:
993 cpia2_set_property_mirror(cam, c->value);
994 break;
995 case V4L2_CID_VFLIP:
996 cpia2_set_property_flip(cam, c->value);
997 break;
998 case CPIA2_CID_TARGET_KB:
999 retval = cpia2_set_target_kb(cam, c->value);
1000 break;
1001 case CPIA2_CID_GPIO:
1002 retval = cpia2_set_gpio(cam, c->value);
1003 break;
1004 case CPIA2_CID_FLICKER_MODE:
1005 retval = cpia2_set_flicker_mode(cam,
1006 flicker_controls[c->value].value);
1007 break;
1008 case CPIA2_CID_FRAMERATE:
1009 retval = cpia2_set_fps(cam, framerate_controls[c->value].value);
1010 break;
1011 case CPIA2_CID_USB_ALT:
1012 retval = cpia2_usb_change_streaming_alternate(cam, c->value);
1013 break;
1014 case CPIA2_CID_LIGHTS:
1015 retval = cpia2_set_gpio(cam, lights_controls[c->value].value);
1016 break;
1017 case CPIA2_CID_RESET_CAMERA:
1018 cpia2_usb_stream_pause(cam);
1019 cpia2_reset_camera(cam);
1020 cpia2_usb_stream_resume(cam);
1021 break;
1022 default:
1023 retval = -EINVAL;
1024 }
1025
1026 return retval;
1027}
1028
1029/******************************************************************************
1030 *
1031 * ioctl_g_jpegcomp
1032 *
1033 * V4L2 get the JPEG compression parameters
1034 *
1035 *****************************************************************************/
1036
1037static int cpia2_g_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms)
1038{
1039 struct camera_data *cam = video_drvdata(file);
1040
1041 memset(parms, 0, sizeof(*parms));
1042
1043 parms->quality = 80; // TODO: Can this be made meaningful?
1044
1045 parms->jpeg_markers = V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI;
1046 if(!cam->params.compression.inhibit_htables) {
1047 parms->jpeg_markers |= V4L2_JPEG_MARKER_DHT;
1048 }
1049
1050 parms->APPn = cam->APPn;
1051 parms->APP_len = cam->APP_len;
1052 if(cam->APP_len > 0) {
1053 memcpy(parms->APP_data, cam->APP_data, cam->APP_len);
1054 parms->jpeg_markers |= V4L2_JPEG_MARKER_APP;
1055 }
1056
1057 parms->COM_len = cam->COM_len;
1058 if(cam->COM_len > 0) {
1059 memcpy(parms->COM_data, cam->COM_data, cam->COM_len);
1060 parms->jpeg_markers |= JPEG_MARKER_COM;
1061 }
1062
1063 DBG("G_JPEGCOMP APP_len:%d COM_len:%d\n",
1064 parms->APP_len, parms->COM_len);
1065
1066 return 0;
1067}
1068
1069/******************************************************************************
1070 *
1071 * ioctl_s_jpegcomp
1072 *
1073 * V4L2 set the JPEG compression parameters
1074 * NOTE: quality and some jpeg_markers are ignored.
1075 *
1076 *****************************************************************************/
1077
1078static int cpia2_s_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms)
1079{
1080 struct camera_data *cam = video_drvdata(file);
1081
1082 DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n",
1083 parms->APP_len, parms->COM_len);
1084
1085 cam->params.compression.inhibit_htables =
1086 !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT);
1087
1088 if(parms->APP_len != 0) {
1089 if(parms->APP_len > 0 &&
1090 parms->APP_len <= sizeof(cam->APP_data) &&
1091 parms->APPn >= 0 && parms->APPn <= 15) {
1092 cam->APPn = parms->APPn;
1093 cam->APP_len = parms->APP_len;
1094 memcpy(cam->APP_data, parms->APP_data, parms->APP_len);
1095 } else {
1096 LOG("Bad APPn Params n=%d len=%d\n",
1097 parms->APPn, parms->APP_len);
1098 return -EINVAL;
1099 }
1100 } else {
1101 cam->APP_len = 0;
1102 }
1103
1104 if(parms->COM_len != 0) {
1105 if(parms->COM_len > 0 &&
1106 parms->COM_len <= sizeof(cam->COM_data)) {
1107 cam->COM_len = parms->COM_len;
1108 memcpy(cam->COM_data, parms->COM_data, parms->COM_len);
1109 } else {
1110 LOG("Bad COM_len=%d\n", parms->COM_len);
1111 return -EINVAL;
1112 }
1113 }
1114
1115 return 0;
1116}
1117
1118/******************************************************************************
1119 *
1120 * ioctl_reqbufs
1121 *
1122 * V4L2 Initiate memory mapping.
1123 * NOTE: The user's request is ignored. For now the buffers are fixed.
1124 *
1125 *****************************************************************************/
1126
1127static int cpia2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *req)
1128{
1129 struct camera_data *cam = video_drvdata(file);
1130
1131 if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1132 req->memory != V4L2_MEMORY_MMAP)
1133 return -EINVAL;
1134
1135 DBG("REQBUFS requested:%d returning:%d\n", req->count, cam->num_frames);
1136 req->count = cam->num_frames;
1137 memset(&req->reserved, 0, sizeof(req->reserved));
1138
1139 return 0;
1140}
1141
1142/******************************************************************************
1143 *
1144 * ioctl_querybuf
1145 *
1146 * V4L2 Query memory buffer status.
1147 *
1148 *****************************************************************************/
1149
1150static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1151{
1152 struct camera_data *cam = video_drvdata(file);
1153
1154 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1155 buf->index > cam->num_frames)
1156 return -EINVAL;
1157
1158 buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
1159 buf->length = cam->frame_size;
1160
1161 buf->memory = V4L2_MEMORY_MMAP;
1162
1163 if(cam->mmapped)
1164 buf->flags = V4L2_BUF_FLAG_MAPPED;
1165 else
1166 buf->flags = 0;
1167
1168 switch (cam->buffers[buf->index].status) {
1169 case FRAME_EMPTY:
1170 case FRAME_ERROR:
1171 case FRAME_READING:
1172 buf->bytesused = 0;
1173 buf->flags = V4L2_BUF_FLAG_QUEUED;
1174 break;
1175 case FRAME_READY:
1176 buf->bytesused = cam->buffers[buf->index].length;
1177 buf->timestamp = cam->buffers[buf->index].timestamp;
1178 buf->sequence = cam->buffers[buf->index].seq;
1179 buf->flags = V4L2_BUF_FLAG_DONE;
1180 break;
1181 }
1182
1183 DBG("QUERYBUF index:%d offset:%d flags:%d seq:%d bytesused:%d\n",
1184 buf->index, buf->m.offset, buf->flags, buf->sequence,
1185 buf->bytesused);
1186
1187 return 0;
1188}
1189
1190/******************************************************************************
1191 *
1192 * ioctl_qbuf
1193 *
1194 * V4L2 User is freeing buffer
1195 *
1196 *****************************************************************************/
1197
1198static int cpia2_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1199{
1200 struct camera_data *cam = video_drvdata(file);
1201
1202 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1203 buf->memory != V4L2_MEMORY_MMAP ||
1204 buf->index > cam->num_frames)
1205 return -EINVAL;
1206
1207 DBG("QBUF #%d\n", buf->index);
1208
1209 if(cam->buffers[buf->index].status == FRAME_READY)
1210 cam->buffers[buf->index].status = FRAME_EMPTY;
1211
1212 return 0;
1213}
1214
1215/******************************************************************************
1216 *
1217 * find_earliest_filled_buffer
1218 *
1219 * Helper for ioctl_dqbuf. Find the next ready buffer.
1220 *
1221 *****************************************************************************/
1222
1223static int find_earliest_filled_buffer(struct camera_data *cam)
1224{
1225 int i;
1226 int found = -1;
1227 for (i=0; i<cam->num_frames; i++) {
1228 if(cam->buffers[i].status == FRAME_READY) {
1229 if(found < 0) {
1230 found = i;
1231 } else {
1232 /* find which buffer is earlier */
1233 struct timeval *tv1, *tv2;
1234 tv1 = &cam->buffers[i].timestamp;
1235 tv2 = &cam->buffers[found].timestamp;
1236 if(tv1->tv_sec < tv2->tv_sec ||
1237 (tv1->tv_sec == tv2->tv_sec &&
1238 tv1->tv_usec < tv2->tv_usec))
1239 found = i;
1240 }
1241 }
1242 }
1243 return found;
1244}
1245
1246/******************************************************************************
1247 *
1248 * ioctl_dqbuf
1249 *
1250 * V4L2 User is asking for a filled buffer.
1251 *
1252 *****************************************************************************/
1253
1254static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1255{
1256 struct camera_data *cam = video_drvdata(file);
1257 int frame;
1258
1259 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1260 buf->memory != V4L2_MEMORY_MMAP)
1261 return -EINVAL;
1262
1263 frame = find_earliest_filled_buffer(cam);
1264
1265 if(frame < 0 && file->f_flags&O_NONBLOCK)
1266 return -EAGAIN;
1267
1268 if(frame < 0) {
1269 /* Wait for a frame to become available */
1270 struct framebuf *cb=cam->curbuff;
1271 mutex_unlock(&cam->v4l2_lock);
1272 wait_event_interruptible(cam->wq_stream,
1273 !cam->present ||
1274 (cb=cam->curbuff)->status == FRAME_READY);
1275 mutex_lock(&cam->v4l2_lock);
1276 if (signal_pending(current))
1277 return -ERESTARTSYS;
1278 if(!cam->present)
1279 return -ENOTTY;
1280 frame = cb->num;
1281 }
1282
1283
1284 buf->index = frame;
1285 buf->bytesused = cam->buffers[buf->index].length;
1286 buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
1287 buf->field = V4L2_FIELD_NONE;
1288 buf->timestamp = cam->buffers[buf->index].timestamp;
1289 buf->sequence = cam->buffers[buf->index].seq;
1290 buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
1291 buf->length = cam->frame_size;
1292 buf->input = 0;
1293 buf->reserved = 0;
1294 memset(&buf->timecode, 0, sizeof(buf->timecode));
1295
1296 DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index,
1297 cam->buffers[buf->index].status, buf->sequence, buf->bytesused);
1298
1299 return 0;
1300}
1301
1302static int cpia2_g_priority(struct file *file, void *_fh, enum v4l2_priority *p)
1303{
1304 struct cpia2_fh *fh = _fh;
1305
1306 *p = fh->prio;
1307 return 0;
1308}
1309
1310static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio)
1311{
1312 struct camera_data *cam = video_drvdata(file);
1313 struct cpia2_fh *fh = _fh;
1314
1315 if (cam->streaming && prio != fh->prio &&
1316 fh->prio == V4L2_PRIORITY_RECORD)
1317 /* Can't drop record priority while streaming */
1318 return -EBUSY;
1319
1320 if (prio == V4L2_PRIORITY_RECORD && prio != fh->prio &&
1321 v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD)
1322 /* Only one program can record at a time */
1323 return -EBUSY;
1324 return v4l2_prio_change(&cam->prio, &fh->prio, prio);
1325}
1326
1327static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1328{
1329 struct camera_data *cam = video_drvdata(file);
1330
1331 DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming);
1332 if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1333 return -EINVAL;
1334
1335 if (!cam->streaming)
1336 return cpia2_usb_stream_start(cam,
1337 cam->params.camera_state.stream_mode);
1338 return -EINVAL;
1339}
1340
1341static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1342{
1343 struct camera_data *cam = video_drvdata(file);
1344
1345 DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming);
1346 if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1347 return -EINVAL;
1348
1349 if (cam->streaming)
1350 return cpia2_usb_stream_stop(cam);
1351 return -EINVAL;
1352}
1353
1354/******************************************************************************
1355 *
1356 * cpia2_mmap
1357 *
1358 *****************************************************************************/
1359static int cpia2_mmap(struct file *file, struct vm_area_struct *area)
1360{
1361 struct camera_data *cam = video_drvdata(file);
1362 int retval;
1363
1364 /* Priority check */
1365 struct cpia2_fh *fh = file->private_data;
1366 if(fh->prio != V4L2_PRIORITY_RECORD) {
1367 return -EBUSY;
1368 }
1369
1370 retval = cpia2_remap_buffer(cam, area);
1371
1372 if(!retval)
1373 fh->mmapped = 1;
1374 return retval;
1375}
1376
1377/******************************************************************************
1378 *
1379 * reset_camera_struct_v4l
1380 *
1381 * Sets all values to the defaults
1382 *****************************************************************************/
1383static void reset_camera_struct_v4l(struct camera_data *cam)
1384{
1385 cam->width = cam->params.roi.width;
1386 cam->height = cam->params.roi.height;
1387
1388 cam->frame_size = buffer_size;
1389 cam->num_frames = num_buffers;
1390
1391 /* FlickerModes */
1392 cam->params.flicker_control.flicker_mode_req = flicker_mode;
1393 cam->params.flicker_control.mains_frequency = flicker_freq;
1394
1395 /* streamMode */
1396 cam->params.camera_state.stream_mode = alternate;
1397
1398 cam->pixelformat = V4L2_PIX_FMT_JPEG;
1399 v4l2_prio_init(&cam->prio);
1400}
1401
1402static const struct v4l2_ioctl_ops cpia2_ioctl_ops = {
1403 .vidioc_querycap = cpia2_querycap,
1404 .vidioc_enum_input = cpia2_enum_input,
1405 .vidioc_g_input = cpia2_g_input,
1406 .vidioc_s_input = cpia2_s_input,
1407 .vidioc_enum_fmt_vid_cap = cpia2_enum_fmt_vid_cap,
1408 .vidioc_g_fmt_vid_cap = cpia2_g_fmt_vid_cap,
1409 .vidioc_s_fmt_vid_cap = cpia2_s_fmt_vid_cap,
1410 .vidioc_try_fmt_vid_cap = cpia2_try_fmt_vid_cap,
1411 .vidioc_queryctrl = cpia2_queryctrl,
1412 .vidioc_querymenu = cpia2_querymenu,
1413 .vidioc_g_ctrl = cpia2_g_ctrl,
1414 .vidioc_s_ctrl = cpia2_s_ctrl,
1415 .vidioc_g_jpegcomp = cpia2_g_jpegcomp,
1416 .vidioc_s_jpegcomp = cpia2_s_jpegcomp,
1417 .vidioc_cropcap = cpia2_cropcap,
1418 .vidioc_reqbufs = cpia2_reqbufs,
1419 .vidioc_querybuf = cpia2_querybuf,
1420 .vidioc_qbuf = cpia2_qbuf,
1421 .vidioc_dqbuf = cpia2_dqbuf,
1422 .vidioc_streamon = cpia2_streamon,
1423 .vidioc_streamoff = cpia2_streamoff,
1424 .vidioc_g_priority = cpia2_g_priority,
1425 .vidioc_s_priority = cpia2_s_priority,
1426 .vidioc_default = cpia2_default,
1427};
1428
1429/***
1430 * The v4l video device structure initialized for this device
1431 ***/
1432static const struct v4l2_file_operations cpia2_fops = {
1433 .owner = THIS_MODULE,
1434 .open = cpia2_open,
1435 .release = cpia2_close,
1436 .read = cpia2_v4l_read,
1437 .poll = cpia2_v4l_poll,
1438 .unlocked_ioctl = video_ioctl2,
1439 .mmap = cpia2_mmap,
1440};
1441
1442static struct video_device cpia2_template = {
1443 /* I could not find any place for the old .initialize initializer?? */
1444 .name = "CPiA2 Camera",
1445 .fops = &cpia2_fops,
1446 .ioctl_ops = &cpia2_ioctl_ops,
1447 .release = video_device_release,
1448};
1449
1450/******************************************************************************
1451 *
1452 * cpia2_register_camera
1453 *
1454 *****************************************************************************/
1455int cpia2_register_camera(struct camera_data *cam)
1456{
1457 cam->vdev = video_device_alloc();
1458 if(!cam->vdev)
1459 return -ENOMEM;
1460
1461 memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template));
1462 video_set_drvdata(cam->vdev, cam);
1463 cam->vdev->lock = &cam->v4l2_lock;
1464
1465 reset_camera_struct_v4l(cam);
1466
1467 /* register v4l device */
1468 if (video_register_device(cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1469 ERR("video_register_device failed\n");
1470 video_device_release(cam->vdev);
1471 return -ENODEV;
1472 }
1473
1474 return 0;
1475}
1476
1477/******************************************************************************
1478 *
1479 * cpia2_unregister_camera
1480 *
1481 *****************************************************************************/
1482void cpia2_unregister_camera(struct camera_data *cam)
1483{
1484 if (!cam->open_count) {
1485 video_unregister_device(cam->vdev);
1486 } else {
1487 LOG("%s removed while open, deferring "
1488 "video_unregister_device\n",
1489 video_device_node_name(cam->vdev));
1490 }
1491}
1492
1493/******************************************************************************
1494 *
1495 * check_parameters
1496 *
1497 * Make sure that all user-supplied parameters are sensible
1498 *****************************************************************************/
1499static void __init check_parameters(void)
1500{
1501 if(buffer_size < PAGE_SIZE) {
1502 buffer_size = PAGE_SIZE;
1503 LOG("buffer_size too small, setting to %d\n", buffer_size);
1504 } else if(buffer_size > 1024*1024) {
1505 /* arbitrary upper limiit */
1506 buffer_size = 1024*1024;
1507 LOG("buffer_size ridiculously large, setting to %d\n",
1508 buffer_size);
1509 } else {
1510 buffer_size += PAGE_SIZE-1;
1511 buffer_size &= ~(PAGE_SIZE-1);
1512 }
1513
1514 if(num_buffers < 1) {
1515 num_buffers = 1;
1516 LOG("num_buffers too small, setting to %d\n", num_buffers);
1517 } else if(num_buffers > VIDEO_MAX_FRAME) {
1518 num_buffers = VIDEO_MAX_FRAME;
1519 LOG("num_buffers too large, setting to %d\n", num_buffers);
1520 }
1521
1522 if(alternate < USBIF_ISO_1 || alternate > USBIF_ISO_6) {
1523 alternate = DEFAULT_ALT;
1524 LOG("alternate specified is invalid, using %d\n", alternate);
1525 }
1526
1527 if (flicker_mode != NEVER_FLICKER && flicker_mode != ANTI_FLICKER_ON) {
1528 flicker_mode = NEVER_FLICKER;
1529 LOG("Flicker mode specified is invalid, using %d\n",
1530 flicker_mode);
1531 }
1532
1533 if (flicker_freq != FLICKER_50 && flicker_freq != FLICKER_60) {
1534 flicker_freq = FLICKER_60;
1535 LOG("Flicker mode specified is invalid, using %d\n",
1536 flicker_freq);
1537 }
1538
1539 if(video_nr < -1 || video_nr > 64) {
1540 video_nr = -1;
1541 LOG("invalid video_nr specified, must be -1 to 64\n");
1542 }
1543
1544 DBG("Using %d buffers, each %d bytes, alternate=%d\n",
1545 num_buffers, buffer_size, alternate);
1546}
1547
1548/************ Module Stuff ***************/
1549
1550
1551/******************************************************************************
1552 *
1553 * cpia2_init/module_init
1554 *
1555 *****************************************************************************/
1556static int __init cpia2_init(void)
1557{
1558 LOG("%s v%s\n",
1559 ABOUT, CPIA_VERSION);
1560 check_parameters();
1561 cpia2_usb_init();
1562 return 0;
1563}
1564
1565
1566/******************************************************************************
1567 *
1568 * cpia2_exit/module_exit
1569 *
1570 *****************************************************************************/
1571static void __exit cpia2_exit(void)
1572{
1573 cpia2_usb_cleanup();
1574 schedule_timeout(2 * HZ);
1575}
1576
1577module_init(cpia2_init);
1578module_exit(cpia2_exit);
diff --git a/drivers/media/video/cpia2/cpia2dev.h b/drivers/media/video/cpia2/cpia2dev.h
new file mode 100644
index 00000000000..f66691fe5a3
--- /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/videodev2.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_VIDIOC_PRIVATE + 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