#include <linux/videodev.h>
#include <linux/usb.h>
#include <linux/i2c.h>
+#include <linux/device.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/wait.h>
#include <linux/config.h>
#include <linux/param.h>
+#include <linux/types.h>
+#include <linux/rwsem.h>
#include <asm/semaphore.h>
-#include <asm/types.h>
-#include "w9968cf_externaldef.h"
+#include <media/ovcamchip.h>
+
+#include "w9968cf_vpp.h"
/****************************************************************************
* Default values *
****************************************************************************/
+#define W9968CF_OVMOD_LOAD 1 /* automatic 'ovcamchip' module loading */
#define W9968CF_VPPMOD_LOAD 1 /* automatic 'w9968cf-vpp' module loading */
/* Comment/uncomment the following line to enable/disable debugging messages */
#define W9968CF_FORCE_RGB 0 /* read RGB instead of BGR, yes=1/no=0 */
-#define W9968CF_MAX_WIDTH 800 /* should be >= 640 */
-#define W9968CF_MAX_HEIGHT 600 /* should be >= 480 */
+#define W9968CF_MAX_WIDTH 800 /* Has effect if up-scaling is on */
+#define W9968CF_MAX_HEIGHT 600 /* Has effect if up-scaling is on */
#define W9968CF_WIDTH 320 /* from 128 to 352, multiple of 16 */
#define W9968CF_HEIGHT 240 /* from 96 to 288, multiple of 16 */
#define W9968CF_MODULE_NAME "V4L driver for W996[87]CF JPEG USB " \
"Dual Mode Camera Chip"
-#define W9968CF_MODULE_VERSION "v1.25-basic"
+#define W9968CF_MODULE_VERSION "1:1.32-basic"
#define W9968CF_MODULE_AUTHOR "(C) 2002-2004 Luca Risolia"
#define W9968CF_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
#define W9968CF_MODULE_LICENSE "GPL"
-static u8 w9968cf_vppmod_present; /* status flag: yes=1, no=0 */
-
static const struct usb_device_id winbond_id_table[] = {
{
/* Creative Labs Video Blaster WebCam Go Plus */
{ } /* terminating entry */
};
-MODULE_DEVICE_TABLE(usb, winbond_id_table);
-
/* W996[87]CF camera models, internal ids: */
enum w9968cf_model_id {
W9968CF_MOD_GENERIC = 1, /* Generic W996[87]CF based device */
W9968CF_MOD_CLVBWGP = 11,/*Creative Labs Video Blaster WebCam Go Plus*/
- W9968CF_MOD_ADPA5R = 21, /* Aroma Digi Pen ADG-5000 Refurbished */
- W9986CF_MOD_AU = 31, /* AVerTV USB */
- W9968CF_MOD_CLVBWG = 34, /* Creative Labs Video Blaster WebCam Go */
- W9968CF_MOD_DLLDK = 37, /* Die Lebon LDC-D35A Digital Kamera */
+ W9968CF_MOD_ADPVDMA = 21, /* Aroma Digi Pen VGA Dual Mode ADG-5000 */
+ W9986CF_MOD_AAU = 31, /* AVerMedia AVerTV USB */
+ W9968CF_MOD_CLVBWG = 34, /* Creative Labs Video Blaster WebCam Go */
+ W9968CF_MOD_LL = 37, /* Lebon LDC-035A */
W9968CF_MOD_EEEMC = 40, /* Ezonics EZ-802 EZMega Cam */
+ W9968CF_MOD_OOE = 42, /* OmniVision OV8610-EDE */
W9968CF_MOD_ODPVDMPC = 43,/* OPCOM Digi Pen VGA Dual Mode Pen Camera */
+ W9968CF_MOD_PDPII = 46, /* Pretec Digi Pen-II */
+ W9968CF_MOD_PDP480 = 49, /* Pretec DigiPen-480 */
};
enum w9968cf_frame_status {
};
struct w9968cf_frame_t {
- #define W9968CF_HW_BUF_SIZE 640*480*2 /* buf.size of original frames */
void* buffer;
+ unsigned long size;
u32 length;
+ int number;
enum w9968cf_frame_status status;
struct w9968cf_frame_t* next;
u8 queued;
VPP_UYVY_TO_RGBX = 0x08,
};
-static struct list_head w9968cf_dev_list; /* head of V4L registered cameras list */
-static LIST_HEAD(w9968cf_dev_list);
-struct semaphore w9968cf_devlist_sem; /* semaphore for list traversal */
+static struct w9968cf_vpp_t* w9968cf_vpp;
+static DECLARE_MUTEX(w9968cf_vppmod_lock);
+static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait);
+
+static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */
+static DECLARE_MUTEX(w9968cf_devlist_sem); /* semaphore for list traversal */
+
+static DECLARE_RWSEM(w9968cf_disconnect); /* prevent races with open() */
/* Main device driver structure */
struct w9968cf_device {
+ struct device dev; /* device structure */
+
enum w9968cf_model_id id; /* private device identifier */
struct video_device* v4ldev; /* -> V4L structure */
u16* data_buffer; /* -> data to send to the FSB */
struct w9968cf_frame_t frame[W9968CF_MAX_BUFFERS];
- struct w9968cf_frame_t frame_tmp; /* temporary frame */
+ struct w9968cf_frame_t frame_tmp; /* temporary frame */
+ struct w9968cf_frame_t frame_vpp; /* helper frame.*/
struct w9968cf_frame_t* frame_current; /* -> frame being grabbed */
struct w9968cf_frame_t* requested_frame[W9968CF_MAX_BUFFERS];
- void* vpp_buffer; /*-> helper buf.for video post-processing routines */
u8 max_buffers, /* number of requested buffers */
force_palette, /* yes=1/no=0 */
hs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */
vs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */
start_cropx, /* pixels from HS inactive edge to 1st cropped pixel*/
- start_cropy; /* pixels from VS incative edge to 1st cropped pixel*/
+ start_cropy; /* pixels from VS inactive edge to 1st cropped pixel*/
enum w9968cf_vpp_flag vpp_flag; /* post-processing routines in use */
u8 sensor_initialized; /* flag: yes=1, no=0 */
- /* Determined by CMOS sensor type: */
+ /* Determined by the image sensor type: */
int sensor, /* type of image sensor chip (CC_*) */
- monochrome; /* CMOS sensor is (probably) monochrome */
- u16 maxwidth, /* maximum width supported by the CMOS sensor */
- maxheight, /* maximum height supported by the CMOS sensor */
- minwidth, /* minimum width supported by the CMOS sensor */
- minheight; /* minimum height supported by the CMOS sensor */
+ monochrome; /* image sensor is (probably) monochrome */
+ u16 maxwidth, /* maximum width supported by the image sensor */
+ maxheight, /* maximum height supported by the image sensor */
+ minwidth, /* minimum width supported by the image sensor */
+ minheight; /* minimum height supported by the image sensor */
u8 auto_brt, /* auto brightness enabled flag */
auto_exp, /* auto exposure enabled flag */
backlight, /* backlight exposure algorithm flag */
fileop_sem; /* for read and ioctl */
spinlock_t urb_lock, /* for submit_urb() and unlink_urb() */
flist_lock; /* for requested frame list accesses */
- char command[16]; /* name of the program holding the device */
wait_queue_head_t open, wait_queue;
+
+ char command[16]; /* name of the program holding the device */
};
****************************************************************************/
#undef DBG
+#undef KDBG
#ifdef W9968CF_DEBUG
-# define DBG(level, fmt, args...) \
-{ \
-if ( ((specific_debug) && (debug == (level))) || \
- ((!specific_debug) && (debug >= (level))) ) { \
- if ((level) == 1) \
- err(fmt, ## args); \
- else if ((level) == 2 || (level) == 3) \
- info(fmt, ## args); \
- else if ((level) == 4) \
- warn(fmt, ## args); \
- else if ((level) >= 5) \
- info("[%s:%d] " fmt, \
- __PRETTY_FUNCTION__, __LINE__ , ## args); \
-} \
+/* For device specific debugging messages */
+# define DBG(level, fmt, args...) \
+{ \
+ if ( ((specific_debug) && (debug == (level))) || \
+ ((!specific_debug) && (debug >= (level))) ) { \
+ if ((level) == 1) \
+ dev_err(&cam->dev, fmt "\n", ## args); \
+ else if ((level) == 2 || (level) == 3) \
+ dev_info(&cam->dev, fmt "\n", ## args); \
+ else if ((level) == 4) \
+ dev_warn(&cam->dev, fmt "\n", ## args); \
+ else if ((level) >= 5) \
+ dev_info(&cam->dev, "[%s:%d] " fmt "\n", \
+ __FUNCTION__, __LINE__ , ## args); \
+ } \
+}
+/* For generic kernel (not device specific) messages */
+# define KDBG(level, fmt, args...) \
+{ \
+ if ( ((specific_debug) && (debug == (level))) || \
+ ((!specific_debug) && (debug >= (level))) ) { \
+ if ((level) >= 1 && (level) <= 4) \
+ pr_info("w9968cf: " fmt "\n", ## args); \
+ else if ((level) >= 5) \
+ pr_debug("w9968cf: [%s:%d] " fmt "\n", __FUNCTION__, \
+ __LINE__ , ## args); \
+ } \
}
#else
/* Not debugging: nothing */
# define DBG(level, fmt, args...) do {;} while(0);
+# define KDBG(level, fmt, args...) do {;} while(0);
#endif
#undef PDBG
+#define PDBG(fmt, args...) \
+dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args);
+
#undef PDBGG
-#define PDBG(fmt, args...) info("[%s:%d] "fmt, \
- __PRETTY_FUNCTION__, __LINE__ , ## args);
#define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */
#endif /* _W9968CF_H_ */