/*
* Driver for Logitech Quickcam Messenger usb video camera
* Copyright (C) Jaya Kumar
*
* This work was sponsored by CIS(M) Sdn Bhd.
* History:
* 05/08/2006 - Jaya Kumar
* I wrote this based on the konicawc by Simon Evans.
* -
* Full credit for reverse engineering and creating an initial
* working linux driver for the VV6422 goes to the qce-ga project by
* Tuukka Toivonen, Jochen Hoenicke, Peter McConnell,
* Cristiano De Michele, Georg Acher, Jean-Frederic Clere as well as
* others.
* ---
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/usb/input.h>
#include "usbvideo.h"
#include "quickcam_messenger.h"
/*
* Version Information
*/
#ifdef CONFIG_USB_DEBUG
static int debug;
#define DEBUG(n, format, arg...) \
if (n <= debug) { \
printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \
}
#else
#define DEBUG(n, arg...)
static const int debug;
#endif
#define DRIVER_VERSION "v0.01"
#define DRIVER_DESC "Logitech Quickcam Messenger USB"
#define USB_LOGITECH_VENDOR_ID 0x046D
#define USB_QCM_PRODUCT_ID 0x08F0
#define MAX_CAMERAS 1
#define MAX_COLOUR 32768
#define MAX_HUE 32768
#define MAX_BRIGHTNESS 32768
#define MAX_CONTRAST 32768
#define MAX_WHITENESS 32768
static int size = SIZE_320X240;
static int colour = MAX_COLOUR;
static int hue = MAX_HUE;
static int brightness = MAX_BRIGHTNESS;
static int contrast = MAX_CONTRAST;
static int whiteness = MAX_WHITENESS;
static struct usbvideo *cams;
static struct usb_device_id qcm_table [] = {
{ USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) },
{ }
};
MODULE_DEVICE_TABLE(usb, qcm_table);
#ifdef CONFIG_INPUT
static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
{
struct input_dev *input_dev;
int error;
usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
cam->input = input_dev = input_allocate_device();
if (!input_dev) {
warn("insufficient mem for cam input device");
return;
}
input_dev->name = "QCM button";
input_dev->phys = cam->input_physname;
usb_to_input_id(dev, &input_dev->id);
input_dev->dev.parent = &dev->dev;
input_dev->evbit[0] = BIT_MASK(EV_KEY);
input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
error = input_register_device(cam->input);
if (error) {
warn("Failed to register camera's input device, err: %d\n",
error);
input_free_device(cam->input);
cam->input = NULL;
}
}
static void qcm_unregister_input(struct qcm *cam)
{
if (cam->input) {
input_unregister_device(cam->input);
cam->input = NULL;
}
}
static void qcm_report_buttonstat(struct qcm *cam)
{
if (cam->input) {
input_report_key(cam->input, BTN_0, cam->button_sts);
input_sync(cam->input);
}
}
static void qcm_int_irq(struct urb *urb)
{
int ret;
struct uvd *uvd = urb->context;
struct qcm *cam;
if (!CAMERA_IS_OPERATIONAL(uvd))
return;
if (!uvd->streaming)
return;
uvd->stats.urb_count++;
if (urb->status < 0)
uvd->stats.iso_err_count++;
else {
if