Add support for SXGA
[microdia.git] / sn9c20x.h
blob5d51953c877a9374d9f77084bd392e9113a4d3ec
1 /**
2 * @file sn9c20x.h
3 * @author Nicolas VIVIEN
4 * @date 2008-02-01
6 * @brief Driver for SN9C20X USB video cameras
8 * @note Copyright (C) Nicolas VIVIEN
10 * @par Licences
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <linux/kernel.h>
28 #include <linux/version.h>
29 #include <linux/usb.h>
30 #ifdef CONFIG_SN9C20X_EVDEV
31 #include <linux/input.h>
32 #endif
33 #include <media/v4l2-common.h>
35 #ifndef SN9C20X_H
36 #define SN9C20X_H
38 #define DRIVER_NAME "sn9c20x" /**< Name of this driver */
39 #define DRIVER_VERSION "v2009.04" /**< Version of this driver */
40 #define DRIVER_VERSION_NUM 0x200904 /**< Version numerical of this driver */
41 #define DRIVER_DESC "SN9C20x USB 2.0 Webcam Driver" /**< Short description of this driver */
42 #define DRIVER_AUTHOR "Nicolas VIVIEN and microdia project" \
43 " <microdia@googlegroups.com>" /**< Author of this driver */
44 #define PREFIX DRIVER_NAME ": " /**< Prefix use for the SN9C20X "printk" */
46 #define SN9C20X_USB_DEVICE(vend, prod, sensor, address) \
47 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
48 USB_DEVICE_ID_MATCH_INT_CLASS, \
49 .idVendor = (vend), \
50 .idProduct = (prod), \
51 .bInterfaceClass = 0xff, \
52 .driver_info = ((address << 8) | sensor)
54 /** V4L2-CONTROLS for compatibility with older kernels: */
55 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 25)
56 #define V4L2_CID_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0)
57 #define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_PRIVATE_BASE + 1)
58 #endif
60 #ifndef V4L2_PIX_FMT_SN9C20X_I420
61 #define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0')
62 #endif
64 /**
65 * @def MAX_URBS
66 * Number maximal of URBS
68 * @def ISO_FRAMES_PER_DESC
69 * Number frames per ISOC descriptor
71 #define MAX_URBS 10
72 #define ISO_FRAMES_PER_DESC 10
74 /**
75 * @def hb_multiplier(wMaxPacketSize)
76 * USB endpoint high bandwidth multiplier
78 * @def max_packet_sz(wMaxPacketSize)
79 * USB endpoint maximum packet size
81 * These values are both encoded within the wMaxPacketSize field of the usb_endpoint_descriptor structure.
82 * The 11(10:0) lowest bits hold the MaxPacketSize(according to the usb specs a value over 1024 is undefined),
83 * and the bits 12:11 will give the high bandwidth multiplier(this should be a value of 0-2).
86 #define hb_multiplier(wMaxPacketSize) (((wMaxPacketSize >> 11) & 0x03) + 1)
87 #define max_packet_sz(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
89 /**
90 * @def DRIVER_SUPPORT
92 * List of supported devices
94 #define DRIVER_SUPPORT "SN9C20X USB Camera"
96 #define SN9C20X_INFO (1 << 0)
97 #define SN9C20X_WARNING (1 << 1)
98 #define SN9C20X_ERROR (1 << 2)
99 #define SN9C20X_DEBUG (1 << 3)
100 #define SN9C20X_STREAM (1 << 4)
103 * @def UDIA_INFO(str, args...)
104 * Print information message.
105 * @a Use this function like the function printf.
107 * @def UDIA_ERROR(str, args...)
108 * Print error message.
109 * @a Use this function like the function printf.
111 * @def UDIA_WARNING(str, args...)
112 * Print warning message.
113 * @a Use this function like the function printf.
115 * @def UDIA_DEBUG(str, args...)
116 * Print debug message.
117 * @a Use this function like the function printf.
119 * @def UDIA_STREAM(str, args...)
120 * Print stream debug message.
121 * @a Use this function like the function printf.
123 extern __u8 log_level;
125 #define UDIA_INFO(str, args...) \
126 do { \
127 if (log_level & SN9C20X_INFO) \
128 printk(KERN_INFO PREFIX str, ##args); \
129 } while (0)
131 #define UDIA_WARNING(str, args...) \
132 do { \
133 if (log_level & SN9C20X_WARNING) \
134 printk(KERN_WARNING PREFIX str, ##args); \
135 } while (0)
137 #define UDIA_ERROR(str, args...) \
138 do { \
139 if (log_level & SN9C20X_ERROR) \
140 printk(KERN_ERR PREFIX str, ##args); \
141 } while (0)
143 #define UDIA_DEBUG(str, args...) \
144 do { \
145 if (log_level & SN9C20X_DEBUG) \
146 printk(KERN_DEBUG PREFIX str, ##args); \
147 } while (0)
149 #define UDIA_STREAM(str, args...) \
150 do { \
151 if (log_level & SN9C20X_STREAM) \
152 printk(KERN_DEBUG PREFIX str, ##args); \
153 } while (0)
156 enum sn9c20x_buffer_state {
157 SN9C20X_BUF_STATE_IDLE = 0,
158 SN9C20X_BUF_STATE_QUEUED = 1,
159 SN9C20X_BUF_STATE_ACTIVE = 2,
160 SN9C20X_BUF_STATE_DONE = 3,
161 SN9C20X_BUF_STATE_ERROR = 4,
164 enum sn9c20x_mode {
165 SN9C20X_MODE_IDLE = 0,
166 SN9C20X_MODE_READ = 1,
167 SN9C20X_MODE_STREAM = 2,
170 struct sn9c20x_buffer {
171 unsigned long vma_use_count;
172 struct list_head stream;
174 /* Touched by interrupt handler. */
175 struct v4l2_buffer buf;
176 struct list_head queue;
177 wait_queue_head_t wait;
178 enum sn9c20x_buffer_state state;
181 #define SN9C20X_QUEUE_STREAMING (1 << 0)
182 #define SN9C20X_QUEUE_DISCONNECTED (1 << 1)
183 #define SN9C20X_QUEUE_DROP_INCOMPLETE (1 << 2)
185 struct sn9c20x_video_queue {
186 void *mem;
187 unsigned int flags;
188 __u32 sequence;
190 unsigned int count;
191 unsigned int min_buffers;
192 unsigned int max_buffers;
193 unsigned int buf_size;
195 struct sn9c20x_buffer *buffer;
196 struct sn9c20x_buffer *read_buffer;
197 struct mutex mutex; /* protects buffers and mainqueue */
198 spinlock_t irqlock; /* protects irqqueue */
200 struct list_head mainqueue;
201 struct list_head irqqueue;
205 * @struct sn9c20x_urb
207 struct sn9c20x_urb {
208 void *data;
209 struct urb *urb;
213 * @struct sn9c20x_video
215 struct sn9c20x_video {
216 struct v4l2_pix_format format;
217 __u8 cmatrix[21];
219 int fps; /**< FPS setting */
220 int brightness; /**< Brightness setting */
221 int contrast; /**< Contrast setting */
222 int gamma; /**< Gamma setting */
223 int colour; /**< Colour setting */
224 int hue; /**< Hue setting */
225 int hflip; /**< Horizontal flip */
226 int vflip; /**< Vertical flip */
227 int exposure; /**< Exposure */
228 int gain; /**< Gain */
229 int sharpness; /**< Sharpness */
230 int red_gain; /**< Red Gain Control */
231 int blue_gain; /**< Blue Gain Control */
232 int auto_exposure; /**< Automatic exposure */
233 int auto_gain; /**< Automatic gain */
234 int auto_whitebalance; /**< Automatic whitebalance */
238 * @struct sn9c20x_debugfs
240 struct sn9c20x_debugfs {
241 struct dentry *dent_device;
242 struct dentry *dent_bridge_addr;
243 struct dentry *dent_bridge_val;
244 struct dentry *dent_bridge_dump;
245 struct dentry *dent_sensor_addr;
246 struct dentry *dent_sensor_val8;
247 struct dentry *dent_sensor_val16;
248 struct dentry *dent_sensor_val32;
250 __u16 bridge_addr; /**< Current bridge register address */
251 __u8 sensor_addr; /**< Current sensor register address */
254 enum sn9c20x_endpoints {
255 SN9C20X_VID_ISOC = 1,
256 SN9C20X_BULK = 2,
257 SN9C20X_INT = 3,
258 SN9C20X_AUD_ISOC = 4
261 enum sn9c20x_sensors {
262 PROBE_SENSOR = 0,
263 OV9650_SENSOR = 1,
264 OV9655_SENSOR = 2,
265 SOI968_SENSOR = 3,
266 OV7660_SENSOR = 4,
267 OV7670_SENSOR = 5,
268 MT9M111_SENSOR = 6,
269 MT9V111_SENSOR = 7,
270 MT9V011_SENSOR = 8,
271 MT9M001_SENSOR = 9,
272 HV7131R_SENSOR = 10,
273 MT9V112_SENSOR = 11,
278 struct usb_sn9c20x;
280 struct sn9c20x_video_mode {
281 __u16 width;
282 __u16 height;
283 __u8 scale;
284 __u16 window[4];
287 struct sn9c20x_video_format {
288 __u32 pix_fmt;
289 char desc[32];
290 __u8 depth;
291 void (*set_format) (struct usb_sn9c20x *dev);
294 struct sn9c20x_i2c_regs {
295 __u8 address;
296 __u16 value;
299 #define SN9C20X_N_FMTS 3
300 #define SN9C20X_N_MODES 7
302 extern struct sn9c20x_video_format sn9c20x_fmts[SN9C20X_N_FMTS];
303 extern struct sn9c20x_video_mode sn9c20x_modes[SN9C20X_N_MODES];
305 struct sn9c20x_camera {
307 /* Sensor ID */
308 __u8 sensor;
310 /* SCCB/I2C interface */
311 __u8 i2c_flags;
312 __u8 address;
314 int min_yavg, max_yavg, old_step, older_step;
315 unsigned int exposure_step;
317 atomic_t yavg;
319 int vstart;
320 int hstart;
322 int (*flip_detect) (struct usb_sn9c20x *dev);
323 int (*set_hvflip) (struct usb_sn9c20x *dev);
324 void (*set_sxga_mode) (struct usb_sn9c20x *dev, bool sxga);
325 /* image quality functions */
326 int (*set_exposure) (struct usb_sn9c20x *dev);
327 int (*set_gain) (struct usb_sn9c20x *dev);
328 int (*set_auto_exposure) (struct usb_sn9c20x *dev);
329 int (*set_auto_gain) (struct usb_sn9c20x *dev);
330 int (*set_auto_whitebalance) (struct usb_sn9c20x *dev);
331 int (*set_contrast) (struct usb_sn9c20x *dev);
332 int (*set_brightness) (struct usb_sn9c20x *dev);
333 int (*set_gamma) (struct usb_sn9c20x *dev);
334 int (*set_saturation) (struct usb_sn9c20x *dev);
335 int (*set_sharpness) (struct usb_sn9c20x *dev);
336 int (*set_red_gain) (struct usb_sn9c20x *dev);
337 int (*set_blue_gain) (struct usb_sn9c20x *dev);
338 int (*set_hue) (struct usb_sn9c20x *dev);
342 * @struct usb_sn9c20x
344 struct usb_sn9c20x {
345 #ifdef CONFIG_SN9C20X_EVDEV
346 struct input_dev *input_dev;
347 __u8 input_gpio;
348 struct task_struct *input_task;
349 #endif
350 struct video_device *vdev; /**< Pointer on a V4L2 video device */
351 struct usb_device *udev; /**< Pointer on a USB device */
352 struct usb_interface *interface;/**< Pointer on a USB interface */
354 int release; /**< Release of the device (bcdDevice) */
356 struct sn9c20x_video vsettings; /**< Video settings (brightness, whiteness...) */
357 struct sn9c20x_debugfs debug; /**< debugfs information structure */
359 struct kref vopen; /**< Video status (Opened or Closed) */
360 struct file *owner; /**< file handler of stream owner */
361 enum sn9c20x_mode mode; /**< camera mode */
363 int vframes_overflow; /**< Buffer overflow frames */
364 int vframes_incomplete; /**< Incomplete frames */
365 int vframes_dropped; /**< Dropped frames */
367 struct sn9c20x_urb urbs[MAX_URBS];
369 __u8 jpeg;
371 unsigned int frozen:1;
372 struct sn9c20x_video_queue queue;
373 struct sn9c20x_camera camera;
377 * @def SN9C20X_PERCENT
378 * Calculate a value from a percent
380 #define SN9C20X_PERCENT(x, y) (((int)x * (int)y) / 100)
383 extern struct mutex open_lock;
384 extern __u8 jpeg;
386 int usb_sn9c20x_control_write(struct usb_sn9c20x *, __u16, __u8 *, __u16);
387 int usb_sn9c20x_control_read(struct usb_sn9c20x *, __u16, __u8 *, __u16);
389 int usb_sn9c20x_isoc_init(struct usb_sn9c20x *,
390 struct usb_endpoint_descriptor *);
391 void usb_sn9c20x_completion_handler(struct urb *);
392 int usb_sn9c20x_init_urbs(struct usb_sn9c20x *);
393 void usb_sn9c20x_uninit_urbs(struct usb_sn9c20x *, int);
394 void usb_sn9c20x_delete(struct kref *);
396 int sn9c20x_initialize(struct usb_sn9c20x *dev);
397 int sn9c20x_initialize_sensor(struct usb_sn9c20x *dev);
398 int sn9c20x_enable_video(struct usb_sn9c20x *dev, int enable);
400 int dev_sn9c20x_call_constantly(struct usb_sn9c20x *dev);
401 int dev_sn9c20x_flip_detection(struct usb_sn9c20x *dev);
402 int dev_sn9c20x_camera_set_exposure(struct usb_sn9c20x *);
403 int dev_sn9c20x_camera_set_gain(struct usb_sn9c20x *);
404 int dev_sn9c20x_camera_set_hvflip(struct usb_sn9c20x *);
405 int dev_sn9c20x_camera_set_auto_exposure(struct usb_sn9c20x *dev);
406 int dev_sn9c20x_camera_set_auto_gain(struct usb_sn9c20x *dev);
407 int dev_sn9c20x_camera_set_auto_whitebalance(struct usb_sn9c20x *dev);
408 int dev_sn9c20x_perform_soft_ae(struct usb_sn9c20x *dev);
410 void v4l2_set_control_default(struct usb_sn9c20x *, __u32, __u16);
411 int v4l_sn9c20x_select_video_mode(struct usb_sn9c20x *, int);
412 int v4l_sn9c20x_register_video_device(struct usb_sn9c20x *);
413 int v4l_sn9c20x_unregister_video_device(struct usb_sn9c20x *);
415 int sn9c20x_create_sysfs_files(struct video_device *);
416 void sn9c20x_remove_sysfs_files(struct video_device *);
418 #ifdef CONFIG_SN9C20X_DEBUGFS
419 void sn9c20x_init_debugfs(void);
420 void sn9c20x_uninit_debugfs(void);
421 int sn9c20x_create_debugfs_files(struct usb_sn9c20x *);
422 int sn9c20x_remove_debugfs_files(struct usb_sn9c20x *);
423 #else
424 static inline void sn9c20x_init_debugfs(void) {}
425 static inline void sn9c20x_uninit_debugfs(void) {}
426 static inline int sn9c20x_create_debugfs_files(struct usb_sn9c20x *dev)
428 return 0;
430 static inline int sn9c20x_remove_debugfs_files(struct usb_sn9c20x *dev)
432 return 0;
434 #endif
436 void sn9c20x_queue_init(struct sn9c20x_video_queue *);
437 int sn9c20x_alloc_buffers(struct sn9c20x_video_queue *,
438 unsigned int, unsigned int);
439 int sn9c20x_free_buffers(struct sn9c20x_video_queue *);
440 int sn9c20x_queue_enable(struct sn9c20x_video_queue *, int);
441 void sn9c20x_queue_cancel(struct sn9c20x_video_queue *, int);
442 unsigned int sn9c20x_queue_poll(struct sn9c20x_video_queue *,
443 struct file *, poll_table *);
444 int sn9c20x_query_buffer(struct sn9c20x_video_queue *, struct v4l2_buffer *);
445 int sn9c20x_queue_buffer(struct sn9c20x_video_queue *, struct v4l2_buffer *);
446 int sn9c20x_dequeue_buffer(struct sn9c20x_video_queue *,
447 struct v4l2_buffer *, int);
448 struct sn9c20x_buffer *sn9c20x_queue_next_buffer(
449 struct sn9c20x_video_queue *, struct sn9c20x_buffer *);
451 static inline int sn9c20x_queue_streaming(struct sn9c20x_video_queue *queue)
453 return queue->flags & SN9C20X_QUEUE_STREAMING;
456 /* sensor hv7131r has no header-file of its own: */
457 extern struct sn9c20x_i2c_regs hv7131r_init[];
458 int hv7131r_initialize(struct usb_sn9c20x *dev);
459 int hv7131r_set_exposure(struct usb_sn9c20x *dev);
460 int hv7131r_set_gain(struct usb_sn9c20x *dev);
461 int hv7131r_set_hvflip(struct usb_sn9c20x *dev);
463 #endif