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/stv06xx | |
parent | 84cfe9e79bd5ac11c963f4841158454fefa872f6 (diff) | |
download | blackbird-op-linux-0c0d06cac63ee327ceaab4b5ffe2206574ab86bd.tar.gz blackbird-op-linux-0c0d06cac63ee327ceaab4b5ffe2206574ab86bd.zip |
[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/stv06xx')
-rw-r--r-- | drivers/media/video/gspca/stv06xx/Kconfig | 9 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/Makefile | 10 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx.c | 634 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx.h | 116 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c | 540 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h | 206 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c | 434 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h | 144 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_sensor.h | 87 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_st6422.c | 285 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_st6422.h | 52 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c | 272 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h | 255 |
13 files changed, 0 insertions, 3044 deletions
diff --git a/drivers/media/video/gspca/stv06xx/Kconfig b/drivers/media/video/gspca/stv06xx/Kconfig deleted file mode 100644 index 634ad38d9fb8..000000000000 --- a/drivers/media/video/gspca/stv06xx/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config USB_STV06XX - tristate "STV06XX USB Camera Driver" - depends on USB_GSPCA - help - Say Y here if you want support for cameras based on - the ST STV06XX chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_stv06xx. diff --git a/drivers/media/video/gspca/stv06xx/Makefile b/drivers/media/video/gspca/stv06xx/Makefile deleted file mode 100644 index 38bc41061d83..000000000000 --- a/drivers/media/video/gspca/stv06xx/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -obj-$(CONFIG_USB_STV06XX) += gspca_stv06xx.o - -gspca_stv06xx-objs := stv06xx.o \ - stv06xx_vv6410.o \ - stv06xx_hdcs.o \ - stv06xx_pb0100.o \ - stv06xx_st6422.o - -ccflags-y += -I$(srctree)/drivers/media/video/gspca - diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c deleted file mode 100644 index 999ec7764449..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx.c +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * 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 - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/input.h> -#include "stv06xx_sensor.h" - -MODULE_AUTHOR("Erik Andrén"); -MODULE_DESCRIPTION("STV06XX USB Camera Driver"); -MODULE_LICENSE("GPL"); - -static bool dump_bridge; -static bool dump_sensor; - -int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data) -{ - int err; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - u8 len = (i2c_data > 0xff) ? 2 : 1; - - buf[0] = i2c_data & 0xff; - buf[1] = (i2c_data >> 8) & 0xff; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, address, 0, buf, len, - STV06XX_URB_MSG_TIMEOUT); - - PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d", - i2c_data, address, err); - - return (err < 0) ? err : 0; -} - -int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data) -{ - int err; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x04, 0xc0, address, 0, buf, 1, - STV06XX_URB_MSG_TIMEOUT); - - *i2c_data = buf[0]; - - PDEBUG(D_CONF, "Reading 0x%x from address 0x%x, status %d", - *i2c_data, address, err); - - return (err < 0) ? err : 0; -} - -/* Wraps the normal write sensor bytes / words functions for writing a - single value */ -int stv06xx_write_sensor(struct sd *sd, u8 address, u16 value) -{ - if (sd->sensor->i2c_len == 2) { - u16 data[2] = { address, value }; - return stv06xx_write_sensor_words(sd, data, 1); - } else { - u8 data[2] = { address, value }; - return stv06xx_write_sensor_bytes(sd, data, 1); - } -} - -static int stv06xx_write_sensor_finish(struct sd *sd) -{ - int err = 0; - - if (sd->bridge == BRIDGE_STV610) { - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - buf[0] = 0; - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x1704, 0, buf, 1, - STV06XX_URB_MSG_TIMEOUT); - } - - return (err < 0) ? err : 0; -} - -int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len) -{ - int err, i, j; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len); - for (i = 0; i < len;) { - /* Build the command buffer */ - memset(buf, 0, I2C_BUFFER_LENGTH); - for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) { - buf[j] = data[2*i]; - buf[0x10 + j] = data[2*i+1]; - PDEBUG(D_CONF, "I2C: Writing 0x%02x to reg 0x%02x", - data[2*i+1], data[2*i]); - } - buf[0x20] = sd->sensor->i2c_addr; - buf[0x21] = j - 1; /* Number of commands to send - 1 */ - buf[0x22] = I2C_WRITE_CMD; - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x0400, 0, buf, - I2C_BUFFER_LENGTH, - STV06XX_URB_MSG_TIMEOUT); - if (err < 0) - return err; - } - return stv06xx_write_sensor_finish(sd); -} - -int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len) -{ - int err, i, j; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len); - - for (i = 0; i < len;) { - /* Build the command buffer */ - memset(buf, 0, I2C_BUFFER_LENGTH); - for (j = 0; j < I2C_MAX_WORDS && i < len; j++, i++) { - buf[j] = data[2*i]; - buf[0x10 + j * 2] = data[2*i+1]; - buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8; - PDEBUG(D_CONF, "I2C: Writing 0x%04x to reg 0x%02x", - data[2*i+1], data[2*i]); - } - buf[0x20] = sd->sensor->i2c_addr; - buf[0x21] = j - 1; /* Number of commands to send - 1 */ - buf[0x22] = I2C_WRITE_CMD; - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x0400, 0, buf, - I2C_BUFFER_LENGTH, - STV06XX_URB_MSG_TIMEOUT); - if (err < 0) - return err; - } - return stv06xx_write_sensor_finish(sd); -} - -int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value) -{ - int err; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - err = stv06xx_write_bridge(sd, STV_I2C_FLUSH, sd->sensor->i2c_flush); - if (err < 0) - return err; - - /* Clear mem */ - memset(buf, 0, I2C_BUFFER_LENGTH); - - buf[0] = address; - buf[0x20] = sd->sensor->i2c_addr; - buf[0x21] = 0; - - /* Read I2C register */ - buf[0x22] = I2C_READ_CMD; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH, - STV06XX_URB_MSG_TIMEOUT); - if (err < 0) { - pr_err("I2C: Read error writing address: %d\n", err); - return err; - } - - err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x04, 0xc0, 0x1410, 0, buf, sd->sensor->i2c_len, - STV06XX_URB_MSG_TIMEOUT); - if (sd->sensor->i2c_len == 2) - *value = buf[0] | (buf[1] << 8); - else - *value = buf[0]; - - PDEBUG(D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d", - *value, address, err); - - return (err < 0) ? err : 0; -} - -/* Dumps all bridge registers */ -static void stv06xx_dump_bridge(struct sd *sd) -{ - int i; - u8 data, buf; - - pr_info("Dumping all stv06xx bridge registers\n"); - for (i = 0x1400; i < 0x160f; i++) { - stv06xx_read_bridge(sd, i, &data); - - pr_info("Read 0x%x from address 0x%x\n", data, i); - } - - pr_info("Testing stv06xx bridge registers for writability\n"); - for (i = 0x1400; i < 0x160f; i++) { - stv06xx_read_bridge(sd, i, &data); - buf = data; - - stv06xx_write_bridge(sd, i, 0xff); - stv06xx_read_bridge(sd, i, &data); - if (data == 0xff) - pr_info("Register 0x%x is read/write\n", i); - else if (data != buf) - pr_info("Register 0x%x is read/write, but only partially\n", - i); - else - pr_info("Register 0x%x is read-only\n", i); - - stv06xx_write_bridge(sd, i, buf); - } -} - -/* this function is called at probe and resume time */ -static int stv06xx_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int err; - - PDEBUG(D_PROBE, "Initializing camera"); - - /* Let the usb init settle for a bit - before performing the initialization */ - msleep(250); - - err = sd->sensor->init(sd); - - if (dump_sensor && sd->sensor->dump) - sd->sensor->dump(sd); - - return (err < 0) ? err : 0; -} - -/* this function is called at probe time */ -static int stv06xx_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(D_PROBE, "Initializing controls"); - - gspca_dev->vdev.ctrl_handler = &gspca_dev->ctrl_handler; - return sd->sensor->init_controls(sd); -} - -/* Start the camera */ -static int stv06xx_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct usb_host_interface *alt; - struct usb_interface *intf; - int err, packet_size; - - intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); - alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); - if (!alt) { - PDEBUG(D_ERR, "Couldn't get altsetting"); - return -EIO; - } - - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size); - if (err < 0) - return err; - - /* Prepare the sensor for start */ - err = sd->sensor->start(sd); - if (err < 0) - goto out; - - /* Start isochronous streaming */ - err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 1); - -out: - if (err < 0) - PDEBUG(D_STREAM, "Starting stream failed"); - else - PDEBUG(D_STREAM, "Started streaming"); - - return (err < 0) ? err : 0; -} - -static int stv06xx_isoc_init(struct gspca_dev *gspca_dev) -{ - struct usb_host_interface *alt; - struct sd *sd = (struct sd *) gspca_dev; - - /* Start isoc bandwidth "negotiation" at max isoc bandwidth */ - alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; - alt->endpoint[0].desc.wMaxPacketSize = - cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]); - - return 0; -} - -static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev) -{ - int ret, packet_size, min_packet_size; - struct usb_host_interface *alt; - struct sd *sd = (struct sd *) gspca_dev; - - alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode]; - if (packet_size <= min_packet_size) - return -EIO; - - packet_size -= 100; - if (packet_size < min_packet_size) - packet_size = min_packet_size; - alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size); - - ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); - if (ret < 0) - PDEBUG(D_ERR|D_STREAM, "set alt 1 err %d", ret); - - return ret; -} - -static void stv06xx_stopN(struct gspca_dev *gspca_dev) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - - /* stop ISO-streaming */ - err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 0); - if (err < 0) - goto out; - - err = sd->sensor->stop(sd); - -out: - if (err < 0) - PDEBUG(D_STREAM, "Failed to stop stream"); - else - PDEBUG(D_STREAM, "Stopped streaming"); -} - -/* - * Analyse an USB packet of the data stream and store it appropriately. - * Each packet contains an integral number of chunks. Each chunk has - * 2-bytes identification, followed by 2-bytes that describe the chunk - * length. Known/guessed chunk identifications are: - * 8001/8005/C001/C005 - Begin new frame - * 8002/8006/C002/C006 - End frame - * 0200/4200 - Contains actual image data, bayer or compressed - * 0005 - 11 bytes of unknown data - * 0100 - 2 bytes of unknown data - * The 0005 and 0100 chunks seem to appear only in compressed stream. - */ -static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(D_PACK, "Packet of length %d arrived", len); - - /* A packet may contain several frames - loop until the whole packet is reached */ - while (len) { - int id, chunk_len; - - if (len < 4) { - PDEBUG(D_PACK, "Packet is smaller than 4 bytes"); - return; - } - - /* Capture the id */ - id = (data[0] << 8) | data[1]; - - /* Capture the chunk length */ - chunk_len = (data[2] << 8) | data[3]; - PDEBUG(D_PACK, "Chunk id: %x, length: %d", id, chunk_len); - - data += 4; - len -= 4; - - if (len < chunk_len) { - PDEBUG(D_ERR, "URB packet length is smaller" - " than the specified chunk length"); - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - } - - /* First byte seem to be 02=data 2nd byte is unknown??? */ - if (sd->bridge == BRIDGE_ST6422 && (id & 0xff00) == 0x0200) - goto frame_data; - - switch (id) { - case 0x0200: - case 0x4200: -frame_data: - PDEBUG(D_PACK, "Frame data packet detected"); - - if (sd->to_skip) { - int skip = (sd->to_skip < chunk_len) ? - sd->to_skip : chunk_len; - data += skip; - len -= skip; - chunk_len -= skip; - sd->to_skip -= skip; - } - - gspca_frame_add(gspca_dev, INTER_PACKET, - data, chunk_len); - break; - - case 0x8001: - case 0x8005: - case 0xc001: - case 0xc005: - PDEBUG(D_PACK, "Starting new frame"); - - /* Create a new frame, chunk length should be zero */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - NULL, 0); - - if (sd->bridge == BRIDGE_ST6422) - sd->to_skip = gspca_dev->width * 4; - - if (chunk_len) - PDEBUG(D_ERR, "Chunk length is " - "non-zero on a SOF"); - break; - - case 0x8002: - case 0x8006: - case 0xc002: - PDEBUG(D_PACK, "End of frame detected"); - - /* Complete the last frame (if any) */ - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); - - if (chunk_len) - PDEBUG(D_ERR, "Chunk length is " - "non-zero on a EOF"); - break; - - case 0x0005: - PDEBUG(D_PACK, "Chunk 0x005 detected"); - /* Unknown chunk with 11 bytes of data, - occurs just before end of each frame - in compressed mode */ - break; - - case 0x0100: - PDEBUG(D_PACK, "Chunk 0x0100 detected"); - /* Unknown chunk with 2 bytes of data, - occurs 2-3 times per USB interrupt */ - break; - case 0x42ff: - PDEBUG(D_PACK, "Chunk 0x42ff detected"); - /* Special chunk seen sometimes on the ST6422 */ - break; - default: - PDEBUG(D_PACK, "Unknown chunk 0x%04x detected", id); - /* Unknown chunk */ - } - data += chunk_len; - len -= chunk_len; - } -} - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* interrupt packet data */ - int len) /* interrupt packet length */ -{ - int ret = -EINVAL; - - if (len == 1 && data[0] == 0x80) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); - input_sync(gspca_dev->input_dev); - ret = 0; - } - - if (len == 1 && data[0] == 0x88) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - ret = 0; - } - - return ret; -} -#endif - -static int stv06xx_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id); - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = stv06xx_config, - .init = stv06xx_init, - .init_controls = stv06xx_init_controls, - .start = stv06xx_start, - .stopN = stv06xx_stopN, - .pkt_scan = stv06xx_pkt_scan, - .isoc_init = stv06xx_isoc_init, - .isoc_nego = stv06xx_isoc_nego, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .int_pkt_scan = sd_int_pkt_scan, -#endif -}; - -/* This function is called at probe time */ -static int stv06xx_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(D_PROBE, "Configuring camera"); - - sd->bridge = id->driver_info; - gspca_dev->sd_desc = &sd_desc; - - if (dump_bridge) - stv06xx_dump_bridge(sd); - - sd->sensor = &stv06xx_sensor_st6422; - if (!sd->sensor->probe(sd)) - return 0; - - sd->sensor = &stv06xx_sensor_vv6410; - if (!sd->sensor->probe(sd)) - return 0; - - sd->sensor = &stv06xx_sensor_hdcs1x00; - if (!sd->sensor->probe(sd)) - return 0; - - sd->sensor = &stv06xx_sensor_hdcs1020; - if (!sd->sensor->probe(sd)) - return 0; - - sd->sensor = &stv06xx_sensor_pb0100; - if (!sd->sensor->probe(sd)) - return 0; - - sd->sensor = NULL; - return -ENODEV; -} - - - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - /* QuickCam Express */ - {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, - /* LEGO cam / QuickCam Web */ - {USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 }, - /* Dexxa WebCam USB */ - {USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 }, - /* QuickCam Messenger */ - {USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 }, - /* QuickCam Communicate */ - {USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 }, - /* QuickCam Messenger (new) */ - {USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 }, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - PDEBUG(D_PROBE, "Probing for a stv06xx device"); - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static void sd_disconnect(struct usb_interface *intf) -{ - struct gspca_dev *gspca_dev = usb_get_intfdata(intf); - struct sd *sd = (struct sd *) gspca_dev; - void *priv = sd->sensor_priv; - PDEBUG(D_PROBE, "Disconnecting the stv06xx device"); - - sd->sensor = NULL; - gspca_disconnect(intf); - kfree(priv); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = sd_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); - -module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); - -module_param(dump_sensor, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(dump_sensor, "Dumps all sensor registers at startup"); diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h deleted file mode 100644 index 34957a4ec150..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * 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 - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#ifndef STV06XX_H_ -#define STV06XX_H_ - -#include <linux/slab.h> -#include "gspca.h" - -#define MODULE_NAME "STV06xx" - -#define STV_ISOC_ENDPOINT_ADDR 0x81 - -#define STV_R 0x0509 - -#define STV_REG23 0x0423 - -/* Control registers of the STV0600 ASIC */ -#define STV_I2C_PARTNER 0x1420 -#define STV_I2C_VAL_REG_VAL_PAIRS_MIN1 0x1421 -#define STV_I2C_READ_WRITE_TOGGLE 0x1422 -#define STV_I2C_FLUSH 0x1423 -#define STV_I2C_SUCC_READ_REG_VALS 0x1424 - -#define STV_ISO_ENABLE 0x1440 -#define STV_SCAN_RATE 0x1443 -#define STV_LED_CTRL 0x1445 -#define STV_STV0600_EMULATION 0x1446 -#define STV_REG00 0x1500 -#define STV_REG01 0x1501 -#define STV_REG02 0x1502 -#define STV_REG03 0x1503 -#define STV_REG04 0x1504 - -#define STV_ISO_SIZE_L 0x15c1 -#define STV_ISO_SIZE_H 0x15c2 - -/* Refers to the CIF 352x288 and QCIF 176x144 */ -/* 1: 288 lines, 2: 144 lines */ -#define STV_Y_CTRL 0x15c3 - -#define STV_RESET 0x1620 - -/* 0xa: 352 columns, 0x6: 176 columns */ -#define STV_X_CTRL 0x1680 - -#define STV06XX_URB_MSG_TIMEOUT 5000 - -#define I2C_MAX_BYTES 16 -#define I2C_MAX_WORDS 8 - -#define I2C_BUFFER_LENGTH 0x23 -#define I2C_READ_CMD 3 -#define I2C_WRITE_CMD 1 - -#define LED_ON 1 -#define LED_OFF 0 - -/* STV06xx device descriptor */ -struct sd { - struct gspca_dev gspca_dev; - - /* A pointer to the currently connected sensor */ - const struct stv06xx_sensor *sensor; - - /* Sensor private data */ - void *sensor_priv; - - /* The first 4 lines produced by the stv6422 are no good, this keeps - track of how many bytes we still need to skip during a frame */ - int to_skip; - - /* Bridge / Camera type */ - u8 bridge; - #define BRIDGE_STV600 0 - #define BRIDGE_STV602 1 - #define BRIDGE_STV610 2 - #define BRIDGE_ST6422 3 /* With integrated sensor */ -}; - -int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data); -int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data); - -int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len); -int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len); - -int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value); -int stv06xx_write_sensor(struct sd *sd, u8 address, u16 value); - -#endif diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c deleted file mode 100644 index 06fa54c5efb2..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * Copyright (c) 2008 Chia-I Wu - * - * 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 - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "stv06xx_hdcs.h" - -static struct v4l2_pix_format hdcs1x00_mode[] = { - { - HDCS_1X00_DEF_WIDTH, - HDCS_1X00_DEF_HEIGHT, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = - HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, - .bytesperline = HDCS_1X00_DEF_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } -}; - -static struct v4l2_pix_format hdcs1020_mode[] = { - { - HDCS_1020_DEF_WIDTH, - HDCS_1020_DEF_HEIGHT, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = - HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, - .bytesperline = HDCS_1020_DEF_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } -}; - -enum hdcs_power_state { - HDCS_STATE_SLEEP, - HDCS_STATE_IDLE, - HDCS_STATE_RUN -}; - -/* no lock? */ -struct hdcs { - enum hdcs_power_state state; - int w, h; - - /* visible area of the sensor array */ - struct { - int left, top; - int width, height; - int border; - } array; - - struct { - /* Column timing overhead */ - u8 cto; - /* Column processing overhead */ - u8 cpo; - /* Row sample period constant */ - u16 rs; - /* Exposure reset duration */ - u16 er; - } exp; - - int psmp; -}; - -static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len) -{ - u8 regs[I2C_MAX_BYTES * 2]; - int i; - - if (unlikely((len <= 0) || (len >= I2C_MAX_BYTES) || - (reg + len > 0xff))) - return -EINVAL; - - for (i = 0; i < len; i++) { - regs[2 * i] = reg; - regs[2 * i + 1] = vals[i]; - /* All addresses are shifted left one bit - * as bit 0 toggles r/w */ - reg += 2; - } - - return stv06xx_write_sensor_bytes(sd, regs, len); -} - -static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state) -{ - struct hdcs *hdcs = sd->sensor_priv; - u8 val; - int ret; - - if (hdcs->state == state) - return 0; - - /* we need to go idle before running or sleeping */ - if (hdcs->state != HDCS_STATE_IDLE) { - ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0); - if (ret) - return ret; - } - - hdcs->state = HDCS_STATE_IDLE; - - if (state == HDCS_STATE_IDLE) - return 0; - - switch (state) { - case HDCS_STATE_SLEEP: - val = HDCS_SLEEP_MODE; - break; - - case HDCS_STATE_RUN: - val = HDCS_RUN_ENABLE; - break; - - default: - return -EINVAL; - } - - ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val); - - /* Update the state if the write succeeded */ - if (!ret) - hdcs->state = state; - - return ret; -} - -static int hdcs_reset(struct sd *sd) -{ - struct hdcs *hdcs = sd->sensor_priv; - int err; - - err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 1); - if (err < 0) - return err; - - err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0); - if (err < 0) - hdcs->state = HDCS_STATE_IDLE; - - return err; -} - -static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct hdcs *hdcs = sd->sensor_priv; - int rowexp, srowexp; - int max_srowexp; - /* Column time period */ - int ct; - /* Column processing period */ - int cp; - /* Row processing period */ - int rp; - /* Minimum number of column timing periods - within the column processing period */ - int mnct; - int cycles, err; - u8 exp[14]; - - cycles = val * HDCS_CLK_FREQ_MHZ * 257; - - ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2); - cp = hdcs->exp.cto + (hdcs->w * ct / 2); - - /* the cycles one row takes */ - rp = hdcs->exp.rs + cp; - - rowexp = cycles / rp; - - /* the remaining cycles */ - cycles -= rowexp * rp; - - /* calculate sub-row exposure */ - if (IS_1020(sd)) { - /* see HDCS-1020 datasheet 3.5.6.4, p. 63 */ - srowexp = hdcs->w - (cycles + hdcs->exp.er + 13) / ct; - - mnct = (hdcs->exp.er + 12 + ct - 1) / ct; - max_srowexp = hdcs->w - mnct; - } else { - /* see HDCS-1000 datasheet 3.4.5.5, p. 61 */ - srowexp = cp - hdcs->exp.er - 6 - cycles; - - mnct = (hdcs->exp.er + 5 + ct - 1) / ct; - max_srowexp = cp - mnct * ct - 1; - } - - if (srowexp < 0) - srowexp = 0; - else if (srowexp > max_srowexp) - srowexp = max_srowexp; - - if (IS_1020(sd)) { - exp[0] = HDCS20_CONTROL; - exp[1] = 0x00; /* Stop streaming */ - exp[2] = HDCS_ROWEXPL; - exp[3] = rowexp & 0xff; - exp[4] = HDCS_ROWEXPH; - exp[5] = rowexp >> 8; - exp[6] = HDCS20_SROWEXP; - exp[7] = (srowexp >> 2) & 0xff; - exp[8] = HDCS20_ERROR; - exp[9] = 0x10; /* Clear exposure error flag*/ - exp[10] = HDCS20_CONTROL; - exp[11] = 0x04; /* Restart streaming */ - err = stv06xx_write_sensor_bytes(sd, exp, 6); - } else { - exp[0] = HDCS00_CONTROL; - exp[1] = 0x00; /* Stop streaming */ - exp[2] = HDCS_ROWEXPL; - exp[3] = rowexp & 0xff; - exp[4] = HDCS_ROWEXPH; - exp[5] = rowexp >> 8; - exp[6] = HDCS00_SROWEXPL; - exp[7] = srowexp & 0xff; - exp[8] = HDCS00_SROWEXPH; - exp[9] = srowexp >> 8; - exp[10] = HDCS_STATUS; - exp[11] = 0x10; /* Clear exposure error flag*/ - exp[12] = HDCS00_CONTROL; - exp[13] = 0x04; /* Restart streaming */ - err = stv06xx_write_sensor_bytes(sd, exp, 7); - if (err < 0) - return err; - } - PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d", - val, rowexp, srowexp); - return err; -} - -static int hdcs_set_gains(struct sd *sd, u8 g) -{ - int err; - u8 gains[4]; - - /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */ - if (g > 127) - g = 0x80 | (g / 2); - - gains[0] = g; - gains[1] = g; - gains[2] = g; - gains[3] = g; - - err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4); - return err; -} - -static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - PDEBUG(D_V4L2, "Writing gain %d", val); - return hdcs_set_gains((struct sd *) gspca_dev, - val & 0xff); -} - -static int hdcs_set_size(struct sd *sd, - unsigned int width, unsigned int height) -{ - struct hdcs *hdcs = sd->sensor_priv; - u8 win[4]; - unsigned int x, y; - int err; - - /* must be multiple of 4 */ - width = (width + 3) & ~0x3; - height = (height + 3) & ~0x3; - - if (width > hdcs->array.width) - width = hdcs->array.width; - - if (IS_1020(sd)) { - /* the borders are also invalid */ - if (height + 2 * hdcs->array.border + HDCS_1020_BOTTOM_Y_SKIP - > hdcs->array.height) - height = hdcs->array.height - 2 * hdcs->array.border - - HDCS_1020_BOTTOM_Y_SKIP; - - y = (hdcs->array.height - HDCS_1020_BOTTOM_Y_SKIP - height) / 2 - + hdcs->array.top; - } else { - if (height > hdcs->array.height) - height = hdcs->array.height; - - y = hdcs->array.top + (hdcs->array.height - height) / 2; - } - - x = hdcs->array.left + (hdcs->array.width - width) / 2; - - win[0] = y / 4; - win[1] = x / 4; - win[2] = (y + height) / 4 - 1; - win[3] = (x + width) / 4 - 1; - - err = hdcs_reg_write_seq(sd, HDCS_FWROW, win, 4); - if (err < 0) - return err; - - /* Update the current width and height */ - hdcs->w = width; - hdcs->h = height; - return err; -} - -static int hdcs_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - int err = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_GAIN: - err = hdcs_set_gain(gspca_dev, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - err = hdcs_set_exposure(gspca_dev, ctrl->val); - break; - } - return err; -} - -static const struct v4l2_ctrl_ops hdcs_ctrl_ops = { - .s_ctrl = hdcs_s_ctrl, -}; - -static int hdcs_init_controls(struct sd *sd) -{ - struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; - - v4l2_ctrl_handler_init(hdl, 2); - v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 0xff, 1, HDCS_DEFAULT_EXPOSURE); - v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops, - V4L2_CID_GAIN, 0, 0xff, 1, HDCS_DEFAULT_GAIN); - return hdl->error; -} - -static int hdcs_probe_1x00(struct sd *sd) -{ - struct hdcs *hdcs; - u16 sensor; - int ret; - - ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor); - if (ret < 0 || sensor != 0x08) - return -ENODEV; - - pr_info("HDCS-1000/1100 sensor detected\n"); - - sd->gspca_dev.cam.cam_mode = hdcs1x00_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode); - - hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); - if (!hdcs) - return -ENOMEM; - - hdcs->array.left = 8; - hdcs->array.top = 8; - hdcs->array.width = HDCS_1X00_DEF_WIDTH; - hdcs->array.height = HDCS_1X00_DEF_HEIGHT; - hdcs->array.border = 4; - - hdcs->exp.cto = 4; - hdcs->exp.cpo = 2; - hdcs->exp.rs = 186; - hdcs->exp.er = 100; - - /* - * Frame rate on HDCS-1000 with STV600 depends on PSMP: - * 4 = doesn't work at all - * 5 = 7.8 fps, - * 6 = 6.9 fps, - * 8 = 6.3 fps, - * 10 = 5.5 fps, - * 15 = 4.4 fps, - * 31 = 2.8 fps - * - * Frame rate on HDCS-1000 with STV602 depends on PSMP: - * 15 = doesn't work at all - * 18 = doesn't work at all - * 19 = 7.3 fps - * 20 = 7.4 fps - * 21 = 7.4 fps - * 22 = 7.4 fps - * 24 = 6.3 fps - * 30 = 5.4 fps - */ - hdcs->psmp = (sd->bridge == BRIDGE_STV602) ? 20 : 5; - - sd->sensor_priv = hdcs; - - return 0; -} - -static int hdcs_probe_1020(struct sd *sd) -{ - struct hdcs *hdcs; - u16 sensor; - int ret; - - ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor); - if (ret < 0 || sensor != 0x10) - return -ENODEV; - - pr_info("HDCS-1020 sensor detected\n"); - - sd->gspca_dev.cam.cam_mode = hdcs1020_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode); - - hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); - if (!hdcs) - return -ENOMEM; - - /* - * From Andrey's test image: looks like HDCS-1020 upper-left - * visible pixel is at 24,8 (y maybe even smaller?) and lower-right - * visible pixel at 375,299 (x maybe even larger?) - */ - hdcs->array.left = 24; - hdcs->array.top = 4; - hdcs->array.width = HDCS_1020_DEF_WIDTH; - hdcs->array.height = 304; - hdcs->array.border = 4; - - hdcs->psmp = 6; - - hdcs->exp.cto = 3; - hdcs->exp.cpo = 3; - hdcs->exp.rs = 155; - hdcs->exp.er = 96; - - sd->sensor_priv = hdcs; - - return 0; -} - -static int hdcs_start(struct sd *sd) -{ - PDEBUG(D_STREAM, "Starting stream"); - - return hdcs_set_state(sd, HDCS_STATE_RUN); -} - -static int hdcs_stop(struct sd *sd) -{ - PDEBUG(D_STREAM, "Halting stream"); - - return hdcs_set_state(sd, HDCS_STATE_SLEEP); -} - -static int hdcs_init(struct sd *sd) -{ - struct hdcs *hdcs = sd->sensor_priv; - int i, err = 0; - - /* Set the STV0602AA in STV0600 emulation mode */ - if (sd->bridge == BRIDGE_STV602) - stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1); - - /* Execute the bridge init */ - for (i = 0; i < ARRAY_SIZE(stv_bridge_init) && !err; i++) { - err = stv06xx_write_bridge(sd, stv_bridge_init[i][0], - stv_bridge_init[i][1]); - } - if (err < 0) - return err; - - /* sensor soft reset */ - hdcs_reset(sd); - - /* Execute the sensor init */ - for (i = 0; i < ARRAY_SIZE(stv_sensor_init) && !err; i++) { - err = stv06xx_write_sensor(sd, stv_sensor_init[i][0], - stv_sensor_init[i][1]); - } - if (err < 0) - return err; - - /* Enable continuous frame capture, bit 2: stop when frame complete */ - err = stv06xx_write_sensor(sd, HDCS_REG_CONFIG(sd), BIT(3)); - if (err < 0) - return err; - - /* Set PGA sample duration - (was 0x7E for the STV602, but caused slow framerate with HDCS-1020) */ - if (IS_1020(sd)) - err = stv06xx_write_sensor(sd, HDCS_TCTRL, - (HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp); - else - err = stv06xx_write_sensor(sd, HDCS_TCTRL, - (HDCS_ADC_START_SIG_DUR << 5) | hdcs->psmp); - if (err < 0) - return err; - - return hdcs_set_size(sd, hdcs->array.width, hdcs->array.height); -} - -static int hdcs_dump(struct sd *sd) -{ - u16 reg, val; - - pr_info("Dumping sensor registers:\n"); - - for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH; reg++) { - stv06xx_read_sensor(sd, reg, &val); - pr_info("reg 0x%02x = 0x%02x\n", reg, val); - } - return 0; -} diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h deleted file mode 100644 index 1ba9158d0102..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * Copyright (c) 2008 Chia-I Wu - * - * 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 - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#ifndef STV06XX_HDCS_H_ -#define STV06XX_HDCS_H_ - -#include "stv06xx_sensor.h" - -#define HDCS_REG_CONFIG(sd) (IS_1020(sd) ? HDCS20_CONFIG : HDCS00_CONFIG) -#define HDCS_REG_CONTROL(sd) (IS_1020(sd) ? HDCS20_CONTROL : HDCS00_CONTROL) - -#define HDCS_1X00_DEF_WIDTH 360 -#define HDCS_1X00_DEF_HEIGHT 296 - -#define HDCS_1020_DEF_WIDTH 352 -#define HDCS_1020_DEF_HEIGHT 292 - -#define HDCS_1020_BOTTOM_Y_SKIP 4 - -#define HDCS_CLK_FREQ_MHZ 25 - -#define HDCS_ADC_START_SIG_DUR 3 - -/* LSB bit of I2C or register address signifies write (0) or read (1) */ -/* I2C Registers common for both HDCS-1000/1100 and HDCS-1020 */ -/* Identifications Register */ -#define HDCS_IDENT (0x00 << 1) -/* Status Register */ -#define HDCS_STATUS (0x01 << 1) -/* Interrupt Mask Register */ -#define HDCS_IMASK (0x02 << 1) -/* Pad Control Register */ -#define HDCS_PCTRL (0x03 << 1) -/* Pad Drive Control Register */ -#define HDCS_PDRV (0x04 << 1) -/* Interface Control Register */ -#define HDCS_ICTRL (0x05 << 1) -/* Interface Timing Register */ -#define HDCS_ITMG (0x06 << 1) -/* Baud Fraction Register */ -#define HDCS_BFRAC (0x07 << 1) -/* Baud Rate Register */ -#define HDCS_BRATE (0x08 << 1) -/* ADC Control Register */ -#define HDCS_ADCCTRL (0x09 << 1) -/* First Window Row Register */ -#define HDCS_FWROW (0x0a << 1) -/* First Window Column Register */ -#define HDCS_FWCOL (0x0b << 1) -/* Last Window Row Register */ -#define HDCS_LWROW (0x0c << 1) -/* Last Window Column Register */ -#define HDCS_LWCOL (0x0d << 1) -/* Timing Control Register */ -#define HDCS_TCTRL (0x0e << 1) -/* PGA Gain Register: Even Row, Even Column */ -#define HDCS_ERECPGA (0x0f << 1) -/* PGA Gain Register: Even Row, Odd Column */ -#define HDCS_EROCPGA (0x10 << 1) -/* PGA Gain Register: Odd Row, Even Column */ -#define HDCS_ORECPGA (0x11 << 1) -/* PGA Gain Register: Odd Row, Odd Column */ -#define HDCS_OROCPGA (0x12 << 1) -/* Row Exposure Low Register */ -#define HDCS_ROWEXPL (0x13 << 1) -/* Row Exposure High Register */ -#define HDCS_ROWEXPH (0x14 << 1) - -/* I2C Registers only for HDCS-1000/1100 */ -/* Sub-Row Exposure Low Register */ -#define HDCS00_SROWEXPL (0x15 << 1) -/* Sub-Row Exposure High Register */ -#define HDCS00_SROWEXPH (0x16 << 1) -/* Configuration Register */ -#define HDCS00_CONFIG (0x17 << 1) -/* Control Register */ -#define HDCS00_CONTROL (0x18 << 1) - -/* I2C Registers only for HDCS-1020 */ -/* Sub-Row Exposure Register */ -#define HDCS20_SROWEXP (0x15 << 1) -/* Error Control Register */ -#define HDCS20_ERROR (0x16 << 1) -/* Interface Timing 2 Register */ -#define HDCS20_ITMG2 (0x17 << 1) -/* Interface Control 2 Register */ -#define HDCS20_ICTRL2 (0x18 << 1) -/* Horizontal Blank Register */ -#define HDCS20_HBLANK (0x19 << 1) -/* Vertical Blank Register */ -#define HDCS20_VBLANK (0x1a << 1) -/* Configuration Register */ -#define HDCS20_CONFIG (0x1b << 1) -/* Control Register */ -#define HDCS20_CONTROL (0x1c << 1) - -#define HDCS_RUN_ENABLE (1 << 2) -#define HDCS_SLEEP_MODE (1 << 1) - -#define HDCS_DEFAULT_EXPOSURE 48 -#define HDCS_DEFAULT_GAIN 50 - -static int hdcs_probe_1x00(struct sd *sd); -static int hdcs_probe_1020(struct sd *sd); -static int hdcs_start(struct sd *sd); -static int hdcs_init(struct sd *sd); -static int hdcs_init_controls(struct sd *sd); -static int hdcs_stop(struct sd *sd); -static int hdcs_dump(struct sd *sd); - -static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val); - -const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = { - .name = "HP HDCS-1000/1100", - .i2c_flush = 0, - .i2c_addr = (0x55 << 1), - .i2c_len = 1, - - /* FIXME (see if we can lower min_packet_size, needs testing, and also - adjusting framerate when the bandwidth gets lower) */ - .min_packet_size = { 847 }, - .max_packet_size = { 847 }, - - .init = hdcs_init, - .init_controls = hdcs_init_controls, - .probe = hdcs_probe_1x00, - .start = hdcs_start, - .stop = hdcs_stop, - .dump = hdcs_dump, -}; - -const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = { - .name = "HDCS-1020", - .i2c_flush = 0, - .i2c_addr = (0x55 << 1), - .i2c_len = 1, - - /* FIXME (see if we can lower min_packet_size, needs testing, and also - adjusting framerate when the bandwidthm gets lower) */ - .min_packet_size = { 847 }, - .max_packet_size = { 847 }, - - .init = hdcs_init, - .init_controls = hdcs_init_controls, - .probe = hdcs_probe_1020, - .start = hdcs_start, - .stop = hdcs_stop, - .dump = hdcs_dump, -}; - -static const u16 stv_bridge_init[][2] = { - {STV_ISO_ENABLE, 0}, - {STV_REG23, 0}, - {STV_REG00, 0x1d}, - {STV_REG01, 0xb5}, - {STV_REG02, 0xa8}, - {STV_REG03, 0x95}, - {STV_REG04, 0x07}, - - {STV_SCAN_RATE, 0x20}, - {STV_Y_CTRL, 0x01}, - {STV_X_CTRL, 0x0a} -}; - -static const u8 stv_sensor_init[][2] = { - /* Clear status (writing 1 will clear the corresponding status bit) */ - {HDCS_STATUS, BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1)}, - /* Disable all interrupts */ - {HDCS_IMASK, 0x00}, - {HDCS_PCTRL, BIT(6) | BIT(5) | BIT(1) | BIT(0)}, - {HDCS_PDRV, 0x00}, - {HDCS_ICTRL, BIT(5)}, - {HDCS_ITMG, BIT(4) | BIT(1)}, - /* ADC output resolution to 10 bits */ - {HDCS_ADCCTRL, 10} -}; - -#endif diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c deleted file mode 100644 index cdfc3d05ab6b..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * 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 - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -/* - * The spec file for the PB-0100 suggests the following for best quality - * images after the sensor has been reset : - * - * PB_ADCGAINL = R60 = 0x03 (3 dec) : sets low reference of ADC - to produce good black level - * PB_PREADCTRL = R32 = 0x1400 (5120 dec) : Enables global gain changes - through R53 - * PB_ADCMINGAIN = R52 = 0x10 (16 dec) : Sets the minimum gain for - auto-exposure - * PB_ADCGLOBALGAIN = R53 = 0x10 (16 dec) : Sets the global gain - * PB_EXPGAIN = R14 = 0x11 (17 dec) : Sets the auto-exposure value - * PB_UPDATEINT = R23 = 0x02 (2 dec) : Sets the speed on - auto-exposure routine - * PB_CFILLIN = R5 = 0x0E (14 dec) : Sets the frame rate - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "stv06xx_pb0100.h" - -struct pb0100_ctrls { - struct { /* one big happy control cluster... */ - struct v4l2_ctrl *autogain; - struct v4l2_ctrl *gain; - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *red; - struct v4l2_ctrl *blue; - struct v4l2_ctrl *natural; - }; - struct v4l2_ctrl *target; -}; - -static struct v4l2_pix_format pb0100_mode[] = { -/* low res / subsample modes disabled as they are only half res horizontal, - halving the vertical resolution does not seem to work */ - { - 320, - 240, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 320 * 240, - .bytesperline = 320, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = PB0100_CROP_TO_VGA - }, - { - 352, - 288, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 352 * 288, - .bytesperline = 352, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - } -}; - -static int pb0100_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; - struct pb0100_ctrls *ctrls = sd->sensor_priv; - int err = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - err = pb0100_set_autogain(gspca_dev, ctrl->val); - if (err) - break; - if (ctrl->val) - break; - err = pb0100_set_gain(gspca_dev, ctrls->gain->val); - if (err) - break; - err = pb0100_set_exposure(gspca_dev, ctrls->exposure->val); - break; - case V4L2_CTRL_CLASS_USER + 0x1001: - err = pb0100_set_autogain_target(gspca_dev, ctrl->val); - break; - } - return err; -} - -static const struct v4l2_ctrl_ops pb0100_ctrl_ops = { - .s_ctrl = pb0100_s_ctrl, -}; - -static int pb0100_init_controls(struct sd *sd) -{ - struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; - struct pb0100_ctrls *ctrls; - static const struct v4l2_ctrl_config autogain_target = { - .ops = &pb0100_ctrl_ops, - .id = V4L2_CTRL_CLASS_USER + 0x1000, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Automatic Gain Target", - .max = 255, - .step = 1, - .def = 128, - }; - static const struct v4l2_ctrl_config natural_light = { - .ops = &pb0100_ctrl_ops, - .id = V4L2_CTRL_CLASS_USER + 0x1001, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Natural Light Source", - .max = 1, - .step = 1, - .def = 1, - }; - - ctrls = kzalloc(sizeof(*ctrls), GFP_KERNEL); - if (!ctrls) - return -ENOMEM; - - v4l2_ctrl_handler_init(hdl, 6); - ctrls->autogain = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - ctrls->exposure = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 511, 1, 12); - ctrls->gain = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops, - V4L2_CID_GAIN, 0, 255, 1, 128); - ctrls->red = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops, - V4L2_CID_RED_BALANCE, -255, 255, 1, 0); - ctrls->blue = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops, - V4L2_CID_BLUE_BALANCE, -255, 255, 1, 0); - ctrls->natural = v4l2_ctrl_new_custom(hdl, &natural_light, NULL); - ctrls->target = v4l2_ctrl_new_custom(hdl, &autogain_target, NULL); - if (hdl->error) { - kfree(ctrls); - return hdl->error; - } - sd->sensor_priv = ctrls; - v4l2_ctrl_auto_cluster(5, &ctrls->autogain, 0, false); - return 0; -} - -static int pb0100_probe(struct sd *sd) -{ - u16 sensor; - int err; - - err = stv06xx_read_sensor(sd, PB_IDENT, &sensor); - - if (err < 0) - return -ENODEV; - if ((sensor >> 8) != 0x64) - return -ENODEV; - - pr_info("Photobit pb0100 sensor detected\n"); - - sd->gspca_dev.cam.cam_mode = pb0100_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode); - - return 0; -} - -static int pb0100_start(struct sd *sd) -{ - int err, packet_size, max_packet_size; - struct usb_host_interface *alt; - struct usb_interface *intf; - struct cam *cam = &sd->gspca_dev.cam; - u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv; - - intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); - alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); - if (!alt) - return -ENODEV; - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - - /* If we don't have enough bandwidth use a lower framerate */ - max_packet_size = sd->sensor->max_packet_size[sd->gspca_dev.curr_mode]; - if (packet_size < max_packet_size) - stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); - else - stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(5)|BIT(3)|BIT(1)); - - /* Setup sensor window */ - if (mode & PB0100_CROP_TO_VGA) { - stv06xx_write_sensor(sd, PB_RSTART, 30); - stv06xx_write_sensor(sd, PB_CSTART, 20); - stv06xx_write_sensor(sd, PB_RWSIZE, 240 - 1); - stv06xx_write_sensor(sd, PB_CWSIZE, 320 - 1); - } else { - stv06xx_write_sensor(sd, PB_RSTART, 8); - stv06xx_write_sensor(sd, PB_CSTART, 4); - stv06xx_write_sensor(sd, PB_RWSIZE, 288 - 1); - stv06xx_write_sensor(sd, PB_CWSIZE, 352 - 1); - } - - if (mode & PB0100_SUBSAMPLE) { - stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); /* Wrong, FIXME */ - stv06xx_write_bridge(sd, STV_X_CTRL, 0x06); - - stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10); - } else { - stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01); - stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a); - /* larger -> slower */ - stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20); - } - - err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1)); - PDEBUG(D_STREAM, "Started stream, status: %d", err); - - return (err < 0) ? err : 0; -} - -static int pb0100_stop(struct sd *sd) -{ - int err; - - err = stv06xx_write_sensor(sd, PB_ABORTFRAME, 1); - - if (err < 0) - goto out; - - /* Set bit 1 to zero */ - err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)); - - PDEBUG(D_STREAM, "Halting stream"); -out: - return (err < 0) ? err : 0; -} - -/* FIXME: Sort the init commands out and put them into tables, - this is only for getting the camera to work */ -/* FIXME: No error handling for now, - add this once the init has been converted to proper tables */ -static int pb0100_init(struct sd *sd) -{ - stv06xx_write_bridge(sd, STV_REG00, 1); - stv06xx_write_bridge(sd, STV_SCAN_RATE, 0); - - /* Reset sensor */ - stv06xx_write_sensor(sd, PB_RESET, 1); - stv06xx_write_sensor(sd, PB_RESET, 0); - - /* Disable chip */ - stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)); - - /* Gain stuff...*/ - stv06xx_write_sensor(sd, PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6)); - stv06xx_write_sensor(sd, PB_ADCGLOBALGAIN, 12); - - /* Set up auto-exposure */ - /* ADC VREF_HI new setting for a transition - from the Expose1 to the Expose2 setting */ - stv06xx_write_sensor(sd, PB_R28, 12); - /* gain max for autoexposure */ - stv06xx_write_sensor(sd, PB_ADCMAXGAIN, 180); - /* gain min for autoexposure */ - stv06xx_write_sensor(sd, PB_ADCMINGAIN, 12); - /* Maximum frame integration time (programmed into R8) - allowed for auto-exposure routine */ - stv06xx_write_sensor(sd, PB_R54, 3); - /* Minimum frame integration time (programmed into R8) - allowed for auto-exposure routine */ - stv06xx_write_sensor(sd, PB_R55, 0); - stv06xx_write_sensor(sd, PB_UPDATEINT, 1); - /* R15 Expose0 (maximum that auto-exposure may use) */ - stv06xx_write_sensor(sd, PB_R15, 800); - /* R17 Expose2 (minimum that auto-exposure may use) */ - stv06xx_write_sensor(sd, PB_R17, 10); - - stv06xx_write_sensor(sd, PB_EXPGAIN, 0); - - /* 0x14 */ - stv06xx_write_sensor(sd, PB_VOFFSET, 0); - /* 0x0D */ - stv06xx_write_sensor(sd, PB_ADCGAINH, 11); - /* Set black level (important!) */ - stv06xx_write_sensor(sd, PB_ADCGAINL, 0); - - /* ??? */ - stv06xx_write_bridge(sd, STV_REG00, 0x11); - stv06xx_write_bridge(sd, STV_REG03, 0x45); - stv06xx_write_bridge(sd, STV_REG04, 0x07); - - /* Scan/timing for the sensor */ - stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); - stv06xx_write_sensor(sd, PB_CFILLIN, 14); - stv06xx_write_sensor(sd, PB_VBL, 0); - stv06xx_write_sensor(sd, PB_FINTTIME, 0); - stv06xx_write_sensor(sd, PB_RINTTIME, 123); - - stv06xx_write_bridge(sd, STV_REG01, 0xc2); - stv06xx_write_bridge(sd, STV_REG02, 0xb0); - return 0; -} - -static int pb0100_dump(struct sd *sd) -{ - return 0; -} - -static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - struct pb0100_ctrls *ctrls = sd->sensor_priv; - - err = stv06xx_write_sensor(sd, PB_G1GAIN, val); - if (!err) - err = stv06xx_write_sensor(sd, PB_G2GAIN, val); - PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err); - - if (!err) - err = pb0100_set_red_balance(gspca_dev, ctrls->red->val); - if (!err) - err = pb0100_set_blue_balance(gspca_dev, ctrls->blue->val); - - return err; -} - -static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - struct pb0100_ctrls *ctrls = sd->sensor_priv; - - val += ctrls->gain->val; - if (val < 0) - val = 0; - else if (val > 255) - val = 255; - - err = stv06xx_write_sensor(sd, PB_RGAIN, val); - PDEBUG(D_V4L2, "Set red gain to %d, status: %d", val, err); - - return err; -} - -static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - struct pb0100_ctrls *ctrls = sd->sensor_priv; - - val += ctrls->gain->val; - if (val < 0) - val = 0; - else if (val > 255) - val = 255; - - err = stv06xx_write_sensor(sd, PB_BGAIN, val); - PDEBUG(D_V4L2, "Set blue gain to %d, status: %d", val, err); - - return err; -} - -static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - int err; - - err = stv06xx_write_sensor(sd, PB_RINTTIME, val); - PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err); - - return err; -} - -static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - struct pb0100_ctrls *ctrls = sd->sensor_priv; - - if (val) { - if (ctrls->natural->val) - val = BIT(6)|BIT(4)|BIT(0); - else - val = BIT(4)|BIT(0); - } else - val = 0; - - err = stv06xx_write_sensor(sd, PB_EXPGAIN, val); - PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d", - val, ctrls->natural->val, err); - - return err; -} - -static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val) -{ - int err, totalpixels, brightpixels, darkpixels; - struct sd *sd = (struct sd *) gspca_dev; - - /* Number of pixels counted by the sensor when subsampling the pixels. - * Slightly larger than the real value to avoid oscillation */ - totalpixels = gspca_dev->width * gspca_dev->height; - totalpixels = totalpixels/(8*8) + totalpixels/(64*64); - - brightpixels = (totalpixels * val) >> 8; - darkpixels = totalpixels - brightpixels; - err = stv06xx_write_sensor(sd, PB_R21, brightpixels); - if (!err) - err = stv06xx_write_sensor(sd, PB_R22, darkpixels); - - PDEBUG(D_V4L2, "Set autogain target to %d, status: %d", val, err); - - return err; -} diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h deleted file mode 100644 index 5071e5353fd3..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * 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 - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#ifndef STV06XX_PB0100_H_ -#define STV06XX_PB0100_H_ - -#include "stv06xx_sensor.h" - -/* mode priv field flags */ -#define PB0100_CROP_TO_VGA 0x01 -#define PB0100_SUBSAMPLE 0x02 - -/* I2C Registers */ -#define PB_IDENT 0x00 /* Chip Version */ -#define PB_RSTART 0x01 /* Row Window Start */ -#define PB_CSTART 0x02 /* Column Window Start */ -#define PB_RWSIZE 0x03 /* Row Window Size */ -#define PB_CWSIZE 0x04 /* Column Window Size */ -#define PB_CFILLIN 0x05 /* Column Fill-In */ -#define PB_VBL 0x06 /* Vertical Blank Count */ -#define PB_CONTROL 0x07 /* Control Mode */ -#define PB_FINTTIME 0x08 /* Integration Time/Frame Unit Count */ -#define PB_RINTTIME 0x09 /* Integration Time/Row Unit Count */ -#define PB_ROWSPEED 0x0a /* Row Speed Control */ -#define PB_ABORTFRAME 0x0b /* Abort Frame */ -#define PB_R12 0x0c /* Reserved */ -#define PB_RESET 0x0d /* Reset */ -#define PB_EXPGAIN 0x0e /* Exposure Gain Command */ -#define PB_R15 0x0f /* Expose0 */ -#define PB_R16 0x10 /* Expose1 */ -#define PB_R17 0x11 /* Expose2 */ -#define PB_R18 0x12 /* Low0_DAC */ -#define PB_R19 0x13 /* Low1_DAC */ -#define PB_R20 0x14 /* Low2_DAC */ -#define PB_R21 0x15 /* Threshold11 */ -#define PB_R22 0x16 /* Threshold0x */ -#define PB_UPDATEINT 0x17 /* Update Interval */ -#define PB_R24 0x18 /* High_DAC */ -#define PB_R25 0x19 /* Trans0H */ -#define PB_R26 0x1a /* Trans1L */ -#define PB_R27 0x1b /* Trans1H */ -#define PB_R28 0x1c /* Trans2L */ -#define PB_R29 0x1d /* Reserved */ -#define PB_R30 0x1e /* Reserved */ -#define PB_R31 0x1f /* Wait to Read */ -#define PB_PREADCTRL 0x20 /* Pixel Read Control Mode */ -#define PB_R33 0x21 /* IREF_VLN */ -#define PB_R34 0x22 /* IREF_VLP */ -#define PB_R35 0x23 /* IREF_VLN_INTEG */ -#define PB_R36 0x24 /* IREF_MASTER */ -#define PB_R37 0x25 /* IDACP */ -#define PB_R38 0x26 /* IDACN */ -#define PB_R39 0x27 /* DAC_Control_Reg */ -#define PB_R40 0x28 /* VCL */ -#define PB_R41 0x29 /* IREF_VLN_ADCIN */ -#define PB_R42 0x2a /* Reserved */ -#define PB_G1GAIN 0x2b /* Green 1 Gain */ -#define PB_BGAIN 0x2c /* Blue Gain */ -#define PB_RGAIN 0x2d /* Red Gain */ -#define PB_G2GAIN 0x2e /* Green 2 Gain */ -#define PB_R47 0x2f /* Dark Row Address */ -#define PB_R48 0x30 /* Dark Row Options */ -#define PB_R49 0x31 /* Reserved */ -#define PB_R50 0x32 /* Image Test Data */ -#define PB_ADCMAXGAIN 0x33 /* Maximum Gain */ -#define PB_ADCMINGAIN 0x34 /* Minimum Gain */ -#define PB_ADCGLOBALGAIN 0x35 /* Global Gain */ -#define PB_R54 0x36 /* Maximum Frame */ -#define PB_R55 0x37 /* Minimum Frame */ -#define PB_R56 0x38 /* Reserved */ -#define PB_VOFFSET 0x39 /* VOFFSET */ -#define PB_R58 0x3a /* Snap-Shot Sequence Trigger */ -#define PB_ADCGAINH 0x3b /* VREF_HI */ -#define PB_ADCGAINL 0x3c /* VREF_LO */ -#define PB_R61 0x3d /* Reserved */ -#define PB_R62 0x3e /* Reserved */ -#define PB_R63 0x3f /* Reserved */ -#define PB_R64 0x40 /* Red/Blue Gain */ -#define PB_R65 0x41 /* Green 2/Green 1 Gain */ -#define PB_R66 0x42 /* VREF_HI/LO */ -#define PB_R67 0x43 /* Integration Time/Row Unit Count */ -#define PB_R240 0xf0 /* ADC Test */ -#define PB_R241 0xf1 /* Chip Enable */ -#define PB_R242 0xf2 /* Reserved */ - -static int pb0100_probe(struct sd *sd); -static int pb0100_start(struct sd *sd); -static int pb0100_init(struct sd *sd); -static int pb0100_init_controls(struct sd *sd); -static int pb0100_stop(struct sd *sd); -static int pb0100_dump(struct sd *sd); - -/* V4L2 controls supported by the driver */ -static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); -static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); -static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val); -static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val); - -const struct stv06xx_sensor stv06xx_sensor_pb0100 = { - .name = "PB-0100", - .i2c_flush = 1, - .i2c_addr = 0xba, - .i2c_len = 2, - - .min_packet_size = { 635, 847 }, - .max_packet_size = { 847, 923 }, - - .init = pb0100_init, - .init_controls = pb0100_init_controls, - .probe = pb0100_probe, - .start = pb0100_start, - .stop = pb0100_stop, - .dump = pb0100_dump, -}; - -#endif diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h deleted file mode 100644 index 3a498c2495c6..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * 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 - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#ifndef STV06XX_SENSOR_H_ -#define STV06XX_SENSOR_H_ - -#include "stv06xx.h" - -#define IS_1020(sd) ((sd)->sensor == &stv06xx_sensor_hdcs1020) - -extern const struct stv06xx_sensor stv06xx_sensor_vv6410; -extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00; -extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020; -extern const struct stv06xx_sensor stv06xx_sensor_pb0100; -extern const struct stv06xx_sensor stv06xx_sensor_st6422; - -struct stv06xx_sensor { - /* Defines the name of a sensor */ - char name[32]; - - /* Sensor i2c address */ - u8 i2c_addr; - - /* Flush value*/ - u8 i2c_flush; - - /* length of an i2c word */ - u8 i2c_len; - - /* Isoc packet size (per mode) */ - int min_packet_size[4]; - int max_packet_size[4]; - - /* Probes if the sensor is connected */ - int (*probe)(struct sd *sd); - - /* Performs a initialization sequence */ - int (*init)(struct sd *sd); - - /* Initializes the controls */ - int (*init_controls)(struct sd *sd); - - /* Reads a sensor register */ - int (*read_sensor)(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - - /* Writes to a sensor register */ - int (*write_sensor)(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - - /* Instructs the sensor to start streaming */ - int (*start)(struct sd *sd); - - /* Instructs the sensor to stop streaming */ - int (*stop)(struct sd *sd); - - /* Instructs the sensor to dump all its contents */ - int (*dump)(struct sd *sd); -}; - -#endif diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c deleted file mode 100644 index 8a57990dfe0f..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Support for the sensor part which is integrated (I think) into the - * st6422 stv06xx alike bridge, as its integrated there are no i2c writes - * but instead direct bridge writes. - * - * Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com> - * - * Strongly based on qc-usb-messenger, which is: - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * - * 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 - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "stv06xx_st6422.h" - -static struct v4l2_pix_format st6422_mode[] = { - /* Note we actually get 124 lines of data, of which we skip the 4st - 4 as they are garbage */ - { - 162, - 120, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 162 * 120, - .bytesperline = 162, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - }, - /* Note we actually get 248 lines of data, of which we skip the 4st - 4 as they are garbage, and we tell the app it only gets the - first 240 of the 244 lines it actually gets, so that it ignores - the last 4. */ - { - 324, - 240, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 324 * 244, - .bytesperline = 324, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - }, -}; - -/* V4L2 controls supported by the driver */ -static int setbrightness(struct sd *sd, s32 val); -static int setcontrast(struct sd *sd, s32 val); -static int setgain(struct sd *sd, u8 gain); -static int setexposure(struct sd *sd, s16 expo); - -static int st6422_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; - int err = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - err = setbrightness(sd, ctrl->val); - break; - case V4L2_CID_CONTRAST: - err = setcontrast(sd, ctrl->val); - break; - case V4L2_CID_GAIN: - err = setgain(sd, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - err = setexposure(sd, ctrl->val); - break; - } - - /* commit settings */ - if (err >= 0) - err = stv06xx_write_bridge(sd, 0x143f, 0x01); - sd->gspca_dev.usb_err = err; - return err; -} - -static const struct v4l2_ctrl_ops st6422_ctrl_ops = { - .s_ctrl = st6422_s_ctrl, -}; - -static int st6422_init_controls(struct sd *sd) -{ - struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; - - v4l2_ctrl_handler_init(hdl, 4); - v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 31, 1, 3); - v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops, - V4L2_CID_CONTRAST, 0, 15, 1, 11); - v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 1023, 1, 256); - v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops, - V4L2_CID_GAIN, 0, 255, 1, 64); - - return hdl->error; -} - -static int st6422_probe(struct sd *sd) -{ - if (sd->bridge != BRIDGE_ST6422) - return -ENODEV; - - pr_info("st6422 sensor detected\n"); - - sd->gspca_dev.cam.cam_mode = st6422_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode); - return 0; -} - -static int st6422_init(struct sd *sd) -{ - int err = 0, i; - - const u16 st6422_bridge_init[][2] = { - { STV_ISO_ENABLE, 0x00 }, /* disable capture */ - { 0x1436, 0x00 }, - { 0x1432, 0x03 }, /* 0x00-0x1F brightness */ - { 0x143a, 0xf9 }, /* 0x00-0x0F contrast */ - { 0x0509, 0x38 }, /* R */ - { 0x050a, 0x38 }, /* G */ - { 0x050b, 0x38 }, /* B */ - { 0x050c, 0x2a }, - { 0x050d, 0x01 }, - - - { 0x1431, 0x00 }, /* 0x00-0x07 ??? */ - { 0x1433, 0x34 }, /* 160x120, 0x00-0x01 night filter */ - { 0x1438, 0x18 }, /* 640x480 */ -/* 18 bayes */ -/* 10 compressed? */ - - { 0x1439, 0x00 }, -/* anti-noise? 0xa2 gives a perfect image */ - - { 0x143b, 0x05 }, - { 0x143c, 0x00 }, /* 0x00-0x01 - ??? */ - - -/* shutter time 0x0000-0x03FF */ -/* low value give good picures on moving objects (but requires much light) */ -/* high value gives good picures in darkness (but tends to be overexposed) */ - { 0x143e, 0x01 }, - { 0x143d, 0x00 }, - - { 0x1442, 0xe2 }, -/* write: 1x1x xxxx */ -/* read: 1x1x xxxx */ -/* bit 5 == button pressed and hold if 0 */ -/* write 0xe2,0xea */ - -/* 0x144a */ -/* 0x00 init */ -/* bit 7 == button has been pressed, but not handled */ - -/* interrupt */ -/* if(urb->iso_frame_desc[i].status == 0x80) { */ -/* if(urb->iso_frame_desc[i].status == 0x88) { */ - - { 0x1500, 0xd0 }, - { 0x1500, 0xd0 }, - { 0x1500, 0x50 }, /* 0x00 - 0xFF 0x80 == compr ? */ - - { 0x1501, 0xaf }, -/* high val-> light area gets darker */ -/* low val -> light area gets lighter */ - { 0x1502, 0xc2 }, -/* high val-> light area gets darker */ -/* low val -> light area gets lighter */ - { 0x1503, 0x45 }, -/* high val-> light area gets darker */ -/* low val -> light area gets lighter */ - { 0x1505, 0x02 }, -/* 2 : 324x248 80352 bytes */ -/* 7 : 248x162 40176 bytes */ -/* c+f: 162*124 20088 bytes */ - - { 0x150e, 0x8e }, - { 0x150f, 0x37 }, - { 0x15c0, 0x00 }, - { 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */ - - - { 0x143f, 0x01 }, /* commit settings */ - - }; - - for (i = 0; i < ARRAY_SIZE(st6422_bridge_init) && !err; i++) { - err = stv06xx_write_bridge(sd, st6422_bridge_init[i][0], - st6422_bridge_init[i][1]); - } - - return err; -} - -static int setbrightness(struct sd *sd, s32 val) -{ - /* val goes from 0 -> 31 */ - return stv06xx_write_bridge(sd, 0x1432, val); -} - -static int setcontrast(struct sd *sd, s32 val) -{ - /* Val goes from 0 -> 15 */ - return stv06xx_write_bridge(sd, 0x143a, val | 0xf0); -} - -static int setgain(struct sd *sd, u8 gain) -{ - int err; - - /* Set red, green, blue, gain */ - err = stv06xx_write_bridge(sd, 0x0509, gain); - if (err < 0) - return err; - - err = stv06xx_write_bridge(sd, 0x050a, gain); - if (err < 0) - return err; - - err = stv06xx_write_bridge(sd, 0x050b, gain); - if (err < 0) - return err; - - /* 2 mystery writes */ - err = stv06xx_write_bridge(sd, 0x050c, 0x2a); - if (err < 0) - return err; - - return stv06xx_write_bridge(sd, 0x050d, 0x01); -} - -static int setexposure(struct sd *sd, s16 expo) -{ - int err; - - err = stv06xx_write_bridge(sd, 0x143d, expo & 0xff); - if (err < 0) - return err; - - return stv06xx_write_bridge(sd, 0x143e, expo >> 8); -} - -static int st6422_start(struct sd *sd) -{ - int err; - struct cam *cam = &sd->gspca_dev.cam; - - if (cam->cam_mode[sd->gspca_dev.curr_mode].priv) - err = stv06xx_write_bridge(sd, 0x1505, 0x0f); - else - err = stv06xx_write_bridge(sd, 0x1505, 0x02); - if (err < 0) - return err; - - /* commit settings */ - err = stv06xx_write_bridge(sd, 0x143f, 0x01); - return (err < 0) ? err : 0; -} - -static int st6422_stop(struct sd *sd) -{ - PDEBUG(D_STREAM, "Halting stream"); - - return 0; -} diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h deleted file mode 100644 index 8f20fbf30f33..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Support for the sensor part which is integrated (I think) into the - * st6422 stv06xx alike bridge, as its integrated there are no i2c writes - * but instead direct bridge writes. - * - * Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com> - * - * Strongly based on qc-usb-messenger, which is: - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * - * 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 - * - */ - -#ifndef STV06XX_ST6422_H_ -#define STV06XX_ST6422_H_ - -#include "stv06xx_sensor.h" - -static int st6422_probe(struct sd *sd); -static int st6422_start(struct sd *sd); -static int st6422_init(struct sd *sd); -static int st6422_init_controls(struct sd *sd); -static int st6422_stop(struct sd *sd); - -const struct stv06xx_sensor stv06xx_sensor_st6422 = { - .name = "ST6422", - /* No known way to lower framerate in case of less bandwidth */ - .min_packet_size = { 300, 847 }, - .max_packet_size = { 300, 847 }, - .init = st6422_init, - .init_controls = st6422_init_controls, - .probe = st6422_probe, - .start = st6422_start, - .stop = st6422_stop, -}; - -#endif diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c deleted file mode 100644 index 748e1421d6d8..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * 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 - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "stv06xx_vv6410.h" - -static struct v4l2_pix_format vv6410_mode[] = { - { - 356, - 292, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 356 * 292, - .bytesperline = 356, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - } -}; - -static int vv6410_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - int err = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_HFLIP: - err = vv6410_set_hflip(gspca_dev, ctrl->val); - break; - case V4L2_CID_VFLIP: - err = vv6410_set_vflip(gspca_dev, ctrl->val); - break; - case V4L2_CID_GAIN: - err = vv6410_set_analog_gain(gspca_dev, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - err = vv6410_set_exposure(gspca_dev, ctrl->val); - break; - } - return err; -} - -static const struct v4l2_ctrl_ops vv6410_ctrl_ops = { - .s_ctrl = vv6410_s_ctrl, -}; - -static int vv6410_probe(struct sd *sd) -{ - u16 data; - int err; - - err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data); - if (err < 0) - return -ENODEV; - - if (data != 0x19) - return -ENODEV; - - pr_info("vv6410 sensor detected\n"); - - sd->gspca_dev.cam.cam_mode = vv6410_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode); - return 0; -} - -static int vv6410_init_controls(struct sd *sd) -{ - struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; - - v4l2_ctrl_handler_init(hdl, 4); - v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); - v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 32768, 1, 20000); - v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops, - V4L2_CID_GAIN, 0, 15, 1, 10); - return hdl->error; -} - -static int vv6410_init(struct sd *sd) -{ - int err = 0, i; - - for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) - stv06xx_write_bridge(sd, stv_bridge_init[i].addr, stv_bridge_init[i].data); - - if (err < 0) - return err; - - err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, - ARRAY_SIZE(vv6410_sensor_init)); - return (err < 0) ? err : 0; -} - -static int vv6410_start(struct sd *sd) -{ - int err; - struct cam *cam = &sd->gspca_dev.cam; - u32 priv = cam->cam_mode[sd->gspca_dev.curr_mode].priv; - - if (priv & VV6410_SUBSAMPLE) { - PDEBUG(D_CONF, "Enabling subsampling"); - stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); - stv06xx_write_bridge(sd, STV_X_CTRL, 0x06); - - stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10); - } else { - stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01); - stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a); - stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x00); - - } - - /* Turn on LED */ - err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_ON); - if (err < 0) - return err; - - err = stv06xx_write_sensor(sd, VV6410_SETUP0, 0); - if (err < 0) - return err; - - PDEBUG(D_STREAM, "Starting stream"); - - return 0; -} - -static int vv6410_stop(struct sd *sd) -{ - int err; - - /* Turn off LED */ - err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_OFF); - if (err < 0) - return err; - - err = stv06xx_write_sensor(sd, VV6410_SETUP0, VV6410_LOW_POWER_MODE); - if (err < 0) - return err; - - PDEBUG(D_STREAM, "Halting stream"); - - return (err < 0) ? err : 0; -} - -static int vv6410_dump(struct sd *sd) -{ - u8 i; - int err = 0; - - pr_info("Dumping all vv6410 sensor registers\n"); - for (i = 0; i < 0xff && !err; i++) { - u16 data; - err = stv06xx_read_sensor(sd, i, &data); - pr_info("Register 0x%x contained 0x%x\n", i, data); - } - return (err < 0) ? err : 0; -} - -static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u16 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); - if (err < 0) - return err; - - if (val) - i2c_data |= VV6410_HFLIP; - else - i2c_data &= ~VV6410_HFLIP; - - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); - err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data); - - return (err < 0) ? err : 0; -} - -static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u16 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); - if (err < 0) - return err; - - if (val) - i2c_data |= VV6410_VFLIP; - else - i2c_data &= ~VV6410_VFLIP; - - PDEBUG(D_V4L2, "Set vertical flip to %d", val); - err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data); - - return (err < 0) ? err : 0; -} - -static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(D_V4L2, "Set analog gain to %d", val); - err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf)); - - return (err < 0) ? err : 0; -} - -static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - unsigned int fine, coarse; - - val = (val * val >> 14) + val / 4; - - fine = val % VV6410_CIF_LINELENGTH; - coarse = min(512, val / VV6410_CIF_LINELENGTH); - - PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d", - coarse, fine); - - err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8); - if (err < 0) - goto out; - - err = stv06xx_write_sensor(sd, VV6410_FINEL, fine & 0xff); - if (err < 0) - goto out; - - err = stv06xx_write_sensor(sd, VV6410_COARSEH, coarse >> 8); - if (err < 0) - goto out; - - err = stv06xx_write_sensor(sd, VV6410_COARSEL, coarse & 0xff); - -out: - return err; -} diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h deleted file mode 100644 index 53e67b40ca05..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * 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 - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#ifndef STV06XX_VV6410_H_ -#define STV06XX_VV6410_H_ - -#include "stv06xx_sensor.h" - -#define VV6410_COLS 416 -#define VV6410_ROWS 320 - -/* Status registers */ -/* Chip identification number including revision indicator */ -#define VV6410_DEVICEH 0x00 -#define VV6410_DEVICEL 0x01 - -/* User can determine whether timed I2C data - has been consumed by interrogating flag states */ -#define VV6410_STATUS0 0x02 - -/* Current line counter value */ -#define VV6410_LINECOUNTH 0x03 -#define VV6410_LINECOUNTL 0x04 - -/* End x coordinate of image size */ -#define VV6410_XENDH 0x05 -#define VV6410_XENDL 0x06 - -/* End y coordinate of image size */ -#define VV6410_YENDH 0x07 -#define VV6410_YENDL 0x08 - -/* This is the average pixel value returned from the - dark line offset cancellation algorithm */ -#define VV6410_DARKAVGH 0x09 -#define VV6410_DARKAVGL 0x0a - -/* This is the average pixel value returned from the - black line offset cancellation algorithm */ -#define VV6410_BLACKAVGH 0x0b -#define VV6410_BLACKAVGL 0x0c - -/* Flags to indicate whether the x or y image coordinates have been clipped */ -#define VV6410_STATUS1 0x0d - -/* Setup registers */ - -/* Low-power/sleep modes & video timing */ -#define VV6410_SETUP0 0x10 - -/* Various parameters */ -#define VV6410_SETUP1 0x11 - -/* Contains pixel counter reset value used by external sync */ -#define VV6410_SYNCVALUE 0x12 - -/* Frame grabbing modes (FST, LST and QCK) */ -#define VV6410_FGMODES 0x14 - -/* FST and QCK mapping modes. */ -#define VV6410_PINMAPPING 0x15 - -/* Data resolution */ -#define VV6410_DATAFORMAT 0x16 - -/* Output coding formats */ -#define VV6410_OPFORMAT 0x17 - -/* Various mode select bits */ -#define VV6410_MODESELECT 0x18 - -/* Exposure registers */ -/* Fine exposure. */ -#define VV6410_FINEH 0x20 -#define VV6410_FINEL 0x21 - -/* Coarse exposure */ -#define VV6410_COARSEH 0x22 -#define VV6410_COARSEL 0x23 - -/* Analog gain setting */ -#define VV6410_ANALOGGAIN 0x24 - -/* Clock division */ -#define VV6410_CLKDIV 0x25 - -/* Dark line offset cancellation value */ -#define VV6410_DARKOFFSETH 0x2c -#define VV6410_DARKOFFSETL 0x2d - -/* Dark line offset cancellation enable */ -#define VV6410_DARKOFFSETSETUP 0x2e - -/* Video timing registers */ -/* Line Length (Pixel Clocks) */ -#define VV6410_LINELENGTHH 0x52 -#define VV6410_LINELENGTHL 0x53 - -/* X-co-ordinate of top left corner of region of interest (x-offset) */ -#define VV6410_XOFFSETH 0x57 -#define VV6410_XOFFSETL 0x58 - -/* Y-coordinate of top left corner of region of interest (y-offset) */ -#define VV6410_YOFFSETH 0x59 -#define VV6410_YOFFSETL 0x5a - -/* Field length (Lines) */ -#define VV6410_FIELDLENGTHH 0x61 -#define VV6410_FIELDLENGTHL 0x62 - -/* System registers */ -/* Black offset cancellation default value */ -#define VV6410_BLACKOFFSETH 0x70 -#define VV6410_BLACKOFFSETL 0x71 - -/* Black offset cancellation setup */ -#define VV6410_BLACKOFFSETSETUP 0x72 - -/* Analog Control Register 0 */ -#define VV6410_CR0 0x75 - -/* Analog Control Register 1 */ -#define VV6410_CR1 0x76 - -/* ADC Setup Register */ -#define VV6410_AS0 0x77 - -/* Analog Test Register */ -#define VV6410_AT0 0x78 - -/* Audio Amplifier Setup Register */ -#define VV6410_AT1 0x79 - -#define VV6410_HFLIP (1 << 3) -#define VV6410_VFLIP (1 << 4) - -#define VV6410_LOW_POWER_MODE (1 << 0) -#define VV6410_SOFT_RESET (1 << 2) -#define VV6410_PAL_25_FPS (0 << 3) - -#define VV6410_CLK_DIV_2 (1 << 1) - -#define VV6410_FINE_EXPOSURE 320 -#define VV6410_COARSE_EXPOSURE 192 -#define VV6410_DEFAULT_GAIN 5 - -#define VV6410_SUBSAMPLE 0x01 -#define VV6410_CROP_TO_QVGA 0x02 - -#define VV6410_CIF_LINELENGTH 415 - -static int vv6410_probe(struct sd *sd); -static int vv6410_start(struct sd *sd); -static int vv6410_init(struct sd *sd); -static int vv6410_init_controls(struct sd *sd); -static int vv6410_stop(struct sd *sd); -static int vv6410_dump(struct sd *sd); - -/* V4L2 controls supported by the driver */ -static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); -static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val); - -const struct stv06xx_sensor stv06xx_sensor_vv6410 = { - .name = "ST VV6410", - .i2c_flush = 5, - .i2c_addr = 0x20, - .i2c_len = 1, - /* FIXME (see if we can lower packet_size-s, needs testing, and also - adjusting framerate when the bandwidth gets lower) */ - .min_packet_size = { 1023 }, - .max_packet_size = { 1023 }, - .init = vv6410_init, - .init_controls = vv6410_init_controls, - .probe = vv6410_probe, - .start = vv6410_start, - .stop = vv6410_stop, - .dump = vv6410_dump, -}; - -/* If NULL, only single value to write, stored in len */ -struct stv_init { - u16 addr; - u8 data; -}; - -static const struct stv_init stv_bridge_init[] = { - /* This reg is written twice. Some kind of reset? */ - {STV_RESET, 0x80}, - {STV_RESET, 0x00}, - {STV_SCAN_RATE, 0x00}, - {STV_I2C_FLUSH, 0x04}, - {STV_REG00, 0x0b}, - {STV_REG01, 0xa7}, - {STV_REG02, 0xb7}, - {STV_REG03, 0x00}, - {STV_REG04, 0x00}, - {0x1536, 0x02}, - {0x1537, 0x00}, - {0x1538, 0x60}, - {0x1539, 0x01}, - {0x153a, 0x20}, - {0x153b, 0x01}, -}; - -static const u8 vv6410_sensor_init[][2] = { - /* Setup registers */ - {VV6410_SETUP0, VV6410_SOFT_RESET}, - {VV6410_SETUP0, VV6410_LOW_POWER_MODE}, - /* Use shuffled read-out mode */ - {VV6410_SETUP1, BIT(6)}, - /* All modes to 1, FST, Fast QCK, Free running QCK, Free running LST, FST will qualify visible pixels */ - {VV6410_FGMODES, BIT(6) | BIT(4) | BIT(2) | BIT(0)}, - {VV6410_PINMAPPING, 0x00}, - /* Pre-clock generator divide off */ - {VV6410_DATAFORMAT, BIT(7) | BIT(0)}, - - {VV6410_CLKDIV, VV6410_CLK_DIV_2}, - - /* System registers */ - /* Enable voltage doubler */ - {VV6410_AS0, BIT(6) | BIT(4) | BIT(3) | BIT(2) | BIT(1)}, - {VV6410_AT0, 0x00}, - /* Power up audio, differential */ - {VV6410_AT1, BIT(4) | BIT(0)}, -}; - -#endif |