diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-14 00:13:22 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-15 16:25:07 -0300 |
commit | 0c0d06cac63ee327ceaab4b5ffe2206574ab86bd (patch) | |
tree | e759f0dc3185d97f2a0c6b5cd5e32ea6faa74d40 /drivers/media/video/gspca/mr97310a.c | |
parent | 84cfe9e79bd5ac11c963f4841158454fefa872f6 (diff) |
[media] rename most media/video usb drivers to media/usb
Rename all USB drivers with their own directory under
drivers/media/video into drivers/media/usb and update the
building system.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/mr97310a.c')
-rw-r--r-- | drivers/media/video/gspca/mr97310a.c | 1091 |
1 files changed, 0 insertions, 1091 deletions
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c deleted file mode 100644 index 8f4714df599..00000000000 --- a/drivers/media/video/gspca/mr97310a.c +++ /dev/null @@ -1,1091 +0,0 @@ -/* - * Mars MR97310A library - * - * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is - * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com> - * - * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+ - * and for the routines for detecting and classifying these various cameras, - * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> - * - * Support for the control settings for the CIF cameras is - * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> and - * Thomas Kaiser <thomas@kaiser-linux.li> - * - * Support for the control settings for the VGA cameras is - * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> - * - * Several previously unsupported cameras are owned and have been tested by - * Hans de Goede <hdegoede@redhat.com> and - * Thomas Kaiser <thomas@kaiser-linux.li> and - * Theodore Kilgore <kilgota@auburn.edu> and - * Edmond Rodriguez <erodrig_97@yahoo.com> and - * Aurelien Jacobs <aurel@gnuage.org> - * - * The MR97311A support in gspca/mars.c has been helpful in understanding some - * of the registers in these cameras. - * - * 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 - * 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 - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "mr97310a" - -#include "gspca.h" - -#define CAM_TYPE_CIF 0 -#define CAM_TYPE_VGA 1 - -#define MR97310A_BRIGHTNESS_DEFAULT 0 - -#define MR97310A_EXPOSURE_MIN 0 -#define MR97310A_EXPOSURE_MAX 4095 -#define MR97310A_EXPOSURE_DEFAULT 1000 - -#define MR97310A_GAIN_MIN 0 -#define MR97310A_GAIN_MAX 31 -#define MR97310A_GAIN_DEFAULT 25 - -#define MR97310A_CONTRAST_MIN 0 -#define MR97310A_CONTRAST_MAX 31 -#define MR97310A_CONTRAST_DEFAULT 23 - -#define MR97310A_CS_GAIN_MIN 0 -#define MR97310A_CS_GAIN_MAX 0x7ff -#define MR97310A_CS_GAIN_DEFAULT 0x110 - -#define MR97310A_CID_CLOCKDIV (V4L2_CTRL_CLASS_USER + 0x1000) -#define MR97310A_MIN_CLOCKDIV_MIN 3 -#define MR97310A_MIN_CLOCKDIV_MAX 8 -#define MR97310A_MIN_CLOCKDIV_DEFAULT 3 - -MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>," - "Theodore Kilgore <kilgota@auburn.edu>"); -MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* global parameters */ -static int force_sensor_type = -1; -module_param(force_sensor_type, int, 0644); -MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct { /* exposure/min_clockdiv control cluster */ - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *min_clockdiv; - }; - u8 sof_read; - u8 cam_type; /* 0 is CIF and 1 is VGA */ - u8 sensor_type; /* We use 0 and 1 here, too. */ - u8 do_lcd_stop; - u8 adj_colors; -}; - -struct sensor_w_data { - u8 reg; - u8 flags; - u8 data[16]; - int len; -}; - -static void sd_stopN(struct gspca_dev *gspca_dev); - -static const struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 4}, - {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3}, - {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -/* the bytes to write are in gspca_dev->usb_buf */ -static int mr_write(struct gspca_dev *gspca_dev, int len) -{ - int rc; - - rc = usb_bulk_msg(gspca_dev->dev, - usb_sndbulkpipe(gspca_dev->dev, 4), - gspca_dev->usb_buf, len, NULL, 500); - if (rc < 0) - pr_err("reg write [%02x] error %d\n", - gspca_dev->usb_buf[0], rc); - return rc; -} - -/* the bytes are read into gspca_dev->usb_buf */ -static int mr_read(struct gspca_dev *gspca_dev, int len) -{ - int rc; - - rc = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 3), - gspca_dev->usb_buf, len, NULL, 500); - if (rc < 0) - pr_err("reg read [%02x] error %d\n", - gspca_dev->usb_buf[0], rc); - return rc; -} - -static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags, - const u8 *data, int len) -{ - gspca_dev->usb_buf[0] = 0x1f; - gspca_dev->usb_buf[1] = flags; - gspca_dev->usb_buf[2] = reg; - memcpy(gspca_dev->usb_buf + 3, data, len); - - return mr_write(gspca_dev, len + 3); -} - -static int sensor_write_regs(struct gspca_dev *gspca_dev, - const struct sensor_w_data *data, int len) -{ - int i, rc; - - for (i = 0; i < len; i++) { - rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags, - data[i].data, data[i].len); - if (rc < 0) - return rc; - } - - return 0; -} - -static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 buf, confirm_reg; - int rc; - - buf = data; - if (sd->cam_type == CAM_TYPE_CIF) { - rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1); - confirm_reg = sd->sensor_type ? 0x13 : 0x11; - } else { - rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1); - confirm_reg = 0x11; - } - if (rc < 0) - return rc; - - buf = 0x01; - rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1); - if (rc < 0) - return rc; - - return 0; -} - -static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose) -{ - int err_code; - - gspca_dev->usb_buf[0] = reg; - err_code = mr_write(gspca_dev, 1); - if (err_code < 0) - return err_code; - - err_code = mr_read(gspca_dev, 16); - if (err_code < 0) - return err_code; - - if (verbose) - PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg, - gspca_dev->usb_buf[0], - gspca_dev->usb_buf[1], - gspca_dev->usb_buf[2]); - - return 0; -} - -static int zero_the_pointer(struct gspca_dev *gspca_dev) -{ - __u8 *data = gspca_dev->usb_buf; - int err_code; - u8 status = 0; - int tries = 0; - - err_code = cam_get_response16(gspca_dev, 0x21, 0); - if (err_code < 0) - return err_code; - - data[0] = 0x19; - data[1] = 0x51; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - err_code = cam_get_response16(gspca_dev, 0x21, 0); - if (err_code < 0) - return err_code; - - data[0] = 0x19; - data[1] = 0xba; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - err_code = cam_get_response16(gspca_dev, 0x21, 0); - if (err_code < 0) - return err_code; - - data[0] = 0x19; - data[1] = 0x00; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - err_code = cam_get_response16(gspca_dev, 0x21, 0); - if (err_code < 0) - return err_code; - - data[0] = 0x19; - data[1] = 0x00; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - while (status != 0x0a && tries < 256) { - err_code = cam_get_response16(gspca_dev, 0x21, 0); - status = data[0]; - tries++; - if (err_code < 0) - return err_code; - } - if (status != 0x0a) - PDEBUG(D_ERR, "status is %02x", status); - - tries = 0; - while (tries < 4) { - data[0] = 0x19; - data[1] = 0x00; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - err_code = cam_get_response16(gspca_dev, 0x21, 0); - status = data[0]; - tries++; - if (err_code < 0) - return err_code; - } - - data[0] = 0x19; - err_code = mr_write(gspca_dev, 1); - if (err_code < 0) - return err_code; - - err_code = mr_read(gspca_dev, 16); - if (err_code < 0) - return err_code; - - return 0; -} - -static int stream_start(struct gspca_dev *gspca_dev) -{ - gspca_dev->usb_buf[0] = 0x01; - gspca_dev->usb_buf[1] = 0x01; - return mr_write(gspca_dev, 2); -} - -static void stream_stop(struct gspca_dev *gspca_dev) -{ - gspca_dev->usb_buf[0] = 0x01; - gspca_dev->usb_buf[1] = 0x00; - if (mr_write(gspca_dev, 2) < 0) - PDEBUG(D_ERR, "Stream Stop failed"); -} - -static void lcd_stop(struct gspca_dev *gspca_dev) -{ - gspca_dev->usb_buf[0] = 0x19; - gspca_dev->usb_buf[1] = 0x54; - if (mr_write(gspca_dev, 2) < 0) - PDEBUG(D_ERR, "LCD Stop failed"); -} - -static int isoc_enable(struct gspca_dev *gspca_dev) -{ - gspca_dev->usb_buf[0] = 0x00; - gspca_dev->usb_buf[1] = 0x4d; /* ISOC transferring enable... */ - return mr_write(gspca_dev, 2); -} - -/* This function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - int err_code; - - cam = &gspca_dev->cam; - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - sd->do_lcd_stop = 0; - - /* Several of the supported CIF cameras share the same USB ID but - * require different initializations and different control settings. - * The same is true of the VGA cameras. Therefore, we are forced - * to start the initialization process in order to determine which - * camera is present. Some of the supported cameras require the - * memory pointer to be set to 0 as the very first item of business - * or else they will not stream. So we do that immediately. - */ - err_code = zero_the_pointer(gspca_dev); - if (err_code < 0) - return err_code; - - err_code = stream_start(gspca_dev); - if (err_code < 0) - return err_code; - - /* Now, the query for sensor type. */ - err_code = cam_get_response16(gspca_dev, 0x07, 1); - if (err_code < 0) - return err_code; - - if (id->idProduct == 0x0110 || id->idProduct == 0x010e) { - sd->cam_type = CAM_TYPE_CIF; - cam->nmodes--; - /* - * All but one of the known CIF cameras share the same USB ID, - * but two different init routines are in use, and the control - * settings are different, too. We need to detect which camera - * of the two known varieties is connected! - * - * A list of known CIF cameras follows. They all report either - * 0200 for type 0 or 0300 for type 1. - * If you have another to report, please do - * - * Name sd->sensor_type reported by - * - * Sakar 56379 Spy-shot 0 T. Kilgore - * Innovage 0 T. Kilgore - * Vivitar Mini 0 H. De Goede - * Vivitar Mini 0 E. Rodriguez - * Vivitar Mini 1 T. Kilgore - * Elta-Media 8212dc 1 T. Kaiser - * Philips dig. keych. 1 T. Kilgore - * Trust Spyc@m 100 1 A. Jacobs - */ - switch (gspca_dev->usb_buf[0]) { - case 2: - sd->sensor_type = 0; - break; - case 3: - sd->sensor_type = 1; - break; - default: - pr_err("Unknown CIF Sensor id : %02x\n", - gspca_dev->usb_buf[1]); - return -ENODEV; - } - PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d", - sd->sensor_type); - } else { - sd->cam_type = CAM_TYPE_VGA; - - /* - * Here is a table of the responses to the query for sensor - * type, from the known MR97310A VGA cameras. Six different - * cameras of which five share the same USB ID. - * - * Name gspca_dev->usb_buf[] sd->sensor_type - * sd->do_lcd_stop - * Aiptek Pencam VGA+ 0300 0 1 - * ION digital 0300 0 1 - * Argus DC-1620 0450 1 0 - * Argus QuickClix 0420 1 1 - * Sakar 77379 Digital 0350 0 1 - * Sakar 1638x CyberPix 0120 0 2 - * - * Based upon these results, we assume default settings - * and then correct as necessary, as follows. - * - */ - - sd->sensor_type = 1; - sd->do_lcd_stop = 0; - sd->adj_colors = 0; - if (gspca_dev->usb_buf[0] == 0x01) { - sd->sensor_type = 2; - } else if ((gspca_dev->usb_buf[0] != 0x03) && - (gspca_dev->usb_buf[0] != 0x04)) { - pr_err("Unknown VGA Sensor id Byte 0: %02x\n", - gspca_dev->usb_buf[0]); - pr_err("Defaults assumed, may not work\n"); - pr_err("Please report this\n"); - } - /* Sakar Digital color needs to be adjusted. */ - if ((gspca_dev->usb_buf[0] == 0x03) && - (gspca_dev->usb_buf[1] == 0x50)) - sd->adj_colors = 1; - if (gspca_dev->usb_buf[0] == 0x04) { - sd->do_lcd_stop = 1; - switch (gspca_dev->usb_buf[1]) { - case 0x50: - sd->sensor_type = 0; - PDEBUG(D_PROBE, "sensor_type corrected to 0"); - break; - case 0x20: - /* Nothing to do here. */ - break; - default: - pr_err("Unknown VGA Sensor id Byte 1: %02x\n", - gspca_dev->usb_buf[1]); - pr_err("Defaults assumed, may not work\n"); - pr_err("Please report this\n"); - } - } - PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d", - sd->sensor_type); - } - /* Stop streaming as we've started it only to probe the sensor type. */ - sd_stopN(gspca_dev); - - if (force_sensor_type != -1) { - sd->sensor_type = !!force_sensor_type; - PDEBUG(D_PROBE, "Forcing sensor type to: %d", - sd->sensor_type); - } - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - return 0; -} - -static int start_cif_cam(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 *data = gspca_dev->usb_buf; - int err_code; - static const __u8 startup_string[] = { - 0x00, - 0x0d, - 0x01, - 0x00, /* Hsize/8 for 352 or 320 */ - 0x00, /* Vsize/4 for 288 or 240 */ - 0x13, /* or 0xbb, depends on sensor */ - 0x00, /* Hstart, depends on res. */ - 0x00, /* reserved ? */ - 0x00, /* Vstart, depends on res. and sensor */ - 0x50, /* 0x54 to get 176 or 160 */ - 0xc0 - }; - - /* Note: Some of the above descriptions guessed from MR97113A driver */ - - memcpy(data, startup_string, 11); - if (sd->sensor_type) - data[5] = 0xbb; - - switch (gspca_dev->width) { - case 160: - data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */ - /* fall thru */ - case 320: - default: - data[3] = 0x28; /* reg 2, H size/8 */ - data[4] = 0x3c; /* reg 3, V size/4 */ - data[6] = 0x14; /* reg 5, H start */ - data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */ - break; - case 176: - data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */ - /* fall thru */ - case 352: - data[3] = 0x2c; /* reg 2, H size/8 */ - data[4] = 0x48; /* reg 3, V size/4 */ - data[6] = 0x06; /* reg 5, H start */ - data[8] = 0x06 - sd->sensor_type; /* reg 7, V start */ - break; - } - err_code = mr_write(gspca_dev, 11); - if (err_code < 0) - return err_code; - - if (!sd->sensor_type) { - static const struct sensor_w_data cif_sensor0_init_data[] = { - {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01, - 0x0f, 0x14, 0x0f, 0x10}, 8}, - {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5}, - {0x12, 0x00, {0x07}, 1}, - {0x1f, 0x00, {0x06}, 1}, - {0x27, 0x00, {0x04}, 1}, - {0x29, 0x00, {0x0c}, 1}, - {0x40, 0x00, {0x40, 0x00, 0x04}, 3}, - {0x50, 0x00, {0x60}, 1}, - {0x60, 0x00, {0x06}, 1}, - {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6}, - {0x72, 0x00, {0x1e, 0x56}, 2}, - {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02, - 0x31, 0x80, 0x00}, 9}, - {0x11, 0x00, {0x01}, 1}, - {0, 0, {0}, 0} - }; - err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data, - ARRAY_SIZE(cif_sensor0_init_data)); - } else { /* sd->sensor_type = 1 */ - static const struct sensor_w_data cif_sensor1_init_data[] = { - /* Reg 3,4, 7,8 get set by the controls */ - {0x02, 0x00, {0x10}, 1}, - {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */ - {0x06, 0x01, {0x00}, 1}, - {0x09, 0x02, {0x0e}, 1}, - {0x0a, 0x02, {0x05}, 1}, - {0x0b, 0x02, {0x05}, 1}, - {0x0c, 0x02, {0x0f}, 1}, - {0x0d, 0x02, {0x07}, 1}, - {0x0e, 0x02, {0x0c}, 1}, - {0x0f, 0x00, {0x00}, 1}, - {0x10, 0x00, {0x06}, 1}, - {0x11, 0x00, {0x07}, 1}, - {0x12, 0x00, {0x00}, 1}, - {0x13, 0x00, {0x01}, 1}, - {0, 0, {0}, 0} - }; - /* Without this command the cam won't work with USB-UHCI */ - gspca_dev->usb_buf[0] = 0x0a; - gspca_dev->usb_buf[1] = 0x00; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, - ARRAY_SIZE(cif_sensor1_init_data)); - } - return err_code; -} - -static int start_vga_cam(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 *data = gspca_dev->usb_buf; - int err_code; - static const __u8 startup_string[] = - {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00, - 0x00, 0x50, 0xc0}; - /* What some of these mean is explained in start_cif_cam(), above */ - - memcpy(data, startup_string, 11); - if (!sd->sensor_type) { - data[5] = 0x00; - data[10] = 0x91; - } - if (sd->sensor_type == 2) { - data[5] = 0x00; - data[10] = 0x18; - } - - switch (gspca_dev->width) { - case 160: - data[9] |= 0x0c; /* reg 8, 4:1 scale down */ - /* fall thru */ - case 320: - data[9] |= 0x04; /* reg 8, 2:1 scale down */ - /* fall thru */ - case 640: - default: - data[3] = 0x50; /* reg 2, H size/8 */ - data[4] = 0x78; /* reg 3, V size/4 */ - data[6] = 0x04; /* reg 5, H start */ - data[8] = 0x03; /* reg 7, V start */ - if (sd->sensor_type == 2) { - data[6] = 2; - data[8] = 1; - } - if (sd->do_lcd_stop) - data[8] = 0x04; /* Bayer tile shifted */ - break; - - case 176: - data[9] |= 0x04; /* reg 8, 2:1 scale down */ - /* fall thru */ - case 352: - data[3] = 0x2c; /* reg 2, H size */ - data[4] = 0x48; /* reg 3, V size */ - data[6] = 0x94; /* reg 5, H start */ - data[8] = 0x63; /* reg 7, V start */ - if (sd->do_lcd_stop) - data[8] = 0x64; /* Bayer tile shifted */ - break; - } - - err_code = mr_write(gspca_dev, 11); - if (err_code < 0) - return err_code; - - if (!sd->sensor_type) { - static const struct sensor_w_data vga_sensor0_init_data[] = { - {0x01, 0x00, {0x0c, 0x00, 0x04}, 3}, - {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4}, - {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4}, - {0x25, 0x00, {0x03, 0xa9, 0x80}, 3}, - {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4}, - {0, 0, {0}, 0} - }; - err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, - ARRAY_SIZE(vga_sensor0_init_data)); - } else if (sd->sensor_type == 1) { - static const struct sensor_w_data color_adj[] = { - {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, - /* adjusted blue, green, red gain correct - too much blue from the Sakar Digital */ - 0x05, 0x01, 0x04}, 8} - }; - - static const struct sensor_w_data color_no_adj[] = { - {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, - /* default blue, green, red gain settings */ - 0x07, 0x00, 0x01}, 8} - }; - - static const struct sensor_w_data vga_sensor1_init_data[] = { - {0x11, 0x04, {0x01}, 1}, - {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, - /* These settings may be better for some cameras */ - /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */ - 0x00, 0x0a}, 7}, - {0x11, 0x04, {0x01}, 1}, - {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6}, - {0x11, 0x04, {0x01}, 1}, - {0, 0, {0}, 0} - }; - - if (sd->adj_colors) - err_code = sensor_write_regs(gspca_dev, color_adj, - ARRAY_SIZE(color_adj)); - else - err_code = sensor_write_regs(gspca_dev, color_no_adj, - ARRAY_SIZE(color_no_adj)); - - if (err_code < 0) - return err_code; - - err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, - ARRAY_SIZE(vga_sensor1_init_data)); - } else { /* sensor type == 2 */ - static const struct sensor_w_data vga_sensor2_init_data[] = { - - {0x01, 0x00, {0x48}, 1}, - {0x02, 0x00, {0x22}, 1}, - /* Reg 3 msb and 4 is lsb of the exposure setting*/ - {0x05, 0x00, {0x10}, 1}, - {0x06, 0x00, {0x00}, 1}, - {0x07, 0x00, {0x00}, 1}, - {0x08, 0x00, {0x00}, 1}, - {0x09, 0x00, {0x00}, 1}, - /* The following are used in the gain control - * which is BTW completely borked in the OEM driver - * The values for each color go from 0 to 0x7ff - *{0x0a, 0x00, {0x01}, 1}, green1 gain msb - *{0x0b, 0x00, {0x10}, 1}, green1 gain lsb - *{0x0c, 0x00, {0x01}, 1}, red gain msb - *{0x0d, 0x00, {0x10}, 1}, red gain lsb - *{0x0e, 0x00, {0x01}, 1}, blue gain msb - *{0x0f, 0x00, {0x10}, 1}, blue gain lsb - *{0x10, 0x00, {0x01}, 1}, green2 gain msb - *{0x11, 0x00, {0x10}, 1}, green2 gain lsb - */ - {0x12, 0x00, {0x00}, 1}, - {0x13, 0x00, {0x04}, 1}, /* weird effect on colors */ - {0x14, 0x00, {0x00}, 1}, - {0x15, 0x00, {0x06}, 1}, - {0x16, 0x00, {0x01}, 1}, - {0x17, 0x00, {0xe2}, 1}, /* vertical alignment */ - {0x18, 0x00, {0x02}, 1}, - {0x19, 0x00, {0x82}, 1}, /* don't mess with */ - {0x1a, 0x00, {0x00}, 1}, - {0x1b, 0x00, {0x20}, 1}, - /* {0x1c, 0x00, {0x17}, 1}, contrast control */ - {0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */ - {0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */ - {0x1f, 0x00, {0x0c}, 1}, - {0x20, 0x00, {0x00}, 1}, - {0, 0, {0}, 0} - }; - err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data, - ARRAY_SIZE(vga_sensor2_init_data)); - } - return err_code; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int err_code; - - sd->sof_read = 0; - - /* Some of the VGA cameras require the memory pointer - * to be set to 0 again. We have been forced to start the - * stream in sd_config() to detect the hardware, and closed it. - * Thus, we need here to do a completely fresh and clean start. */ - err_code = zero_the_pointer(gspca_dev); - if (err_code < 0) - return err_code; - - err_code = stream_start(gspca_dev); - if (err_code < 0) - return err_code; - - if (sd->cam_type == CAM_TYPE_CIF) { - err_code = start_cif_cam(gspca_dev); - } else { - err_code = start_vga_cam(gspca_dev); - } - if (err_code < 0) - return err_code; - - return isoc_enable(gspca_dev); -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - stream_stop(gspca_dev); - /* Not all the cams need this, but even if not, probably a good idea */ - zero_the_pointer(gspca_dev); - if (sd->do_lcd_stop) - lcd_stop(gspca_dev); -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */ - u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */ - static const u8 quick_clix_table[] = - /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ - { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15}; - if (sd->cam_type == CAM_TYPE_VGA) { - sign_reg += 4; - value_reg += 4; - } - - /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */ - if (val > 0) { - sensor_write1(gspca_dev, sign_reg, 0x00); - } else { - sensor_write1(gspca_dev, sign_reg, 0x01); - val = 257 - val; - } - /* Use lookup table for funky Argus QuickClix brightness */ - if (sd->do_lcd_stop) - val = quick_clix_table[val]; - - sensor_write1(gspca_dev, value_reg, val); -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 min_clockdiv) -{ - struct sd *sd = (struct sd *) gspca_dev; - int exposure = MR97310A_EXPOSURE_DEFAULT; - u8 buf[2]; - - if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { - /* This cam does not like exposure settings < 300, - so scale 0 - 4095 to 300 - 4095 */ - exposure = (expo * 9267) / 10000 + 300; - sensor_write1(gspca_dev, 3, exposure >> 4); - sensor_write1(gspca_dev, 4, exposure & 0x0f); - } else if (sd->sensor_type == 2) { - exposure = expo; - exposure >>= 3; - sensor_write1(gspca_dev, 3, exposure >> 8); - sensor_write1(gspca_dev, 4, exposure & 0xff); - } else { - /* We have both a clock divider and an exposure register. - We first calculate the clock divider, as that determines - the maximum exposure and then we calculate the exposure - register setting (which goes from 0 - 511). - - Note our 0 - 4095 exposure is mapped to 0 - 511 - milliseconds exposure time */ - u8 clockdiv = (60 * expo + 7999) / 8000; - - /* Limit framerate to not exceed usb bandwidth */ - if (clockdiv < min_clockdiv && gspca_dev->width >= 320) - clockdiv = min_clockdiv; - else if (clockdiv < 2) - clockdiv = 2; - - if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4) - clockdiv = 4; - - /* Frame exposure time in ms = 1000 * clockdiv / 60 -> - exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ - exposure = (60 * 511 * expo) / (8000 * clockdiv); - if (exposure > 511) - exposure = 511; - - /* exposure register value is reversed! */ - exposure = 511 - exposure; - - buf[0] = exposure & 0xff; - buf[1] = exposure >> 8; - sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2); - sensor_write1(gspca_dev, 0x02, clockdiv); - } -} - -static void setgain(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 gainreg; - - if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) - sensor_write1(gspca_dev, 0x0e, val); - else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2) - for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) { - sensor_write1(gspca_dev, gainreg, val >> 8); - sensor_write1(gspca_dev, gainreg + 1, val & 0xff); - } - else - sensor_write1(gspca_dev, 0x10, val); -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - sensor_write1(gspca_dev, 0x1c, val); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - setexposure(gspca_dev, sd->exposure->val, - sd->min_clockdiv ? sd->min_clockdiv->val : 0); - break; - case V4L2_CID_GAIN: - setgain(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - static const struct v4l2_ctrl_config clockdiv = { - .ops = &sd_ctrl_ops, - .id = MR97310A_CID_CLOCKDIV, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Minimum Clock Divider", - .min = MR97310A_MIN_CLOCKDIV_MIN, - .max = MR97310A_MIN_CLOCKDIV_MAX, - .step = 1, - .def = MR97310A_MIN_CLOCKDIV_DEFAULT, - }; - bool has_brightness = false; - bool has_argus_brightness = false; - bool has_contrast = false; - bool has_gain = false; - bool has_cs_gain = false; - bool has_exposure = false; - bool has_clockdiv = false; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); - - /* Setup controls depending on camera type */ - if (sd->cam_type == CAM_TYPE_CIF) { - /* No brightness for sensor_type 0 */ - if (sd->sensor_type == 0) - has_exposure = has_gain = has_clockdiv = true; - else - has_exposure = has_gain = has_brightness = true; - } else { - /* All controls need to be disabled if VGA sensor_type is 0 */ - if (sd->sensor_type == 0) - ; /* no controls! */ - else if (sd->sensor_type == 2) - has_exposure = has_cs_gain = has_contrast = true; - else if (sd->do_lcd_stop) - has_exposure = has_gain = has_argus_brightness = - has_clockdiv = true; - else - has_exposure = has_gain = has_brightness = - has_clockdiv = true; - } - - /* Separate brightness control description for Argus QuickClix as it has - * different limits from the other mr97310a cameras, and separate gain - * control for Sakar CyberPix camera. */ - /* - * This control is disabled for CIF type 1 and VGA type 0 cameras. - * It does not quite act linearly for the Argus QuickClix camera, - * but it does control brightness. The values are 0 - 15 only, and - * the table above makes them act consecutively. - */ - if (has_brightness) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, -254, 255, 1, - MR97310A_BRIGHTNESS_DEFAULT); - else if (has_argus_brightness) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 15, 1, - MR97310A_BRIGHTNESS_DEFAULT); - if (has_contrast) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, MR97310A_CONTRAST_MIN, - MR97310A_CONTRAST_MAX, 1, MR97310A_CONTRAST_DEFAULT); - if (has_gain) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, MR97310A_GAIN_MIN, MR97310A_GAIN_MAX, - 1, MR97310A_GAIN_DEFAULT); - else if (has_cs_gain) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAIN, - MR97310A_CS_GAIN_MIN, MR97310A_CS_GAIN_MAX, - 1, MR97310A_CS_GAIN_DEFAULT); - if (has_exposure) - sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, MR97310A_EXPOSURE_MIN, - MR97310A_EXPOSURE_MAX, 1, MR97310A_EXPOSURE_DEFAULT); - if (has_clockdiv) - sd->min_clockdiv = v4l2_ctrl_new_custom(hdl, &clockdiv, NULL); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - if (has_exposure && has_clockdiv) - v4l2_ctrl_cluster(2, &sd->exposure); - return 0; -} - -/* Include pac common sof detection functions */ -#include "pac_common.h" - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - unsigned char *sof; - - sof = pac_find_sof(&sd->sof_read, data, len); - if (sof) { - int n; - - /* finish decoding current frame */ - n = sof - data; - if (n > sizeof pac_sof_marker) - n -= sizeof pac_sof_marker; - else - n = 0; - gspca_frame_add(gspca_dev, LAST_PACKET, - data, n); - /* Start next frame. */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - pac_sof_marker, sizeof pac_sof_marker); - len -= sof - data; - data = sof; - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */ - {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */ - {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */ - {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */ - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); |