1/*************************************************************************** 2 * V4L2 driver for SN9C1xx PC Camera Controllers * 3 * * 4 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * * 6 * This program is free software; you can redistribute it and/or modify * 7 * it under the terms of the GNU General Public License as published by * 8 * the Free Software Foundation; either version 2 of the License, or * 9 * (at your option) any later version. * 10 * * 11 * This program is distributed in the hope that it will be useful, * 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 * GNU General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU General Public License * 17 * along with this program; if not, write to the Free Software * 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 19 ***************************************************************************/ 20 21#ifndef _SN9C102_H_ 22#define _SN9C102_H_ 23 24#include <linux/usb.h> 25#include <linux/videodev2.h> 26#include <media/v4l2-common.h> 27#include <media/v4l2-ioctl.h> 28#include <linux/device.h> 29#include <linux/list.h> 30#include <linux/spinlock.h> 31#include <linux/time.h> 32#include <linux/wait.h> 33#include <linux/types.h> 34#include <linux/param.h> 35#include <linux/rwsem.h> 36#include <linux/mutex.h> 37#include <linux/string.h> 38#include <linux/stddef.h> 39#include <linux/kref.h> 40 41#include "sn9c102_config.h" 42#include "sn9c102_sensor.h" 43#include "sn9c102_devtable.h" 44 45 46enum sn9c102_frame_state { 47 F_UNUSED, 48 F_QUEUED, 49 F_GRABBING, 50 F_DONE, 51 F_ERROR, 52}; 53 54struct sn9c102_frame_t { 55 void* bufmem; 56 struct v4l2_buffer buf; 57 enum sn9c102_frame_state state; 58 struct list_head frame; 59 unsigned long vma_use_count; 60}; 61 62enum sn9c102_dev_state { 63 DEV_INITIALIZED = 0x01, 64 DEV_DISCONNECTED = 0x02, 65 DEV_MISCONFIGURED = 0x04, 66}; 67 68enum sn9c102_io_method { 69 IO_NONE, 70 IO_READ, 71 IO_MMAP, 72}; 73 74enum sn9c102_stream_state { 75 STREAM_OFF, 76 STREAM_INTERRUPT, 77 STREAM_ON, 78}; 79 80typedef char sn9c102_sof_header_t[62]; 81 82struct sn9c102_sof_t { 83 sn9c102_sof_header_t header; 84 u16 bytesread; 85}; 86 87struct sn9c102_sysfs_attr { 88 u16 reg, i2c_reg; 89 sn9c102_sof_header_t frame_header; 90}; 91 92struct sn9c102_module_param { 93 u8 force_munmap; 94 u16 frame_timeout; 95}; 96 97static DEFINE_MUTEX(sn9c102_sysfs_lock); 98static DECLARE_RWSEM(sn9c102_dev_lock); 99 100struct sn9c102_device { 101 struct video_device* v4ldev; 102 103 enum sn9c102_bridge bridge; 104 struct sn9c102_sensor sensor; 105 106 struct usb_device* usbdev; 107 struct urb* urb[SN9C102_URBS]; 108 void* transfer_buffer[SN9C102_URBS]; 109 u8* control_buffer; 110 111 struct sn9c102_frame_t *frame_current, frame[SN9C102_MAX_FRAMES]; 112 struct list_head inqueue, outqueue; 113 u32 frame_count, nbuffers, nreadbuffers; 114 115 enum sn9c102_io_method io; 116 enum sn9c102_stream_state stream; 117 118 struct v4l2_jpegcompression compression; 119 120 struct sn9c102_sysfs_attr sysfs; 121 struct sn9c102_sof_t sof; 122 u16 reg[384]; 123 124 struct sn9c102_module_param module_param; 125 126 struct kref kref; 127 enum sn9c102_dev_state state; 128 u8 users; 129 130 struct completion probe; 131 struct mutex open_mutex, fileop_mutex; 132 spinlock_t queue_lock; 133 wait_queue_head_t wait_open, wait_frame, wait_stream; 134}; 135 136/*****************************************************************************/ 137 138struct sn9c102_device* 139sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id) 140{ 141 return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL; 142} 143 144 145void 146sn9c102_attach_sensor(struct sn9c102_device* cam, 147 const struct sn9c102_sensor* sensor) 148{ 149 memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor)); 150} 151 152 153enum sn9c102_bridge 154sn9c102_get_bridge(struct sn9c102_device* cam) 155{ 156 return cam->bridge; 157} 158 159 160struct sn9c102_sensor* sn9c102_get_sensor(struct sn9c102_device* cam) 161{ 162 return &cam->sensor; 163} 164 165/*****************************************************************************/ 166 167#undef DBG 168#undef KDBG 169#ifdef SN9C102_DEBUG 170# define DBG(level, fmt, args...) \ 171do { \ 172 if (debug >= (level)) { \ 173 if ((level) == 1) \ 174 dev_err(&cam->usbdev->dev, fmt "\n", ## args); \ 175 else if ((level) == 2) \ 176 dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ 177 else if ((level) >= 3) \ 178 dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ 179 __func__, __LINE__ , ## args); \ 180 } \ 181} while (0) 182# define V4LDBG(level, name, cmd) \ 183do { \ 184 if (debug >= (level)) \ 185 v4l_print_ioctl(name, cmd); \ 186} while (0) 187# define KDBG(level, fmt, args...) \ 188do { \ 189 if (debug >= (level)) { \ 190 if ((level) == 1 || (level) == 2) \ 191 pr_info("sn9c102: " fmt "\n", ## args); \ 192 else if ((level) == 3) \ 193 pr_debug("sn9c102: [%s:%d] " fmt "\n", \ 194 __func__, __LINE__ , ## args); \ 195 } \ 196} while (0) 197#else 198# define DBG(level, fmt, args...) do {;} while(0) 199# define V4LDBG(level, name, cmd) do {;} while(0) 200# define KDBG(level, fmt, args...) do {;} while(0) 201#endif 202 203#undef PDBG 204#define PDBG(fmt, args...) \ 205dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \ 206 __LINE__ , ## args) 207 208#undef PDBGG 209#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ 210 211#endif /* _SN9C102_H_ */ 212