summaryrefslogtreecommitdiff
path: root/linux/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers')
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_net.c8
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvbdev.c6
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dw2102.h2
-rw-r--r--linux/drivers/media/dvb/siano/smscoreapi.c14
-rw-r--r--linux/drivers/media/dvb/siano/smsdvb.c4
-rw-r--r--linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c25
-rw-r--r--linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c4
-rw-r--r--linux/drivers/media/video/cpia2/cpia2_core.c54
-rw-r--r--linux/drivers/media/video/dabusb.c74
-rw-r--r--linux/drivers/media/video/gspca/sonixb.c353
-rw-r--r--linux/drivers/media/video/usbvideo/vicam.c37
11 files changed, 293 insertions, 288 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c
index 3c0106f65..e0d60cdc4 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1165,7 +1165,11 @@ static void wq_set_multicast_list (struct work_struct *work)
#ifdef OLD_XMIT_LOCK /* Kernels equal or lower than 2.6.17 */
spin_lock_bh(&dev->xmit_lock);
#else
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
netif_tx_lock_bh(dev);
+#else
+ netif_addr_lock_bh(dev);
+#endif
#endif
if (dev->flags & IFF_PROMISC) {
@@ -1194,7 +1198,11 @@ static void wq_set_multicast_list (struct work_struct *work)
#ifdef OLD_XMIT_LOCK /* Kernels equal or lower than 2.6.17 */
spin_unlock_bh(&dev->xmit_lock);
#else
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
netif_tx_unlock_bh(dev);
+#else
+ netif_addr_unlock_bh(dev);
+#endif
#endif
dvb_net_feed_start(dev);
}
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c
index e6d20310a..0820da504 100644
--- a/linux/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c
@@ -242,9 +242,15 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
mutex_unlock(&dvbdev_register_lock);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
+ clsdev = device_create_drvdata(dvb_class, adap->device,
+ MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
+ NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
+#else
clsdev = device_create(dvb_class, adap->device,
MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
"dvb%d.%s%d", adap->num, dnames[type], id);
+#endif
if (IS_ERR(clsdev)) {
printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
__func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
diff --git a/linux/drivers/media/dvb/dvb-usb/dw2102.h b/linux/drivers/media/dvb/dvb-usb/dw2102.h
index cb5873752..7a310f906 100644
--- a/linux/drivers/media/dvb/dvb-usb/dw2102.h
+++ b/linux/drivers/media/dvb/dvb-usb/dw2102.h
@@ -2,7 +2,7 @@
#define _DW2102_H_
#define DVB_USB_LOG_PREFIX "dw2102"
-#include <dvb-usb.h>
+#include "dvb-usb.h"
extern int dvb_usb_dw2102_debug;
#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args)
diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c
index d8c7304b2..4781997f6 100644
--- a/linux/drivers/media/dvb/siano/smscoreapi.c
+++ b/linux/drivers/media/dvb/siano/smscoreapi.c
@@ -110,12 +110,12 @@ struct smscore_registry_entry_t {
enum sms_device_type_st type;
};
-struct list_head g_smscore_notifyees;
-struct list_head g_smscore_devices;
-struct mutex g_smscore_deviceslock;
+static struct list_head g_smscore_notifyees;
+static struct list_head g_smscore_devices;
+static struct mutex g_smscore_deviceslock;
-struct list_head g_smscore_registry;
-struct mutex g_smscore_registrylock;
+static struct list_head g_smscore_registry;
+static struct mutex g_smscore_registrylock;
static int default_mode = 4;
@@ -1248,7 +1248,7 @@ static int smscore_map_common_buffer(struct smscore_device_t *coredev,
}
#endif
-int smscore_module_init(void)
+static int __init smscore_module_init(void)
{
int rc = 0;
@@ -1270,7 +1270,7 @@ int smscore_module_init(void)
return rc;
}
-void smscore_module_exit(void)
+static void __exit smscore_module_exit(void)
{
kmutex_lock(&g_smscore_deviceslock);
diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c
index 2da99f19e..e64478b4e 100644
--- a/linux/drivers/media/dvb/siano/smsdvb.c
+++ b/linux/drivers/media/dvb/siano/smsdvb.c
@@ -27,8 +27,8 @@
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-struct list_head g_smsdvb_clients;
-struct mutex g_smsdvb_clientslock;
+static struct list_head g_smsdvb_clients;
+static struct mutex g_smsdvb_clientslock;
static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
{
diff --git a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 133648277..ceae085cb 100644
--- a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -21,6 +21,9 @@
#include <linux/jiffies.h>
#include "compat.h"
#include <linux/mutex.h>
+#ifdef TTUSB_KERNEL
+#include <linux/firmware.h>
+#endif
#include "dvb_frontend.h"
#include "dmxdev.h"
@@ -287,13 +290,27 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num
return i;
}
+#ifndef TTUSB_KERNEL
#include "dvb-ttusb-dspbootcode.h"
+#endif
static int ttusb_boot_dsp(struct ttusb *ttusb)
{
+#ifdef TTUSB_KERNEL
+ const struct firmware *fw;
+#endif
int i, err;
u8 b[40];
+#ifdef TTUSB_KERNEL
+ err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin",
+ &ttusb->dev->dev);
+ if (err) {
+ printk(KERN_ERR "ttusb-budget: failed to request firmware\n");
+ return err;
+ }
+
+#endif
/* BootBlock */
b[0] = 0xaa;
b[2] = 0x13;
@@ -301,8 +318,13 @@ static int ttusb_boot_dsp(struct ttusb *ttusb)
/* upload dsp code in 32 byte steps (36 didn't work for me ...) */
/* 32 is max packet size, no messages should be splitted. */
+#ifndef TTUSB_KERNEL
for (i = 0; i < sizeof(dsp_bootcode); i += 28) {
memcpy(&b[4], &dsp_bootcode[i], 28);
+#else
+ for (i = 0; i < fw->size; i += 28) {
+ memcpy(&b[4], &fw->data[i], 28);
+#endif
b[1] = ++ttusb->c;
@@ -1809,3 +1831,6 @@ module_exit(ttusb_exit);
MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
MODULE_DESCRIPTION("TTUSB DVB Driver");
MODULE_LICENSE("GPL");
+#ifdef TTUSB_KERNEL
+MODULE_FIRMWARE("ttusb-budget/dspbootcode.bin");
+#endif
diff --git a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 8491913aa..0fdcb19cb 100644
--- a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1284,7 +1284,11 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
u8 b1[] = { 0x61 };
u8 *b;
char idstring[21];
+#ifndef TTUSB_KERNEL
u8 *firmware = NULL;
+#else
+ const u8 *firmware = NULL;
+#endif
size_t firmware_size = 0;
u16 firmware_csum = 0;
__be16 firmware_csum_ns;
diff --git a/linux/drivers/media/video/cpia2/cpia2_core.c b/linux/drivers/media/video/cpia2/cpia2_core.c
index c8b9fdb70..eab48dfd0 100644
--- a/linux/drivers/media/video/cpia2/cpia2_core.c
+++ b/linux/drivers/media/video/cpia2/cpia2_core.c
@@ -33,11 +33,16 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include <linux/firmware.h>
+#endif
/* #define _CPIA2_DEBUG_ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
#include "cpia2patch.h"
+#endif
#ifdef _CPIA2_DEBUG_
static const char *block_name[] = {
@@ -893,14 +898,42 @@ int cpia2_set_low_power(struct camera_data *cam)
* apply_vp_patch
*
*****************************************************************************/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+static int cpia2_send_onebyte_command(struct camera_data *cam,
+ struct cpia2_command *cmd,
+ u8 start, u8 datum)
+{
+ cmd->buffer.block_data[0] = datum;
+ cmd->start = start;
+ cmd->reg_count = 1;
+ return cpia2_send_command(cam, cmd);
+}
+
+#endif
static int apply_vp_patch(struct camera_data *cam)
{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
int i, j;
+#else
+ const struct firmware *fw;
+ const char fw_name[] = "cpia2/stv0672_vp4.bin";
+ int i, ret;
+#endif
struct cpia2_command cmd;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ ret = request_firmware(&fw, fw_name, &cam->dev->dev);
+ if (ret) {
+ printk(KERN_ERR "cpia2: failed to load VP patch \"%s\"\n",
+ fw_name);
+ return ret;
+ }
+
+#endif
cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP;
cmd.direction = TRANSFER_WRITE;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
for (i = 0; i < PATCH_DATA_SIZE; i++) {
for (j = 0; j < patch_data[i].count; j++) {
cmd.buffer.block_data[j] = patch_data[i].data[j];
@@ -908,9 +941,30 @@ static int apply_vp_patch(struct camera_data *cam)
cmd.start = patch_data[i].reg;
cmd.reg_count = patch_data[i].count;
+#else
+ /* First send the start address... */
+ cpia2_send_onebyte_command(cam, &cmd, 0x0A, fw->data[0]); /* hi */
+ cpia2_send_onebyte_command(cam, &cmd, 0x0B, fw->data[1]); /* lo */
+
+ /* ... followed by the data payload */
+ for (i = 2; i < fw->size; i += 64) {
+ cmd.start = 0x0C; /* Data */
+ cmd.reg_count = min_t(int, 64, fw->size - i);
+ memcpy(cmd.buffer.block_data, &fw->data[i], cmd.reg_count);
+#endif
cpia2_send_command(cam, &cmd);
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ /* Next send the start address... */
+ cpia2_send_onebyte_command(cam, &cmd, 0x0A, fw->data[0]); /* hi */
+ cpia2_send_onebyte_command(cam, &cmd, 0x0B, fw->data[1]); /* lo */
+
+ /* ... followed by the 'goto' command */
+ cpia2_send_onebyte_command(cam, &cmd, 0x0D, 1);
+
+ release_firmware(fw);
+#endif
return 0;
}
diff --git a/linux/drivers/media/video/dabusb.c b/linux/drivers/media/video/dabusb.c
index 72bf5868c..f23e6b84d 100644
--- a/linux/drivers/media/video/dabusb.c
+++ b/linux/drivers/media/video/dabusb.c
@@ -39,9 +39,15 @@
#include <linux/usb.h>
#include "compat.h"
#include <linux/mutex.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include <linux/firmware.h>
+#include <linux/ihex.h>
+#endif
#include "dabusb.h"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
#include "dabfirmware.h"
+#endif
/*
* Version Information
@@ -302,7 +308,12 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
return ret;
}
/* --------------------------------------------------------------------- */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
static int dabusb_writemem (pdabusb_t s, int pos, unsigned char *data, int len)
+#else
+static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data,
+ int len)
+#endif
{
int ret;
unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL);
@@ -329,24 +340,63 @@ static int dabusb_8051_reset (pdabusb_t s, unsigned char reset_bit)
static int dabusb_loadmem (pdabusb_t s, const char *fname)
{
int ret;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
PINTEL_HEX_RECORD ptr = firmware;
+#else
+ const struct ihex_binrec *rec;
+ const struct firmware *fw;
+#endif
dbg("Enter dabusb_loadmem (internal)");
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev);
+ if (ret) {
+ err("Failed to load \"dabusb/firmware.fw\": %d\n", ret);
+ goto out;
+ }
+#endif
ret = dabusb_8051_reset (s, 1);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
while (ptr->Type == 0) {
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
dbg("dabusb_writemem: %04X %p %d)", ptr->Address, ptr->Data, ptr->Length);
+#else
+ for (rec = (const struct ihex_binrec *)fw->data; rec;
+ rec = ihex_next_binrec(rec)) {
+ dbg("dabusb_writemem: %04X %p %d)", be32_to_cpu(rec->addr),
+ rec->data, be16_to_cpu(rec->len));
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
ret = dabusb_writemem (s, ptr->Address, ptr->Data, ptr->Length);
+#else
+ ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data,
+ be16_to_cpu(rec->len));
+#endif
if (ret < 0) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
err("dabusb_writemem failed (%d %04X %p %d)", ret, ptr->Address, ptr->Data, ptr->Length);
+#else
+ err("dabusb_writemem failed (%d %04X %p %d)", ret,
+ be32_to_cpu(rec->addr), rec->data,
+ be16_to_cpu(rec->len));
+#endif
break;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
ptr++;
+#endif
}
ret = dabusb_8051_reset (s, 0);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+#else
+ release_firmware(fw);
+ out:
+#endif
dbg("dabusb_loadmem: exit");
return ret;
@@ -381,9 +431,14 @@ static int dabusb_fpga_init (pdabusb_t s, pbulk_transfer_t b)
static int dabusb_fpga_download (pdabusb_t s, const char *fname)
{
pbulk_transfer_t b = kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ const struct firmware *fw;
+#endif
unsigned int blen, n;
int ret;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
unsigned char *buf = bitstream;
+#endif
dbg("Enter dabusb_fpga_download (internal)");
@@ -392,10 +447,22 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
return -ENOMEM;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev);
+ if (ret) {
+ err("Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
+ return ret;
+ }
+
+#endif
b->pipe = 1;
ret = dabusb_fpga_clear (s, b);
mdelay (10);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
blen = buf[73] + (buf[72] << 8);
+#else
+ blen = fw->data[73] + (fw->data[72] << 8);
+#endif
dbg("Bitstream len: %i", blen);
@@ -407,7 +474,11 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
for (n = 0; n <= blen + 60; n += 60) {
// some cclks for startup
b->size = 64;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
memcpy (b->data + 4, buf + 74 + n, 60);
+#else
+ memcpy (b->data + 4, fw->data + 74 + n, 60);
+#endif
ret = dabusb_bulk (s, b);
if (ret < 0) {
err("dabusb_bulk failed.");
@@ -418,6 +489,9 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
ret = dabusb_fpga_init (s, b);
kfree (b);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ release_firmware(fw);
+#endif
dbg("exit dabusb_fpga_download");
diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c
index bfe0ae346..b3dfa0447 100644
--- a/linux/drivers/media/video/gspca/sonixb.c
+++ b/linux/drivers/media/video/gspca/sonixb.c
@@ -41,23 +41,21 @@ struct sd {
unsigned char brightness;
unsigned char autogain;
unsigned char autogain_ignore_frames;
+ unsigned char frames_to_drop;
unsigned char freq; /* light freq filter setting */
- unsigned char saturation;
- unsigned char hue;
- unsigned char contrast;
unsigned char fr_h_sz; /* size of frame header */
char sensor; /* Type of image sensor chip */
#define SENSOR_HV7131R 0
#define SENSOR_OV6650 1
#define SENSOR_OV7630 2
-#define SENSOR_OV7630_3 3
-#define SENSOR_PAS106 4
-#define SENSOR_PAS202 5
-#define SENSOR_TAS5110 6
-#define SENSOR_TAS5130CXX 7
+#define SENSOR_PAS106 3
+#define SENSOR_PAS202 4
+#define SENSOR_TAS5110 5
+#define SENSOR_TAS5130CXX 6
char sensor_has_gain;
__u8 sensor_addr;
+ __u8 reg11;
};
#define COMP2 0x8f
@@ -89,12 +87,6 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
{
@@ -171,48 +163,6 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setfreq,
.get = sd_getfreq,
},
- {
- {
- .id = V4L2_CID_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
-#define SATURATION_DEF 127
- .default_value = SATURATION_DEF,
- },
- .set = sd_setsaturation,
- .get = sd_getsaturation,
- },
- {
- {
- .id = V4L2_CID_HUE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Hue",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
-#define HUE_DEF 127
- .default_value = HUE_DEF,
- },
- .set = sd_sethue,
- .get = sd_gethue,
- },
- {
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
-#define CONTRAST_DEF 127
- .default_value = CONTRAST_DEF,
- },
- .set = sd_setcontrast,
- .get = sd_getcontrast,
- },
};
static struct v4l2_pix_format vga_mode[] = {
@@ -245,8 +195,6 @@ static struct v4l2_pix_format sif_mode[] = {
.priv = 0},
};
-static const __u8 probe_ov7630[] = {0x08, 0x44};
-
static const __u8 initHv7131[] = {
0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
0x00, 0x00,
@@ -351,7 +299,7 @@ static const __u8 initOv7630_3[] = {
0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
};
-static const __u8 ov7630_sensor_init_com[][8] = {
+static const __u8 ov7630_sensor_init[][8] = {
{0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
{0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
@@ -372,17 +320,6 @@ static const __u8 ov7630_sensor_init_com[][8] = {
{0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
{0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
};
-static const __u8 ov7630_sensor_init[][8] = {
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */
- {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */
- {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16},
- {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16},
- {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */
-};
-static const __u8 ov7630_sensor_init_3[][8] = {
- {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10},
-};
static const __u8 initPas106[] = {
0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
@@ -572,7 +509,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_OV6650:
- case SENSOR_OV7630_3:
case SENSOR_OV7630: {
__u8 i2cOV[] =
{0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
@@ -665,7 +601,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
case SENSOR_OV6650:
gain >>= 1;
/* fall thru */
- case SENSOR_OV7630_3: {
+ case SENSOR_OV7630: {
__u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
i2c[1] = sd->sensor_addr;
@@ -720,7 +656,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
break;
}
case SENSOR_OV6650:
- case SENSOR_OV7630_3: {
+ case SENSOR_OV7630: {
/* The ov6650 / ov7630 have 2 registers which both influence
exposure, register 11, whose low nibble sets the nr off fps
according to: fps = 30 / (low_nibble + 1)
@@ -735,16 +671,20 @@ static void setexposure(struct gspca_dev *gspca_dev)
The code maps our 0 - 510 ms exposure ctrl to these 2
registers, trying to keep fps as high as possible.
*/
- __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
- int reg10, reg11;
+ __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
+ int reg10, reg11, reg10_max;
+
/* ov6645 datasheet says reg10_max is 9a, but that uses
tline * 2 * reg10 as formula for calculating texpo, the
ov6650 probably uses the same formula as the 7730 which uses
tline * 4 * reg10, which explains why the reg10max we've
found experimentally for the ov6650 is exactly half that of
the ov6645. The ov7630 datasheet says the max is 0x41. */
- const int reg10_max = (sd->sensor == SENSOR_OV6650)
- ? 0x4d : 0x41;
+ if (sd->sensor == SENSOR_OV6650) {
+ reg10_max = 0x4d;
+ i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
+ } else
+ reg10_max = 0x41;
reg11 = (60 * sd->exposure + 999) / 1000;
if (reg11 < 1)
@@ -765,20 +705,23 @@ static void setexposure(struct gspca_dev *gspca_dev)
else if (reg10 > reg10_max)
reg10 = reg10_max;
+ /* In 640x480, if the reg11 has less than 3, the image is
+ unstable (not enough bandwidth). */
+ if (gspca_dev->width == 640 && reg11 < 3)
+ reg11 = 3;
+
/* Write reg 10 and reg11 low nibble */
i2c[1] = sd->sensor_addr;
i2c[3] = reg10;
i2c[4] |= reg11 - 1;
- if (sd->sensor == SENSOR_OV7630_3) {
- __u8 reg76 = reg10 & 0x03;
- __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00,
- 0x00, 0x00, 0x00, 0x10};
- reg10 >>= 2;
- i2c_reg76[3] = reg76;
- if (i2c_w(gspca_dev, i2c_reg76) < 0)
- PDEBUG(D_ERR, "i2c error exposure");
- }
- if (i2c_w(gspca_dev, i2c) < 0)
+
+ /* If register 11 didn't change, don't change it */
+ if (sd->reg11 == reg11 )
+ i2c[0] = 0xa0;
+
+ if (i2c_w(gspca_dev, i2c) == 0)
+ sd->reg11 = reg11;
+ else
PDEBUG(D_ERR, "i2c error exposure");
break;
}
@@ -791,11 +734,11 @@ static void setfreq(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_OV6650:
- case SENSOR_OV7630_3: {
+ case SENSOR_OV7630: {
/* Framerate adjust register for artificial light 50 hz flicker
- compensation, identical to ov6630 0x2b register, see ov6630
- datasheet.
- 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */
+ compensation, for the ov6650 this is identical to ov6630
+ 0x2b register, see ov6630 datasheet.
+ 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
__u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
switch (sd->freq) {
default:
@@ -816,69 +759,6 @@ static void setfreq(struct gspca_dev *gspca_dev)
}
}
-static void setsaturation(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
-/* case SENSOR_OV6650: */
- case SENSOR_OV7630_3:
- case SENSOR_OV7630: {
- __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10};
- i2c[1] = sd->sensor_addr;
- i2c[3] = sd->saturation & 0xf0;
- if (i2c_w(gspca_dev, i2c) < 0)
- PDEBUG(D_ERR, "i2c error setsaturation");
- else
- PDEBUG(D_CONF, "saturation set to: %d",
- (int)sd->saturation);
- break;
- }
- }
-}
-
-static void sethue(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
-/* case SENSOR_OV6650: */
- case SENSOR_OV7630_3:
- case SENSOR_OV7630: {
- __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10};
- i2c[1] = sd->sensor_addr;
- i2c[3] = 0x20 | (sd->hue >> 3);
- if (i2c_w(gspca_dev, i2c) < 0)
- PDEBUG(D_ERR, "i2c error setsaturation");
- else
- PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue);
- break;
- }
- }
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
-/* case SENSOR_OV6650: */
- case SENSOR_OV7630_3:
- case SENSOR_OV7630: {
- __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10};
- i2c[1] = sd->sensor_addr;
- i2c[3] = 0x20 | (sd->contrast >> 3);
- if (i2c_w(gspca_dev, i2c) < 0)
- PDEBUG(D_ERR, "i2c error setcontrast");
- else
- PDEBUG(D_CONF, "contrast set to: %d",
- (int)sd->contrast);
- break;
- }
- }
-}
-
-
static void do_autogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -913,8 +793,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->fr_h_sz = 12; /* default size of the frame header */
sd->sd_desc.nctrls = 2; /* default nb of ctrls */
- sd->autogain = AUTOGAIN_DEF; /* default is autogain active */
-
product = id->idProduct;
/* switch (id->idVendor) { */
/* case 0x0c45: * Sonix */
@@ -945,17 +823,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
case 0x6019: /* SN9C101 */
case 0x602c: /* SN9C102 */
case 0x602e: /* SN9C102 */
- sd->sensor = SENSOR_OV7630;
- sd->sensor_addr = 0x21;
- break;
case 0x60b0: /* SN9C103 */
- sd->sensor = SENSOR_OV7630_3;
+ sd->sensor = SENSOR_OV7630;
sd->sensor_addr = 0x21;
- sd->fr_h_sz = 18; /* size of frame header */
sd->sensor_has_gain = 1;
- sd->sd_desc.nctrls = 8;
+ sd->sd_desc.nctrls = 5;
sd->sd_desc.dq_callback = do_autogain;
- sd->autogain = 0;
+ if (product == 0x60b0)
+ sd->fr_h_sz = 18; /* size of frame header */
break;
case 0x6024: /* SN9C102 */
case 0x6025: /* SN9C102 */
@@ -981,11 +856,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
if (!sif) {
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
- if (sd->sensor == SENSOR_OV7630_3) {
- /* We only have 320x240 & 640x480 */
- cam->cam_mode++;
- cam->nmodes--;
- }
} else {
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
@@ -993,12 +863,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->brightness = BRIGHTNESS_DEF;
sd->gain = GAIN_DEF;
sd->exposure = EXPOSURE_DEF;
+ sd->autogain = AUTOGAIN_DEF;
sd->freq = FREQ_DEF;
- sd->contrast = CONTRAST_DEF;
- sd->saturation = SATURATION_DEF;
- sd->hue = HUE_DEF;
- if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */
- reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
+
return 0;
}
@@ -1032,9 +899,8 @@ static void pas106_i2cinit(struct gspca_dev *gspca_dev)
static void sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int mode, l;
+ int mode, l = 0x1f;
const __u8 *sn9c10x;
- __u8 reg01, reg17;
__u8 reg17_19[3];
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -1052,13 +918,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg17_19[2] = 0x20;
break;
case SENSOR_OV7630:
- sn9c10x = initOv7630;
- reg17_19[0] = 0x68;
- reg17_19[1] = (mode << 4) | COMP2;
- reg17_19[2] = MCK_INIT1;
- break;
- case SENSOR_OV7630_3:
- sn9c10x = initOv7630_3;
+ if (sd->fr_h_sz == 18) { /* SN9C103 */
+ sn9c10x = initOv7630_3;
+ l = sizeof initOv7630_3;
+ } else
+ sn9c10x = initOv7630;
reg17_19[0] = 0x68;
reg17_19[1] = (mode << 4) | COMP2;
reg17_19[2] = MCK_INIT1;
@@ -1089,30 +953,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg17_19[2] = mode ? 0x23 : 0x43;
break;
}
- switch (sd->sensor) {
- case SENSOR_OV7630:
- reg01 = 0x06;
- reg17 = 0x29;
- l = sizeof initOv7630;
- break;
- case SENSOR_OV7630_3:
- reg01 = 0x44;
- reg17 = 0x68;
- l = sizeof initOv7630_3;
- break;
- default:
- reg01 = sn9c10x[0];
- reg17 = sn9c10x[0x17 - 1];
- l = 0x1f;
- break;
- }
/* reg 0x01 bit 2 video transfert on */
- reg_w(gspca_dev, 0x01, &reg01, 1);
+ reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
/* reg 0x17 SensorClk enable inv Clk 0x60 */
- reg_w(gspca_dev, 0x17, &reg17, 1);
-/*fixme: for ov7630 102
- reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
+ reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
/* Set the registers from the template */
reg_w_big(gspca_dev, 0x01, sn9c10x, l);
switch (sd->sensor) {
@@ -1125,17 +970,13 @@ static void sd_start(struct gspca_dev *gspca_dev)
sizeof ov6650_sensor_init);
break;
case SENSOR_OV7630:
- i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
- sizeof ov7630_sensor_init_com);
- msleep(200);
i2c_w_vector(gspca_dev, ov7630_sensor_init,
sizeof ov7630_sensor_init);
- break;
- case SENSOR_OV7630_3:
- i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
- sizeof ov7630_sensor_init_com);
- msleep(200);
- i2c_w(gspca_dev, ov7630_sensor_init_3[mode]);
+ if (sd->fr_h_sz == 18) { /* SN9C103 */
+ const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00,
+ 0x00, 0x00, 0x10 };
+ i2c_w(gspca_dev, i2c);
+ }
break;
case SENSOR_PAS106:
pas106_i2cinit(gspca_dev);
@@ -1175,14 +1016,14 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
msleep(20);
+ sd->reg11 = -1;
+
setgain(gspca_dev);
setbrightness(gspca_dev);
setexposure(gspca_dev);
setfreq(gspca_dev);
- setsaturation(gspca_dev);
- sethue(gspca_dev);
- setcontrast(gspca_dev);
+ sd->frames_to_drop = 0;
sd->autogain_ignore_frames = 0;
atomic_set(&sd->avg_lum, -1);
}
@@ -1228,21 +1069,31 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
&& data[3 + i] == 0xc4
&& data[4 + i] == 0xc4
&& data[5 + i] == 0x96) { /* start of frame */
- frame = gspca_frame_add(gspca_dev, LAST_PACKET,
- frame, data, 0);
+ int lum = -1;
+ int pkt_type = LAST_PACKET;
+
if (len - i < sd->fr_h_sz) {
- atomic_set(&sd->avg_lum, -1);
PDEBUG(D_STREAM, "packet too short to"
" get avg brightness");
} else if (sd->fr_h_sz == 12) {
- atomic_set(&sd->avg_lum,
- data[i + 8] +
- (data[i + 9] << 8));
+ lum = data[i + 8] + (data[i + 9] << 8);
} else {
- atomic_set(&sd->avg_lum,
- data[i + 9] +
- (data[i + 10] << 8));
+ lum = data[i + 9] +
+ (data[i + 10] << 8);
+ }
+ if (lum == 0) {
+ lum = -1;
+ sd->frames_to_drop = 2;
}
+ atomic_set(&sd->avg_lum, lum);
+
+ if (sd->frames_to_drop) {
+ sd->frames_to_drop--;
+ pkt_type = DISCARD_PACKET;
+ }
+
+ frame = gspca_frame_add(gspca_dev, pkt_type,
+ frame, data, 0);
data += i + sd->fr_h_sz;
len -= i + sd->fr_h_sz;
gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -1357,60 +1208,6 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->saturation = val;
- if (gspca_dev->streaming)
- setsaturation(gspca_dev);
- return 0;
-}
-
-static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->saturation;
- return 0;
-}
-
-static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->hue = val;
- if (gspca_dev->streaming)
- sethue(gspca_dev);
- return 0;
-}
-
-static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->hue;
- return 0;
-}
-
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = val;
- if (gspca_dev->streaming)
- setcontrast(gspca_dev);
- return 0;
-}
-
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->contrast;
- return 0;
-}
-
static int sd_querymenu(struct gspca_dev *gspca_dev,
struct v4l2_querymenu *menu)
{
diff --git a/linux/drivers/media/video/usbvideo/vicam.c b/linux/drivers/media/video/usbvideo/vicam.c
index 17f542dfb..2aa05f7ca 100644
--- a/linux/drivers/media/video/usbvideo/vicam.c
+++ b/linux/drivers/media/video/usbvideo/vicam.c
@@ -43,6 +43,10 @@
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/mutex.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include <linux/firmware.h>
+#include <linux/ihex.h>
+#endif
#include "usbvideo.h"
// #define VICAM_DEBUG
@@ -70,6 +74,7 @@
#define VICAM_HEADER_SIZE 64
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
/* Not sure what all the bytes in these char
* arrays do, but they're necessary to make
* the camera work.
@@ -348,6 +353,7 @@ static unsigned char setup5[] = {
0x46, 0x05, 0x6C, 0x05, 0x00, 0x00
};
+#endif
/* rvmalloc / rvfree copied from usbvideo.c
*
* Not sure why these are not yet non-statics which I can reference through
@@ -464,6 +470,7 @@ static int send_control_msg(struct vicam_camera *cam,
static int
initialize_camera(struct vicam_camera *cam)
{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
const struct {
u8 *data;
u32 size;
@@ -478,14 +485,41 @@ initialize_camera(struct vicam_camera *cam)
};
int err, i;
+#else
+ int err;
+ const struct ihex_binrec *rec;
+ const struct firmware *fw;
+
+ err = request_ihex_firmware(&fw, "vicam/firmware.fw", &cam->udev->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load \"vicam/firmware.fw\": %d\n",
+ err);
+ return err;
+ }
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
for (i = 0, err = 0; firmware[i].data && !err; i++) {
memcpy(cam->cntrlbuf, firmware[i].data, firmware[i].size);
+#else
+ for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
+ memcpy(cam->cntrlbuf, rec->data, be16_to_cpu(rec->len));
+#endif
err = send_control_msg(cam, 0xff, 0, 0,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
cam->cntrlbuf, firmware[i].size);
+#else
+ cam->cntrlbuf, be16_to_cpu(rec->len));
+ if (err)
+ break;
+#endif
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ release_firmware(fw);
+
+#endif
return err;
}
@@ -1226,3 +1260,6 @@ module_exit(usb_vicam_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+MODULE_FIRMWARE("vicam/firmware.fw");
+#endif