aboutsummaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/IR/keymaps/rc-rc6-mce.c21
-rw-r--r--drivers/media/IR/lirc_dev.c29
-rw-r--r--drivers/media/IR/mceusb.c174
-rw-r--r--drivers/media/IR/nuvoton-cir.c10
-rw-r--r--drivers/media/IR/streamzap.c21
-rw-r--r--drivers/media/common/saa7146_hlp.c8
-rw-r--r--drivers/media/common/saa7146_video.c16
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c117
-rw-r--r--drivers/media/video/gspca/sonixj.c416
-rw-r--r--drivers/media/video/mx2_camera.c2
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c51
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c54
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h24
-rw-r--r--drivers/media/video/s5p-fimc/regs-fimc.h3
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c2
-rw-r--r--drivers/media/video/soc_camera.c4
16 files changed, 458 insertions, 494 deletions
diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c
index 1b7adabbcee..6da955dfef4 100644
--- a/drivers/media/IR/keymaps/rc-rc6-mce.c
+++ b/drivers/media/IR/keymaps/rc-rc6-mce.c
@@ -26,8 +26,8 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f040a, KEY_DELETE },
{ 0x800f040b, KEY_ENTER },
- { 0x800f040c, KEY_POWER },
- { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
+ { 0x800f040c, KEY_POWER }, /* PC Power */
+ { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
{ 0x800f040e, KEY_MUTE },
{ 0x800f040f, KEY_INFO },
@@ -56,31 +56,32 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f0422, KEY_OK },
{ 0x800f0423, KEY_EXIT },
{ 0x800f0424, KEY_DVD },
- { 0x800f0425, KEY_TUNER }, /* LiveTV */
- { 0x800f0426, KEY_EPG }, /* Guide */
- { 0x800f0427, KEY_ZOOM }, /* Aspect */
+ { 0x800f0425, KEY_TUNER }, /* LiveTV */
+ { 0x800f0426, KEY_EPG }, /* Guide */
+ { 0x800f0427, KEY_ZOOM }, /* Aspect */
{ 0x800f043a, KEY_BRIGHTNESSUP },
{ 0x800f0446, KEY_TV },
- { 0x800f0447, KEY_AUDIO }, /* My Music */
- { 0x800f0448, KEY_PVR }, /* RecordedTV */
+ { 0x800f0447, KEY_AUDIO }, /* My Music */
+ { 0x800f0448, KEY_PVR }, /* RecordedTV */
{ 0x800f0449, KEY_CAMERA },
{ 0x800f044a, KEY_VIDEO },
{ 0x800f044c, KEY_LANGUAGE },
{ 0x800f044d, KEY_TITLE },
- { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
+ { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
{ 0x800f0450, KEY_RADIO },
- { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
+ { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
{ 0x800f045b, KEY_RED },
{ 0x800f045c, KEY_GREEN },
{ 0x800f045d, KEY_YELLOW },
{ 0x800f045e, KEY_BLUE },
+ { 0x800f0465, KEY_POWER2 }, /* TV Power */
{ 0x800f046e, KEY_PLAYPAUSE },
- { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
+ { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
{ 0x800f0480, KEY_BRIGHTNESSDOWN },
{ 0x800f0481, KEY_PLAYPAUSE },
diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c
index 8418b14ee4d..756656e17bd 100644
--- a/drivers/media/IR/lirc_dev.c
+++ b/drivers/media/IR/lirc_dev.c
@@ -522,10 +522,8 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
- if (!ir->attached) {
- mutex_unlock(&ir->irctl_lock);
+ if (!ir->attached)
return POLLERR;
- }
poll_wait(file, &ir->buf->wait_poll, wait);
@@ -649,18 +647,18 @@ ssize_t lirc_dev_fop_read(struct file *file,
if (!buf)
return -ENOMEM;
- if (mutex_lock_interruptible(&ir->irctl_lock))
- return -ERESTARTSYS;
+ if (mutex_lock_interruptible(&ir->irctl_lock)) {
+ ret = -ERESTARTSYS;
+ goto out_unlocked;
+ }
if (!ir->attached) {
- mutex_unlock(&ir->irctl_lock);
- return -ENODEV;
+ ret = -ENODEV;
+ goto out_locked;
}
if (length % ir->chunk_size) {
- dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n",
- ir->d.name, ir->d.minor);
- mutex_unlock(&ir->irctl_lock);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_locked;
}
/*
@@ -711,18 +709,23 @@ ssize_t lirc_dev_fop_read(struct file *file,
lirc_buffer_read(ir->buf, buf);
ret = copy_to_user((void *)buffer+written, buf,
ir->buf->chunk_size);
- written += ir->buf->chunk_size;
+ if (!ret)
+ written += ir->buf->chunk_size;
+ else
+ ret = -EFAULT;
}
}
remove_wait_queue(&ir->buf->wait_poll, &wait);
set_current_state(TASK_RUNNING);
+
+out_locked:
mutex_unlock(&ir->irctl_lock);
out_unlocked:
kfree(buf);
dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
- ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
+ ir->d.name, ir->d.minor, ret ? "<fail>" : "<ok>", ret);
return ret ? ret : written;
}
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c
index 9dce684fd23..392ca24132d 100644
--- a/drivers/media/IR/mceusb.c
+++ b/drivers/media/IR/mceusb.c
@@ -35,10 +35,10 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/usb.h>
#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
#include <media/ir-core.h>
-#include <media/ir-common.h>
#define DRIVER_VERSION "1.91"
#define DRIVER_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
@@ -49,6 +49,7 @@
#define USB_BUFLEN 32 /* USB reception buffer length */
#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */
#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */
+#define MS_TO_NS(msec) ((msec) * 1000)
/* MCE constants */
#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */
@@ -74,6 +75,7 @@
#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
/* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */
+#define MCE_CMD_SIG_END 0x01 /* End of signal */
#define MCE_CMD_PING 0x03 /* Ping device */
#define MCE_CMD_UNKNOWN 0x04 /* Unknown */
#define MCE_CMD_UNKNOWN2 0x05 /* Unknown */
@@ -91,6 +93,7 @@
#define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */
#define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */
#define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */
+#define MCE_RSP_PULSE_COUNT 0x15 /* RX pulse count (only if learning) */
#define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */
#define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */
#define MCE_CMD_UNKNOWN7 0x18 /* Unknown */
@@ -146,14 +149,16 @@ enum mceusb_model_type {
MCE_GEN3,
MCE_GEN2_TX_INV,
POLARIS_EVK,
+ CX_HYBRID_TV,
};
struct mceusb_model {
u32 mce_gen1:1;
u32 mce_gen2:1;
u32 mce_gen3:1;
- u32 tx_mask_inverted:1;
+ u32 tx_mask_normal:1;
u32 is_polaris:1;
+ u32 no_tx:1;
const char *rc_map; /* Allow specify a per-board map */
const char *name; /* per-board name */
@@ -162,18 +167,18 @@ struct mceusb_model {
static const struct mceusb_model mceusb_model[] = {
[MCE_GEN1] = {
.mce_gen1 = 1,
- .tx_mask_inverted = 1,
+ .tx_mask_normal = 1,
},
[MCE_GEN2] = {
.mce_gen2 = 1,
},
[MCE_GEN2_TX_INV] = {
.mce_gen2 = 1,
- .tx_mask_inverted = 1,
+ .tx_mask_normal = 1,
},
[MCE_GEN3] = {
.mce_gen3 = 1,
- .tx_mask_inverted = 1,
+ .tx_mask_normal = 1,
},
[POLARIS_EVK] = {
.is_polaris = 1,
@@ -183,7 +188,12 @@ static const struct mceusb_model mceusb_model[] = {
* to allow testing it
*/
.rc_map = RC_MAP_RC5_HAUPPAUGE_NEW,
- .name = "cx231xx MCE IR",
+ .name = "Conexant Hybrid TV (cx231xx) MCE IR",
+ },
+ [CX_HYBRID_TV] = {
+ .is_polaris = 1,
+ .no_tx = 1, /* tx isn't wired up at all */
+ .name = "Conexant Hybrid TV (cx231xx) MCE IR",
},
};
@@ -273,6 +283,8 @@ static struct usb_device_id mceusb_dev_table[] = {
{ USB_DEVICE(VENDOR_FORMOSA, 0xe03c) },
/* Formosa Industrial Computing */
{ USB_DEVICE(VENDOR_FORMOSA, 0xe03e) },
+ /* Fintek eHome Infrared Transceiver (HP branded) */
+ { USB_DEVICE(VENDOR_FINTEK, 0x5168) },
/* Fintek eHome Infrared Transceiver */
{ USB_DEVICE(VENDOR_FINTEK, 0x0602) },
/* Fintek eHome Infrared Transceiver (in the AOpen MP45) */
@@ -292,9 +304,12 @@ static struct usb_device_id mceusb_dev_table[] = {
{ USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
/* TiVo PC IR Receiver */
{ USB_DEVICE(VENDOR_TIVO, 0x2000) },
- /* Conexant SDK */
+ /* Conexant Hybrid TV "Shelby" Polaris SDK */
{ USB_DEVICE(VENDOR_CONEXANT, 0x58a1),
.driver_info = POLARIS_EVK },
+ /* Conexant Hybrid TV RDU253S Polaris */
+ { USB_DEVICE(VENDOR_CONEXANT, 0x58a5),
+ .driver_info = CX_HYBRID_TV },
/* Terminating entry */
{ }
};
@@ -303,7 +318,10 @@ static struct usb_device_id mceusb_dev_table[] = {
struct mceusb_dev {
/* ir-core bits */
struct ir_dev_props *props;
- struct ir_raw_event rawir;
+
+ /* optional features we can enable */
+ bool carrier_report_enabled;
+ bool learning_enabled;
/* core device bits */
struct device *dev;
@@ -318,6 +336,8 @@ struct mceusb_dev {
/* buffers and dma */
unsigned char *buf_in;
unsigned int len_in;
+ dma_addr_t dma_in;
+ dma_addr_t dma_out;
enum {
CMD_HEADER = 0,
@@ -325,15 +345,14 @@ struct mceusb_dev {
CMD_DATA,
PARSE_IRDATA,
} parser_state;
- u8 cmd, rem; /* Remaining IR data bytes in packet */
- dma_addr_t dma_in;
- dma_addr_t dma_out;
+ u8 cmd, rem; /* Remaining IR data bytes in packet */
struct {
u32 connected:1;
- u32 tx_mask_inverted:1;
+ u32 tx_mask_normal:1;
u32 microsoft_gen1:1;
+ u32 no_tx:1;
} flags;
/* transmit support */
@@ -408,9 +427,10 @@ static int mceusb_cmdsize(u8 cmd, u8 subcmd)
case MCE_CMD_UNKNOWN:
case MCE_CMD_S_CARRIER:
case MCE_CMD_S_TIMEOUT:
- case MCE_CMD_G_RXSENSOR:
+ case MCE_RSP_PULSE_COUNT:
datasize = 2;
break;
+ case MCE_CMD_SIG_END:
case MCE_CMD_S_TXMASK:
case MCE_CMD_S_RXSENSOR:
datasize = 1;
@@ -433,7 +453,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
return;
/* skip meaningless 0xb1 0x60 header bytes on orig receiver */
- if (ir->flags.microsoft_gen1 && !out)
+ if (ir->flags.microsoft_gen1 && !out && !offset)
skip = 2;
if (len <= skip)
@@ -491,6 +511,9 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
break;
case MCE_COMMAND_HEADER:
switch (subcmd) {
+ case MCE_CMD_SIG_END:
+ dev_info(dev, "End of signal\n");
+ break;
case MCE_CMD_PING:
dev_info(dev, "Ping\n");
break;
@@ -525,10 +548,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
inout, data1 == 0x02 ? "short" : "long");
break;
case MCE_CMD_G_RXSENSOR:
- if (len == 2)
+ /* aka MCE_RSP_PULSE_COUNT */
+ if (out)
dev_info(dev, "Get receive sensor\n");
- else
- dev_info(dev, "Received pulse count is %d\n",
+ else if (ir->learning_enabled)
+ dev_info(dev, "RX pulse count: %d\n",
((data1 << 8) | data2));
break;
case MCE_RSP_CMD_INVALID:
@@ -724,16 +748,16 @@ out:
return ret ? ret : n;
}
-/* Sets active IR outputs -- mce devices typically (all?) have two */
+/* Sets active IR outputs -- mce devices typically have two */
static int mceusb_set_tx_mask(void *priv, u32 mask)
{
struct mceusb_dev *ir = priv;
- if (ir->flags.tx_mask_inverted)
+ if (ir->flags.tx_mask_normal)
+ ir->tx_mask = mask;
+ else
ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ?
mask ^ MCE_DEFAULT_TX_MASK : mask) << 1;
- else
- ir->tx_mask = mask;
return 0;
}
@@ -752,7 +776,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
if (carrier == 0) {
ir->carrier = carrier;
- cmdbuf[2] = 0x01;
+ cmdbuf[2] = MCE_CMD_SIG_END;
cmdbuf[3] = MCE_IRDATA_TRAILER;
dev_dbg(ir->dev, "%s: disabling carrier "
"modulation\n", __func__);
@@ -782,6 +806,34 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
return carrier;
}
+/*
+ * We don't do anything but print debug spew for many of the command bits
+ * we receive from the hardware, but some of them are useful information
+ * we want to store so that we can use them.
+ */
+static void mceusb_handle_command(struct mceusb_dev *ir, int index)
+{
+ u8 hi = ir->buf_in[index + 1] & 0xff;
+ u8 lo = ir->buf_in[index + 2] & 0xff;
+
+ switch (ir->buf_in[index]) {
+ /* 2-byte return value commands */
+ case MCE_CMD_S_TIMEOUT:
+ ir->props->timeout = MS_TO_NS((hi << 8 | lo) / 2);
+ break;
+
+ /* 1-byte return value commands */
+ case MCE_CMD_S_TXMASK:
+ ir->tx_mask = hi;
+ break;
+ case MCE_CMD_S_RXSENSOR:
+ ir->learning_enabled = (hi == 0x02);
+ break;
+ default:
+ break;
+ }
+}
+
static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
{
DEFINE_IR_RAW_EVENT(rawir);
@@ -791,39 +843,30 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
if (ir->flags.microsoft_gen1)
i = 2;
+ /* if there's no data, just return now */
+ if (buf_len <= i)
+ return;
+
for (; i < buf_len; i++) {
switch (ir->parser_state) {
case SUBCMD:
ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]);
mceusb_dev_printdata(ir, ir->buf_in, i - 1,
ir->rem + 2, false);
+ mceusb_handle_command(ir, i);
ir->parser_state = CMD_DATA;
break;
case PARSE_IRDATA:
ir->rem--;
rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
- * MCE_TIME_UNIT * 1000;
-
- if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) {
- if (ir->rawir.pulse == rawir.pulse) {
- ir->rawir.duration += rawir.duration;
- } else {
- ir->rawir.duration = rawir.duration;
- ir->rawir.pulse = rawir.pulse;
- }
- if (ir->rem)
- break;
- }
- rawir.duration += ir->rawir.duration;
- ir->rawir.duration = 0;
- ir->rawir.pulse = rawir.pulse;
+ * MS_TO_NS(MCE_TIME_UNIT);
dev_dbg(ir->dev, "Storing %s with duration %d\n",
rawir.pulse ? "pulse" : "space",
rawir.duration);
- ir_raw_event_store(ir->idev, &rawir);
+ ir_raw_event_store_with_filter(ir->idev, &rawir);
break;
case CMD_DATA:
ir->rem--;
@@ -839,17 +882,10 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
continue;
}
ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK);
- mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false);
- if (ir->rem) {
+ mceusb_dev_printdata(ir, ir->buf_in,
+ i, ir->rem + 1, false);
+ if (ir->rem)
ir->parser_state = PARSE_IRDATA;
- break;
- }
- /*
- * a package with len=0 (e. g. 0x80) means end of
- * data. We could use it to do the call to
- * ir_raw_event_handle(). For now, we don't need to
- * use it.
- */
break;
}
@@ -984,9 +1020,11 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
mce_sync_in(ir, NULL, maxp);
- /* get the transmitter bitmask */
- mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
- mce_sync_in(ir, NULL, maxp);
+ if (!ir->flags.no_tx) {
+ /* get the transmitter bitmask */
+ mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
+ mce_sync_in(ir, NULL, maxp);
+ }
/* get receiver timeout value */
mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
@@ -1035,12 +1073,18 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
props->priv = ir;
props->driver_type = RC_DRIVER_IR_RAW;
props->allowed_protos = IR_TYPE_ALL;
- props->s_tx_mask = mceusb_set_tx_mask;
- props->s_tx_carrier = mceusb_set_tx_carrier;
- props->tx_ir = mceusb_tx_ir;
+ props->timeout = MS_TO_NS(1000);
+ if (!ir->flags.no_tx) {
+ props->s_tx_mask = mceusb_set_tx_mask;
+ props->s_tx_carrier = mceusb_set_tx_carrier;
+ props->tx_ir = mceusb_tx_ir;
+ }
ir->props = props;
+ usb_to_input_id(ir->usbdev, &idev->id);
+ idev->dev.parent = ir->dev;
+
if (mceusb_model[ir->model].rc_map)
rc_map = mceusb_model[ir->model].rc_map;
@@ -1074,16 +1118,16 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
enum mceusb_model_type model = id->driver_info;
bool is_gen3;
bool is_microsoft_gen1;
- bool tx_mask_inverted;
+ bool tx_mask_normal;
bool is_polaris;
- dev_dbg(&intf->dev, ": %s called\n", __func__);
+ dev_dbg(&intf->dev, "%s called\n", __func__);
idesc = intf->cur_altsetting;
is_gen3 = mceusb_model[model].mce_gen3;
is_microsoft_gen1 = mceusb_model[model].mce_gen1;
- tx_mask_inverted = mceusb_model[model].tx_mask_inverted;
+ tx_mask_normal = mceusb_model[model].tx_mask_normal;
is_polaris = mceusb_model[model].is_polaris;
if (is_polaris) {
@@ -1107,7 +1151,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
ep_in = ep;
ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
ep_in->bInterval = 1;
- dev_dbg(&intf->dev, ": acceptable inbound endpoint "
+ dev_dbg(&intf->dev, "acceptable inbound endpoint "
"found\n");
}
@@ -1122,12 +1166,12 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
ep_out = ep;
ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
ep_out->bInterval = 1;
- dev_dbg(&intf->dev, ": acceptable outbound endpoint "
+ dev_dbg(&intf->dev, "acceptable outbound endpoint "
"found\n");
}
}
if (ep_in == NULL) {
- dev_dbg(&intf->dev, ": inbound and/or endpoint not found\n");
+ dev_dbg(&intf->dev, "inbound and/or endpoint not found\n");
return -ENODEV;
}
@@ -1150,11 +1194,10 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
ir->dev = &intf->dev;
ir->len_in = maxp;
ir->flags.microsoft_gen1 = is_microsoft_gen1;
- ir->flags.tx_mask_inverted = tx_mask_inverted;
+ ir->flags.tx_mask_normal = tx_mask_normal;
+ ir->flags.no_tx = mceusb_model[model].no_tx;
ir->model = model;
- init_ir_raw_event(&ir->rawir);
-
/* Saving usb interface data for use by the transmitter routine */
ir->usb_ep_in = ep_in;
ir->usb_ep_out = ep_out;
@@ -1191,7 +1234,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
mceusb_get_parameters(ir);
- mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK);
+ if (!ir->flags.no_tx)
+ mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK);
usb_set_intfdata(intf, ir);
diff --git a/drivers/media/IR/nuvoton-cir.c b/drivers/media/IR/nuvoton-cir.c
index 301be53aee8..acc729c79ce 100644
--- a/drivers/media/IR/nuvoton-cir.c
+++ b/drivers/media/IR/nuvoton-cir.c
@@ -603,6 +603,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
count = nvt->pkts;
nvt_dbg_verbose("Processing buffer of len %d", count);
+ init_ir_raw_event(&rawir);
+
for (i = 0; i < count; i++) {
nvt->pkts--;
sample = nvt->buf[i];
@@ -643,11 +645,15 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
* indicates end of IR signal, but new data incoming. In both
* cases, it means we're ready to call ir_raw_event_handle
*/
- if (sample == BUF_PULSE_BIT || ((sample != BUF_LEN_MASK) &&
- (sample & BUF_REPEAT_MASK) == BUF_REPEAT_BYTE))
+ if ((sample == BUF_PULSE_BIT) && nvt->pkts) {
+ nvt_dbg("Calling ir_raw_event_handle (signal end)\n");
ir_raw_event_handle(nvt->rdev);
+ }
}
+ nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n");
+ ir_raw_event_handle(nvt->rdev);
+
if (nvt->pkts) {
nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts);
nvt->pkts = 0;
diff --git a/drivers/media/IR/streamzap.c b/drivers/media/IR/streamzap.c
index 548381c35bf..3a20aef67d0 100644
--- a/drivers/media/IR/streamzap.c
+++ b/drivers/media/IR/streamzap.c
@@ -34,8 +34,9 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/usb.h>
#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
#include <media/ir-core.h>
#define DRIVER_VERSION "1.61"
@@ -140,7 +141,9 @@ static struct usb_driver streamzap_driver = {
static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
{
- ir_raw_event_store(sz->idev, &rawir);
+ dev_dbg(sz->dev, "Storing %s with duration %u us\n",
+ (rawir.pulse ? "pulse" : "space"), rawir.duration);
+ ir_raw_event_store_with_filter(sz->idev, &rawir);
}
static void sz_push_full_pulse(struct streamzap_ir *sz,
@@ -167,7 +170,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
rawir.duration *= 1000;
rawir.duration &= IR_MAX_DURATION;
}
- dev_dbg(sz->dev, "ls %u\n", rawir.duration);
sz_push(sz, rawir);
sz->idle = false;
@@ -180,7 +182,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
sz->sum += rawir.duration;
rawir.duration *= 1000;
rawir.duration &= IR_MAX_DURATION;
- dev_dbg(sz->dev, "p %u\n", rawir.duration);
sz_push(sz, rawir);
}
@@ -200,7 +201,6 @@ static void sz_push_full_space(struct streamzap_ir *sz,
rawir.duration += SZ_RESOLUTION / 2;
sz->sum += rawir.duration;
rawir.duration *= 1000;
- dev_dbg(sz->dev, "s %u\n", rawir.duration);
sz_push(sz, rawir);
}
@@ -221,8 +221,6 @@ static void streamzap_callback(struct urb *urb)
struct streamzap_ir *sz;
unsigned int i;
int len;
- static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
- IR_MAX_DURATION) | 0x03000000);
if (!urb)
return;
@@ -246,7 +244,7 @@ static void streamzap_callback(struct urb *urb)
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
for (i = 0; i < len; i++) {
- dev_dbg(sz->dev, "sz idx %d: %x\n",
+ dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n",
i, (unsigned char)sz->buf_in[i]);
switch (sz->decoder_state) {
case PulseSpace:
@@ -273,7 +271,7 @@ static void streamzap_callback(struct urb *urb)
DEFINE_IR_RAW_EVENT(rawir);
rawir.pulse = false;
- rawir.duration = timeout;
+ rawir.duration = sz->props->timeout;
sz->idle = true;
if (sz->timeout_enabled)
sz_push(sz, rawir);
@@ -335,6 +333,9 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
sz->props = props;
+ usb_to_input_id(sz->usbdev, &idev->id);
+ idev->dev.parent = sz->dev;
+
ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
if (ret < 0) {
dev_err(dev, "remote input device register failed\n");
@@ -444,6 +445,8 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
sz->decoder_state = PulseSpace;
/* FIXME: don't yet have a way to set this */
sz->timeout_enabled = true;
+ sz->props->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
+ IR_MAX_DURATION) | 0x03000000);
#if 0
/* not yet supported, depends on patches from maxim */
/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c
index 05bde9ccb77..1d1d8d20075 100644
--- a/drivers/media/common/saa7146_hlp.c
+++ b/drivers/media/common/saa7146_hlp.c
@@ -558,7 +558,7 @@ static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, e
static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat)
{
struct saa7146_vv *vv = dev->vv_data;
- struct saa7146_format *sfmt = format_by_fourcc(dev, pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pixelformat);
int b_depth = vv->ov_fmt->depth;
int b_bpl = vv->ov_fb.fmt.bytesperline;
@@ -702,7 +702,7 @@ static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa71
struct saa7146_vv *vv = dev->vv_data;
struct saa7146_video_dma vdma1;
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
int width = buf->fmt->width;
int height = buf->fmt->height;
@@ -827,7 +827,7 @@ static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa71
struct saa7146_video_dma vdma2;
struct saa7146_video_dma vdma3;
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
int width = buf->fmt->width;
int height = buf->fmt->height;
@@ -994,7 +994,7 @@ static void program_capture_engine(struct saa7146_dev *dev, int planar)
void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
{
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
struct saa7146_vv *vv = dev->vv_data;
u32 vdma1_prot_addr;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 741c5732b43..d246910129e 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -84,7 +84,7 @@ static struct saa7146_format formats[] = {
static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
-struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
+struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc)
{
int i, j = NUM_FORMATS;
@@ -266,7 +266,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
struct scatterlist *list = dma->sglist;
int length = dma->sglen;
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
@@ -408,7 +408,7 @@ static int video_begin(struct saa7146_fh *fh)
}
}
- fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
/* we need to have a valid format set here */
BUG_ON(NULL == fmt);
@@ -460,7 +460,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
return -EBUSY;
}
- fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
/* we need to have a valid format set here */
BUG_ON(NULL == fmt);
@@ -536,7 +536,7 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
return -EPERM;
/* check args */
- fmt = format_by_fourcc(dev, fb->fmt.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat);
if (NULL == fmt)
return -EINVAL;
@@ -760,7 +760,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma
DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
- fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat);
if (NULL == fmt)
return -EINVAL;
@@ -1264,7 +1264,7 @@ static int buffer_prepare(struct videobuf_queue *q,
buf->fmt = &fh->video_fmt;
buf->vb.field = fh->video_fmt.field;
- sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
release_all_pagetables(dev, buf);
if( 0 != IS_PLANAR(sfmt->trans)) {
@@ -1378,7 +1378,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
fh->video_fmt.bytesperline = 0;
fh->video_fmt.field = V4L2_FIELD_ANY;
- sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
+ sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
videobuf_queue_sg_init(&fh->video_q, &video_qops,
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index a529619e51f..0902ec041c7 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -854,7 +854,6 @@ int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit)
xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM;
/* is it free? */
- mutex_lock(&btv->lock);
if (btv->resources & xbits) {
/* no, someone else uses it */
goto fail;
@@ -884,11 +883,9 @@ int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit)
/* it's free, grab it */
fh->resources |= bit;
btv->resources |= bit;
- mutex_unlock(&btv->lock);
return 1;
fail:
- mutex_unlock(&btv->lock);
return 0;
}
@@ -940,7 +937,6 @@ void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits)
/* trying to free ressources not allocated by us ... */
printk("bttv: BUG! (btres)\n");
}
- mutex_lock(&btv->lock);
fh->resources &= ~bits;
btv->resources &= ~bits;
@@ -951,8 +947,6 @@ void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits)
if (0 == (bits & VBI_RESOURCES))
disclaim_vbi_lines(btv);
-
- mutex_unlock(&btv->lock);
}
/* ----------------------------------------------------------------------- */
@@ -1713,28 +1707,20 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv,
/* Make sure tvnorm and vbi_end remain consistent
until we're done. */
- mutex_lock(&btv->lock);
norm = btv->tvnorm;
/* In this mode capturing always starts at defrect.top
(default VDELAY), ignoring cropping parameters. */
if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) {
- mutex_unlock(&btv->lock);
return -EINVAL;
}
- mutex_unlock(&btv->lock);
-
c.rect = bttv_tvnorms[norm].cropcap.defrect;
} else {
- mutex_lock(&btv->lock);
-
norm = btv->tvnorm;
c = btv->crop[!!fh->do_crop];
- mutex_unlock(&btv->lock);
-
if (width < c.min_scaled_width ||
width > c.max_scaled_width ||
height < c.min_scaled_height)
@@ -1858,7 +1844,6 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id)
unsigned int i;
int err;
- mutex_lock(&btv->lock);
err = v4l2_prio_check(&btv->prio, fh->prio);
if (err)
goto err;
@@ -1874,7 +1859,6 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id)
set_tvnorm(btv, i);
err:
- mutex_unlock(&btv->lock);
return err;
}
@@ -1898,7 +1882,6 @@ static int bttv_enum_input(struct file *file, void *priv,
struct bttv *btv = fh->btv;
int rc = 0;
- mutex_lock(&btv->lock);
if (i->index >= bttv_tvcards[btv->c.type].video_inputs) {
rc = -EINVAL;
goto err;
@@ -1928,7 +1911,6 @@ static int bttv_enum_input(struct file *file, void *priv,
i->std = BTTV_NORMS;
err:
- mutex_unlock(&btv->lock);
return rc;
}
@@ -1938,9 +1920,7 @@ static int bttv_g_input(struct file *file, void *priv, unsigned int *i)
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- mutex_lock(&btv->lock);
*i = btv->input;
- mutex_unlock(&btv->lock);
return 0;
}
@@ -1952,7 +1932,6 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i)
int err;
- mutex_lock(&btv->lock);
err = v4l2_prio_check(&btv->prio, fh->prio);
if (unlikely(err))
goto err;
@@ -1965,7 +1944,6 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i)
set_input(btv, i, btv->tvnorm);
err:
- mutex_unlock(&btv->lock);
return 0;
}
@@ -1979,7 +1957,6 @@ static int bttv_s_tuner(struct file *file, void *priv,
if (unlikely(0 != t->index))
return -EINVAL;
- mutex_lock(&btv->lock);
if (unlikely(btv->tuner_type == TUNER_ABSENT)) {
err = -EINVAL;
goto err;
@@ -1995,7 +1972,6 @@ static int bttv_s_tuner(struct file *file, void *priv,
btv->audio_mode_gpio(btv, t, 1);
err:
- mutex_unlock(&btv->lock);
return 0;
}
@@ -2006,10 +1982,8 @@ static int bttv_g_frequency(struct file *file, void *priv,
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- mutex_lock(&btv->lock);
f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = btv->freq;
- mutex_unlock(&btv->lock);
return 0;
}
@@ -2024,7 +1998,6 @@ static int bttv_s_frequency(struct file *file, void *priv,
if (unlikely(f->tuner != 0))
return -EINVAL;
- mutex_lock(&btv->lock);
err = v4l2_prio_check(&btv->prio, fh->prio);
if (unlikely(err))
goto err;
@@ -2039,7 +2012,6 @@ static int bttv_s_frequency(struct file *file, void *priv,
if (btv->has_matchbox && btv->radio_user)
tea5757_set_freq(btv, btv->freq);
err:
- mutex_unlock(&btv->lock);
return 0;
}
@@ -2172,7 +2144,6 @@ limit_scaled_size_lock (struct bttv_fh * fh,
/* Make sure tvnorm, vbi_end and the current cropping parameters
remain consistent until we're done. */
- mutex_lock(&btv->lock);
b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds;
@@ -2250,7 +2221,6 @@ limit_scaled_size_lock (struct bttv_fh * fh,
rc = 0; /* success */
fail:
- mutex_unlock(&btv->lock);
return rc;
}
@@ -2282,9 +2252,7 @@ verify_window_lock (struct bttv_fh * fh,
if (V4L2_FIELD_ANY == field) {
__s32 height2;
- mutex_lock(&fh->btv->lock);
height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1;
- mutex_unlock(&fh->btv->lock);
field = (win->w.height > height2)
? V4L2_FIELD_INTERLACED
: V4L2_FIELD_TOP;
@@ -2360,7 +2328,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
}
}
- mutex_lock(&fh->cap.vb_lock);
/* clip against screen */
if (NULL != btv->fbuf.base)
n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height,
@@ -2391,13 +2358,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
fh->ov.field = win->field;
fh->ov.setup_ok = 1;
- /*
- * FIXME: btv is protected by btv->lock mutex, while btv->init
- * is protected by fh->cap.vb_lock. This seems to open the
- * possibility for some race situations. Maybe the better would
- * be to unify those locks or to use another way to store the
- * init values that will be consumed by videobuf callbacks
- */
btv->init.ov.w.width = win->w.width;
btv->init.ov.w.height = win->w.height;
btv->init.ov.field = win->field;
@@ -2412,7 +2372,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
retval = bttv_switch_overlay(btv,fh,new);
}
- mutex_unlock(&fh->cap.vb_lock);
return retval;
}
@@ -2526,9 +2485,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
if (V4L2_FIELD_ANY == field) {
__s32 height2;
- mutex_lock(&btv->lock);
height2 = btv->crop[!!fh->do_crop].rect.height >> 1;
- mutex_unlock(&btv->lock);
field = (f->fmt.pix.height > height2)
? V4L2_FIELD_INTERLACED
: V4L2_FIELD_BOTTOM;
@@ -2614,7 +2571,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
/* update our state informations */
- mutex_lock(&fh->cap.vb_lock);
fh->fmt = fmt;
fh->cap.field = f->fmt.pix.field;
fh->cap.last = V4L2_FIELD_NONE;
@@ -2623,7 +2579,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
btv->init.fmt = fmt;
btv->init.width = f->fmt.pix.width;
btv->init.height = f->fmt.pix.height;
- mutex_unlock(&fh->cap.vb_lock);
return 0;
}
@@ -2649,11 +2604,9 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
unsigned int i;
struct bttv_fh *fh = priv;
- mutex_lock(&fh->cap.vb_lock);
retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize,
V4L2_MEMORY_MMAP);
if (retval < 0) {
- mutex_unlock(&fh->cap.vb_lock);
return retval;
}
@@ -2665,7 +2618,6 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
for (i = 0; i < gbuffers; i++)
mbuf->offsets[i] = i * gbufsize;
- mutex_unlock(&fh->cap.vb_lock);
return 0;
}
#endif
@@ -2775,10 +2727,8 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
int retval = 0;
if (on) {
- mutex_lock(&fh->cap.vb_lock);
/* verify args */
if (unlikely(!btv->fbuf.base)) {
- mutex_unlock(&fh->cap.vb_lock);
return -EINVAL;
}
if (unlikely(!fh->ov.setup_ok)) {
@@ -2787,13 +2737,11 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
}
if (retval)
return retval;
- mutex_unlock(&fh->cap.vb_lock);
}
if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY))
return -EBUSY;
- mutex_lock(&fh->cap.vb_lock);
if (on) {
fh->ov.tvnorm = btv->tvnorm;
new = videobuf_sg_alloc(sizeof(*new));
@@ -2805,7 +2753,6 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
/* switch over */
retval = bttv_switch_overlay(btv, fh, new);
- mutex_unlock(&fh->cap.vb_lock);
return retval;
}
@@ -2844,7 +2791,6 @@ static int bttv_s_fbuf(struct file *file, void *f,
}
/* ok, accept it */
- mutex_lock(&fh->cap.vb_lock);
btv->fbuf.base = fb->base;
btv->fbuf.fmt.width = fb->fmt.width;
btv->fbuf.fmt.height = fb->fmt.height;
@@ -2876,7 +2822,6 @@ static int bttv_s_fbuf(struct file *file, void *f,
retval = bttv_switch_overlay(btv, fh, new);
}
}
- mutex_unlock(&fh->cap.vb_lock);
return retval;
}
@@ -2955,7 +2900,6 @@ static int bttv_queryctrl(struct file *file, void *priv,
c->id >= V4L2_CID_PRIVATE_LASTP1))
return -EINVAL;
- mutex_lock(&btv->lock);
if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME))
*c = no_ctl;
else {
@@ -2963,7 +2907,6 @@ static int bttv_queryctrl(struct file *file, void *priv,
*c = (NULL != ctrl) ? *ctrl : no_ctl;
}
- mutex_unlock(&btv->lock);
return 0;
}
@@ -2974,10 +2917,8 @@ static int bttv_g_parm(struct file *file, void *f,
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
- mutex_lock(&btv->lock);
v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id,
&parm->parm.capture.timeperframe);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -2993,7 +2934,6 @@ static int bttv_g_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- mutex_lock(&btv->lock);
t->rxsubchans = V4L2_TUNER_SUB_MONO;
bttv_call_all(btv, tuner, g_tuner, t);
strcpy(t->name, "Television");
@@ -3005,7 +2945,6 @@ static int bttv_g_tuner(struct file *file, void *priv,
if (btv->audio_mode_gpio)
btv->audio_mode_gpio(btv, t, 0);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3014,9 +2953,7 @@ static int bttv_g_priority(struct file *file, void *f, enum v4l2_priority *p)
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
- mutex_lock(&btv->lock);
*p = v4l2_prio_max(&btv->prio);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3028,9 +2965,7 @@ static int bttv_s_priority(struct file *file, void *f,
struct bttv *btv = fh->btv;
int rc;
- mutex_lock(&btv->lock);
rc = v4l2_prio_change(&btv->prio, &fh->prio, prio);
- mutex_unlock(&btv->lock);
return rc;
}
@@ -3045,9 +2980,7 @@ static int bttv_cropcap(struct file *file, void *priv,
cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
return -EINVAL;
- mutex_lock(&btv->lock);
*cap = bttv_tvnorms[btv->tvnorm].cropcap;
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3065,9 +2998,7 @@ static int bttv_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
inconsistent with fh->width or fh->height and apps
do not expect a change here. */
- mutex_lock(&btv->lock);
crop->c = btv->crop[!!fh->do_crop].rect;
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3091,17 +3022,14 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
/* Make sure tvnorm, vbi_end and the current cropping
parameters remain consistent until we're done. Note
read() may change vbi_end in check_alloc_btres_lock(). */
- mutex_lock(&btv->lock);
retval = v4l2_prio_check(&btv->prio, fh->prio);
if (0 != retval) {
- mutex_unlock(&btv->lock);
return retval;
}
retval = -EBUSY;
if (locked_btres(fh->btv, VIDEO_RESOURCES)) {
- mutex_unlock(&btv->lock);
return retval;
}
@@ -3113,7 +3041,6 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
b_top = max(b->top, btv->vbi_end);
if (b_top + 32 >= b_bottom) {
- mutex_unlock(&btv->lock);
return retval;
}
@@ -3136,12 +3063,8 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
btv->crop[1] = c;
- mutex_unlock(&btv->lock);
-
fh->do_crop = 1;
- mutex_lock(&fh->cap.vb_lock);
-
if (fh->width < c.min_scaled_width) {
fh->width = c.min_scaled_width;
btv->init.width = c.min_scaled_width;
@@ -3158,8 +3081,6 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
btv->init.height = c.max_scaled_height;
}
- mutex_unlock(&fh->cap.vb_lock);
-
return 0;
}
@@ -3227,7 +3148,6 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
return videobuf_poll_stream(file, &fh->vbi, wait);
}
- mutex_lock(&fh->cap.vb_lock);
if (check_btres(fh,RESOURCE_VIDEO_STREAM)) {
/* streaming capture */
if (list_empty(&fh->cap.stream))
@@ -3262,7 +3182,6 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
else
rc = 0;
err:
- mutex_unlock(&fh->cap.vb_lock);
return rc;
}
@@ -3293,23 +3212,11 @@ static int bttv_open(struct file *file)
return -ENOMEM;
file->private_data = fh;
- /*
- * btv is protected by btv->lock mutex, while btv->init and other
- * streaming vars are protected by fh->cap.vb_lock. We need to take
- * care of both locks to avoid troubles. However, vb_lock is used also
- * inside videobuf, without calling buf->lock. So, it is a very bad
- * idea to hold both locks at the same time.
- * Let's first copy btv->init at fh, holding cap.vb_lock, and then work
- * with the rest of init, holding btv->lock.
- */
- mutex_lock(&fh->cap.vb_lock);
*fh = btv->init;
- mutex_unlock(&fh->cap.vb_lock);
fh->type = type;
fh->ov.setup_ok = 0;
- mutex_lock(&btv->lock);
v4l2_prio_open(&btv->prio, &fh->prio);
videobuf_queue_sg_init(&fh->cap, &bttv_video_qops,
@@ -3317,13 +3224,13 @@ static int bttv_open(struct file *file)
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_INTERLACED,
sizeof(struct bttv_buffer),
- fh, NULL);
+ fh, &btv->lock);
videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops,
&btv->c.pci->dev, &btv->s_lock,
V4L2_BUF_TYPE_VBI_CAPTURE,
V4L2_FIELD_SEQ_TB,
sizeof(struct bttv_buffer),
- fh, NULL);
+ fh, &btv->lock);
set_tvnorm(btv,btv->tvnorm);
set_input(btv, btv->input, btv->tvnorm);
@@ -3346,7 +3253,6 @@ static int bttv_open(struct file *file)
bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm);
bttv_field_count(btv);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3355,7 +3261,6 @@ static int bttv_release(struct file *file)
struct bttv_fh *fh = file->private_data;
struct bttv *btv = fh->btv;
- mutex_lock(&btv->lock);
/* turn off overlay */
if (check_btres(fh, RESOURCE_OVERLAY))
bttv_switch_overlay(btv,fh,NULL);
@@ -3381,14 +3286,8 @@ static int bttv_release(struct file *file)
/* free stuff */
- /*
- * videobuf uses cap.vb_lock - we should avoid holding btv->lock,
- * otherwise we may have dead lock conditions
- */
- mutex_unlock(&btv->lock);
videobuf_mmap_free(&fh->cap);
videobuf_mmap_free(&fh->vbi);
- mutex_lock(&btv->lock);
v4l2_prio_close(&btv->prio, fh->prio);
file->private_data = NULL;
kfree(fh);
@@ -3398,7 +3297,6 @@ static int bttv_release(struct file *file)
if (!btv->users)
audio_mute(btv, 1);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3502,11 +3400,8 @@ static int radio_open(struct file *file)
if (unlikely(!fh))
return -ENOMEM;
file->private_data = fh;
- mutex_lock(&fh->cap.vb_lock);
*fh = btv->init;
- mutex_unlock(&fh->cap.vb_lock);
- mutex_lock(&btv->lock);
v4l2_prio_open(&btv->prio, &fh->prio);
btv->radio_user++;
@@ -3514,7 +3409,6 @@ static int radio_open(struct file *file)
bttv_call_all(btv, tuner, s_radio);
audio_input(btv,TVAUDIO_INPUT_RADIO);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3524,7 +3418,6 @@ static int radio_release(struct file *file)
struct bttv *btv = fh->btv;
struct rds_command cmd;
- mutex_lock(&btv->lock);
v4l2_prio_close(&btv->prio, fh->prio);
file->private_data = NULL;
kfree(fh);
@@ -3532,7 +3425,6 @@ static int radio_release(struct file *file)
btv->radio_user--;
bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3561,7 +3453,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
- mutex_lock(&btv->lock);
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
@@ -3570,8 +3461,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
if (btv->audio_mode_gpio)
btv->audio_mode_gpio(btv, t, 0);
- mutex_unlock(&btv->lock);
-
return 0;
}
@@ -3692,7 +3581,7 @@ static const struct v4l2_file_operations radio_fops =
.open = radio_open,
.read = radio_read,
.release = radio_release,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.poll = radio_poll,
};
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 330dadc0010..e23de57e2c7 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -63,7 +63,10 @@ struct sd {
#define QUALITY_DEF 80
u8 jpegqual; /* webcam quality */
+ u8 reg01;
+ u8 reg17;
u8 reg18;
+ u8 flags;
s8 ag_cnt;
#define AG_CNT_START 13
@@ -96,6 +99,22 @@ enum sensors {
SENSOR_SP80708,
};
+/* device flags */
+#define PDN_INV 1 /* inverse pin S_PWR_DN / sn_xxx tables */
+
+/* sn9c1xx definitions */
+/* register 0x01 */
+#define S_PWR_DN 0x01 /* sensor power down */
+#define S_PDN_INV 0x02 /* inverse pin S_PWR_DN */
+#define V_TX_EN 0x04 /* video transfer enable */
+#define LED 0x08 /* output to pin LED */
+#define SCL_SEL_OD 0x20 /* open-drain mode */
+#define SYS_SEL_48M 0x40 /* system clock 0: 24MHz, 1: 48MHz */
+/* register 0x17 */
+#define MCK_SIZE_MASK 0x1f /* sensor master clock */
+#define SEN_CLK_EN 0x20 /* enable sensor clock */
+#define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */
+
/* V4L2 controls supported by the driver */
static void setbrightness(struct gspca_dev *gspca_dev);
static void setcontrast(struct gspca_dev *gspca_dev);
@@ -1755,141 +1774,6 @@ static void po2030n_probe(struct gspca_dev *gspca_dev)
}
}
-static void bridge_init(struct gspca_dev *gspca_dev,
- const u8 *sn9c1xx)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 reg0102[2];
- const u8 *reg9a;
- static const u8 reg9a_def[] =
- {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
- static const u8 reg9a_spec[] =
- {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
- static const u8 regd4[] = {0x60, 0x00, 0x00};
-
- /* sensor clock already enabled in sd_init */
- /* reg_w1(gspca_dev, 0xf1, 0x00); */
- reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
-
- /* configure gpio */
- reg0102[0] = sn9c1xx[1];
- reg0102[1] = sn9c1xx[2];
- if (gspca_dev->audio)
- reg0102[1] |= 0x04; /* keep the audio connection */
- reg_w(gspca_dev, 0x01, reg0102, 2);
- reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
- reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
- switch (sd->sensor) {
- case SENSOR_GC0307:
- case SENSOR_OV7660:
- case SENSOR_PO1030:
- case SENSOR_PO2030N:
- case SENSOR_SOI768:
- case SENSOR_SP80708:
- reg9a = reg9a_spec;
- break;
- default:
- reg9a = reg9a_def;
- break;
- }
- reg_w(gspca_dev, 0x9a, reg9a, 6);
-
- reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
-
- reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
-
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- reg_w1(gspca_dev, 0x01, 0x43);
- reg_w1(gspca_dev, 0x17, 0x62);
- reg_w1(gspca_dev, 0x01, 0x42);
- reg_w1(gspca_dev, 0x01, 0x42);
- break;
- case SENSOR_GC0307:
- msleep(50);
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0x22);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- msleep(50);
- break;
- case SENSOR_MI0360B:
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0x60);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- break;
- case SENSOR_MT9V111:
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0x61);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- break;
- case SENSOR_OM6802:
- msleep(10);
- reg_w1(gspca_dev, 0x02, 0x73);
- reg_w1(gspca_dev, 0x17, 0x60);
- reg_w1(gspca_dev, 0x01, 0x22);
- msleep(100);
- reg_w1(gspca_dev, 0x01, 0x62);
- reg_w1(gspca_dev, 0x17, 0x64);
- reg_w1(gspca_dev, 0x17, 0x64);
- reg_w1(gspca_dev, 0x01, 0x42);
- msleep(10);
- reg_w1(gspca_dev, 0x01, 0x42);
- i2c_w8(gspca_dev, om6802_init0[0]);
- i2c_w8(gspca_dev, om6802_init0[1]);
- msleep(15);
- reg_w1(gspca_dev, 0x02, 0x71);
- msleep(150);
- break;
- case SENSOR_OV7630:
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0xe2);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- break;
- case SENSOR_OV7648:
- reg_w1(gspca_dev, 0x01, 0x63);
- reg_w1(gspca_dev, 0x17, 0x20);
- reg_w1(gspca_dev, 0x01, 0x62);
- reg_w1(gspca_dev, 0x01, 0x42);
- break;
- case SENSOR_PO1030:
- case SENSOR_SOI768:
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0x20);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- break;
- case SENSOR_PO2030N:
- case SENSOR_OV7660:
- reg_w1(gspca_dev, 0x01, 0x63);
- reg_w1(gspca_dev, 0x17, 0x20);
- reg_w1(gspca_dev, 0x01, 0x62);
- reg_w1(gspca_dev, 0x01, 0x42);
- break;
- case SENSOR_SP80708:
- reg_w1(gspca_dev, 0x01, 0x63);
- reg_w1(gspca_dev, 0x17, 0x20);
- reg_w1(gspca_dev, 0x01, 0x62);
- reg_w1(gspca_dev, 0x01, 0x42);
- msleep(100);
- reg_w1(gspca_dev, 0x02, 0x62);
- break;
- default:
-/* case SENSOR_HV7131R: */
-/* case SENSOR_MI0360: */
-/* case SENSOR_MO4000: */
- reg_w1(gspca_dev, 0x01, 0x43);
- reg_w1(gspca_dev, 0x17, 0x61);
- reg_w1(gspca_dev, 0x01, 0x42);
- if (sd->sensor == SENSOR_HV7131R)
- hv7131r_probe(gspca_dev);
- break;
- }
-}
-
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
@@ -1898,7 +1782,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
sd->bridge = id->driver_info >> 16;
- sd->sensor = id->driver_info;
+ sd->sensor = id->driver_info >> 8;
+ sd->flags = id->driver_info;
cam = &gspca_dev->cam;
if (sd->sensor == SENSOR_ADCM1700) {
@@ -1929,7 +1814,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
/* setup a selector by bridge */
reg_w1(gspca_dev, 0xf1, 0x01);
reg_r(gspca_dev, 0x00, 1);
- reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
+ reg_w1(gspca_dev, 0xf1, 0x00);
reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
regF1 = gspca_dev->usb_buf[0];
if (gspca_dev->usb_err < 0)
@@ -2423,10 +2308,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i;
- u8 reg1, reg17;
+ u8 reg01, reg17;
+ u8 reg0102[2];
const u8 *sn9c1xx;
const u8 (*init)[8];
+ const u8 *reg9a;
int mode;
+ static const u8 reg9a_def[] =
+ {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
+ static const u8 reg9a_spec[] =
+ {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
+ static const u8 regd4[] = {0x60, 0x00, 0x00};
static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
static const u8 CA_adcm1700[] =
@@ -2448,7 +2340,85 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* initialize the bridge */
sn9c1xx = sn_tb[sd->sensor];
- bridge_init(gspca_dev, sn9c1xx);
+
+ /* sensor clock already enabled in sd_init */
+ /* reg_w1(gspca_dev, 0xf1, 0x00); */
+ reg01 = sn9c1xx[1];
+ if (sd->flags & PDN_INV)
+ reg01 ^= S_PDN_INV; /* power down inverted */
+ reg_w1(gspca_dev, 0x01, reg01);
+
+ /* configure gpio */
+ reg0102[0] = reg01;
+ reg0102[1] = sn9c1xx[2];
+ if (gspca_dev->audio)
+ reg0102[1] |= 0x04; /* keep the audio connection */
+ reg_w(gspca_dev, 0x01, reg0102, 2);
+ reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
+ reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
+ switch (sd->sensor) {
+ case SENSOR_GC0307:
+ case SENSOR_OV7660:
+ case SENSOR_PO1030:
+ case SENSOR_PO2030N:
+ case SENSOR_SOI768:
+ case SENSOR_SP80708:
+ reg9a = reg9a_spec;
+ break;
+ default:
+ reg9a = reg9a_def;
+ break;
+ }
+ reg_w(gspca_dev, 0x9a, reg9a, 6);
+
+ reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
+
+ reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
+
+ reg17 = sn9c1xx[0x17];
+ switch (sd->sensor) {
+ case SENSOR_GC0307:
+ msleep(50); /*fixme: is it useful? */
+ break;
+ case SENSOR_OM6802:
+ msleep(10);
+ reg_w1(gspca_dev, 0x02, 0x73);
+ reg17 |= SEN_CLK_EN;
+ reg_w1(gspca_dev, 0x17, reg17);
+ reg_w1(gspca_dev, 0x01, 0x22);
+ msleep(100);
+ reg01 = SCL_SEL_OD | S_PDN_INV;
+ reg17 &= MCK_SIZE_MASK;
+ reg17 |= 0x04; /* clock / 4 */
+ break;
+ }
+ reg01 |= SYS_SEL_48M;
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg17 |= SEN_CLK_EN;
+ reg_w1(gspca_dev, 0x17, reg17);
+ reg01 &= ~S_PWR_DN; /* sensor power on */
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg01 &= ~SYS_SEL_48M;
+ reg_w1(gspca_dev, 0x01, reg01);
+
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ hv7131r_probe(gspca_dev); /*fixme: is it useful? */
+ break;
+ case SENSOR_OM6802:
+ msleep(10);
+ reg_w1(gspca_dev, 0x01, reg01);
+ i2c_w8(gspca_dev, om6802_init0[0]);
+ i2c_w8(gspca_dev, om6802_init0[1]);
+ msleep(15);
+ reg_w1(gspca_dev, 0x02, 0x71);
+ msleep(150);
+ break;
+ case SENSOR_SP80708:
+ msleep(100);
+ reg_w1(gspca_dev, 0x02, 0x62);
+ break;
+ }
/* initialize the sensor */
i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
@@ -2476,30 +2446,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
switch (sd->sensor) {
- case SENSOR_GC0307:
- reg17 = 0xa2;
- break;
- case SENSOR_MT9V111:
- case SENSOR_MI0360B:
- reg17 = 0xe0;
- break;
- case SENSOR_ADCM1700:
- case SENSOR_OV7630:
- reg17 = 0xe2;
- break;
- case SENSOR_OV7648:
- reg17 = 0x20;
- break;
- case SENSOR_OV7660:
- case SENSOR_SOI768:
- reg17 = 0xa0;
- break;
- case SENSOR_PO1030:
- case SENSOR_PO2030N:
- reg17 = 0xa0;
+ case SENSOR_OM6802:
+/* case SENSOR_OV7648: * fixme: sometimes */
break;
default:
- reg17 = 0x60;
+ reg17 |= DEF_EN;
break;
}
reg_w1(gspca_dev, 0x17, reg17);
@@ -2546,95 +2497,67 @@ static int sd_start(struct gspca_dev *gspca_dev)
init = NULL;
mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- if (mode)
- reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
- else
- reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
- reg17 = 0x61; /* 0x:20: enable sensor clock */
+ reg01 |= SYS_SEL_48M | V_TX_EN;
+ reg17 &= ~MCK_SIZE_MASK;
+ reg17 |= 0x02; /* clock / 2 */
switch (sd->sensor) {
case SENSOR_ADCM1700:
init = adcm1700_sensor_param1;
- reg1 = 0x46;
- reg17 = 0xe2;
break;
case SENSOR_GC0307:
init = gc0307_sensor_param1;
- reg17 = 0xa2;
- reg1 = 0x44;
+ break;
+ case SENSOR_HV7131R:
+ case SENSOR_MI0360:
+ if (mode)
+ reg01 |= SYS_SEL_48M; /* 320x240: clk 48Mhz */
+ else
+ reg01 &= ~SYS_SEL_48M; /* 640x480: clk 24Mhz */
+ reg17 &= ~MCK_SIZE_MASK;
+ reg17 |= 0x01; /* clock / 1 */
break;
case SENSOR_MI0360B:
init = mi0360b_sensor_param1;
- reg1 &= ~0x02; /* don't inverse pin S_PWR_DN */
- reg17 = 0xe2;
break;
case SENSOR_MO4000:
- if (mode) {
-/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
- reg1 = 0x06; /* clk 24Mz */
- } else {
- reg17 = 0x22; /* 640 MCKSIZE */
-/* reg1 = 0x06; * 640 clk 24Mz (done) */
+ if (mode) { /* if 320x240 */
+ reg01 &= ~SYS_SEL_48M; /* clk 24Mz */
+ reg17 &= ~MCK_SIZE_MASK;
+ reg17 |= 0x01; /* clock / 1 */
}
break;
case SENSOR_MT9V111:
init = mt9v111_sensor_param1;
- if (mode) {
- reg1 = 0x04; /* 320 clk 48Mhz */
- } else {
-/* reg1 = 0x06; * 640 clk 24Mz (done) */
- reg17 = 0xc2;
- }
break;
case SENSOR_OM6802:
init = om6802_sensor_param1;
- reg17 = 0x64; /* 640 MCKSIZE */
+ if (!mode) { /* if 640x480 */
+ reg17 &= ~MCK_SIZE_MASK;
+ reg17 |= 0x01; /* clock / 4 */
+ }
break;
case SENSOR_OV7630:
init = ov7630_sensor_param1;
- reg17 = 0xe2;
- reg1 = 0x44;
break;
case SENSOR_OV7648:
init = ov7648_sensor_param1;
- reg17 = 0x21;
-/* reg1 = 0x42; * 42 - 46? */
+ reg17 &= ~MCK_SIZE_MASK;
+ reg17 |= 0x01; /* clock / 1 */
break;
case SENSOR_OV7660:
init = ov7660_sensor_param1;
- if (sd->bridge == BRIDGE_SN9C120) {
- if (mode) { /* 320x240 - 160x120 */
- reg17 = 0xa2;
- reg1 = 0x44; /* 48 Mhz, video trf eneble */
- }
- } else {
- reg17 = 0x22;
- reg1 = 0x06; /* 24 Mhz, video trf eneble
- * inverse power down */
- }
break;
case SENSOR_PO1030:
init = po1030_sensor_param1;
- reg17 = 0xa2;
- reg1 = 0x44;
break;
case SENSOR_PO2030N:
init = po2030n_sensor_param1;
- reg1 = 0x46;
- reg17 = 0xa2;
break;
case SENSOR_SOI768:
init = soi768_sensor_param1;
- reg1 = 0x44;
- reg17 = 0xa2;
break;
case SENSOR_SP80708:
init = sp80708_sensor_param1;
- if (mode) {
-/*?? reg1 = 0x04; * 320 clk 48Mhz */
- } else {
- reg1 = 0x46; /* 640 clk 48Mz */
- reg17 = 0xa2;
- }
break;
}
@@ -2684,7 +2607,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
setjpegqual(gspca_dev);
reg_w1(gspca_dev, 0x17, reg17);
- reg_w1(gspca_dev, 0x01, reg1);
+ reg_w1(gspca_dev, 0x01, reg01);
+ sd->reg01 = reg01;
+ sd->reg17 = reg17;
sethvflip(gspca_dev);
setbrightness(gspca_dev);
@@ -2706,41 +2631,64 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
static const u8 stopsoi768[] =
{ 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
- u8 data;
- const u8 *sn9c1xx;
+ u8 reg01;
+ u8 reg17;
- data = 0x0b;
+ reg01 = sd->reg01;
+ reg17 = sd->reg17 & ~SEN_CLK_EN;
switch (sd->sensor) {
+ case SENSOR_ADCM1700:
case SENSOR_GC0307:
- data = 0x29;
+ case SENSOR_PO2030N:
+ case SENSOR_SP80708:
+ reg01 |= LED;
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg01 &= ~(LED | V_TX_EN);
+ reg_w1(gspca_dev, 0x01, reg01);
+/* reg_w1(gspca_dev, 0x02, 0x??); * LED off ? */
break;
case SENSOR_HV7131R:
+ reg01 &= ~V_TX_EN;
+ reg_w1(gspca_dev, 0x01, reg01);
i2c_w8(gspca_dev, stophv7131);
- data = 0x2b;
break;
case SENSOR_MI0360:
case SENSOR_MI0360B:
+ reg01 &= ~V_TX_EN;
+ reg_w1(gspca_dev, 0x01, reg01);
+/* reg_w1(gspca_dev, 0x02, 0x40); * LED off ? */
i2c_w8(gspca_dev, stopmi0360);
- data = 0x29;
break;
- case SENSOR_OV7648:
- i2c_w8(gspca_dev, stopov7648);
- /* fall thru */
case SENSOR_MT9V111:
- case SENSOR_OV7630:
+ case SENSOR_OM6802:
case SENSOR_PO1030:
- data = 0x29;
+ reg01 &= ~V_TX_EN;
+ reg_w1(gspca_dev, 0x01, reg01);
+ break;
+ case SENSOR_OV7630:
+ case SENSOR_OV7648:
+ reg01 &= ~V_TX_EN;
+ reg_w1(gspca_dev, 0x01, reg01);
+ i2c_w8(gspca_dev, stopov7648);
+ break;
+ case SENSOR_OV7660:
+ reg01 &= ~V_TX_EN;
+ reg_w1(gspca_dev, 0x01, reg01);
break;
case SENSOR_SOI768:
i2c_w8(gspca_dev, stopsoi768);
- data = 0x29;
break;
}
- sn9c1xx = sn_tb[sd->sensor];
- reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
- reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
- reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
- reg_w1(gspca_dev, 0x01, data);
+
+ reg01 |= SCL_SEL_OD;
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg01 |= S_PWR_DN; /* sensor power down */
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg_w1(gspca_dev, 0x17, reg17);
+ reg01 &= ~SYS_SEL_48M; /* clock 24MHz */
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg01 |= LED;
+ reg_w1(gspca_dev, 0x01, reg01);
/* Don't disable sensor clock as that disables the button on the cam */
/* reg_w1(gspca_dev, 0xf1, 0x01); */
}
@@ -2954,14 +2902,18 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
#define BS(bridge, sensor) \
.driver_info = (BRIDGE_ ## bridge << 16) \
- | SENSOR_ ## sensor
+ | (SENSOR_ ## sensor << 8)
+#define BSF(bridge, sensor, flags) \
+ .driver_info = (BRIDGE_ ## bridge << 16) \
+ | (SENSOR_ ## sensor << 8) \
+ | (flags)
static const __devinitdata struct usb_device_id device_table[] = {
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
{USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
#endif
- {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
- {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
+ {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, PDN_INV)},
+ {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, PDN_INV)},
{USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
{USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
{USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index 072bd2d1cfa..13565cba237 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -807,8 +807,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd,
if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
csicr1 |= CSICR1_REDGE;
- if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
- csicr1 |= CSICR1_INV_PCLK;
if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
csicr1 |= CSICR1_SOF_POL;
if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH)
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index 1b93207c89e..2f500809f53 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -522,6 +522,7 @@ static int fimc_cap_streamon(struct file *file, void *priv,
INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
fimc->vid_cap.active_buf_cnt = 0;
fimc->vid_cap.frame_count = 0;
+ fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc);
set_bit(ST_CAPT_PEND, &fimc->state);
ret = videobuf_streamon(&fimc->vid_cap.vbq);
@@ -652,6 +653,50 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
return ret;
}
+static int fimc_cap_cropcap(struct file *file, void *fh,
+ struct v4l2_cropcap *cr)
+{
+ struct fimc_frame *f;
+ struct fimc_ctx *ctx = fh;
+ struct fimc_dev *fimc = ctx->fimc_dev;
+
+ if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&fimc->lock))
+ return -ERESTARTSYS;
+
+ f = &ctx->s_frame;
+ cr->bounds.left = 0;
+ cr->bounds.top = 0;
+ cr->bounds.width = f->o_width;
+ cr->bounds.height = f->o_height;
+ cr->defrect = cr->bounds;
+
+ mutex_unlock(&fimc->lock);
+ return 0;
+}
+
+static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
+{
+ struct fimc_frame *f;
+ struct fimc_ctx *ctx = file->private_data;
+ struct fimc_dev *fimc = ctx->fimc_dev;
+
+
+ if (mutex_lock_interruptible(&fimc->lock))
+ return -ERESTARTSYS;
+
+ f = &ctx->s_frame;
+ cr->c.left = f->offs_h;
+ cr->c.top = f->offs_v;
+ cr->c.width = f->width;
+ cr->c.height = f->height;
+
+ mutex_unlock(&fimc->lock);
+ return 0;
+}
+
static int fimc_cap_s_crop(struct file *file, void *fh,
struct v4l2_crop *cr)
{
@@ -716,9 +761,9 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
.vidioc_g_ctrl = fimc_vidioc_g_ctrl,
.vidioc_s_ctrl = fimc_cap_s_ctrl,
- .vidioc_g_crop = fimc_vidioc_g_crop,
+ .vidioc_g_crop = fimc_cap_g_crop,
.vidioc_s_crop = fimc_cap_s_crop,
- .vidioc_cropcap = fimc_vidioc_cropcap,
+ .vidioc_cropcap = fimc_cap_cropcap,
.vidioc_enum_input = fimc_cap_enum_input,
.vidioc_s_input = fimc_cap_s_input,
@@ -785,7 +830,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops,
vid_cap->v4l2_dev.dev, &fimc->irqlock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- sizeof(struct fimc_vid_buffer), (void *)ctx);
+ sizeof(struct fimc_vid_buffer), (void *)ctx, NULL);
ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
if (ret) {
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index 2e7c547894b..bb99f2d805d 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -50,8 +50,8 @@ static struct fimc_fmt fimc_formats[] = {
.planes_cnt = 1,
.flags = FMT_FLAGS_M2M,
}, {
- .name = "XRGB-8-8-8-8, 24 bpp",
- .fourcc = V4L2_PIX_FMT_RGB24,
+ .name = "XRGB-8-8-8-8, 32 bpp",
+ .fourcc = V4L2_PIX_FMT_RGB32,
.depth = 32,
.color = S5P_FIMC_RGB888,
.buff_cnt = 1,
@@ -983,6 +983,7 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
{
struct fimc_ctx *ctx = priv;
struct v4l2_queryctrl *c;
+ int ret = -EINVAL;
c = get_ctrl(qc->id);
if (c) {
@@ -990,10 +991,14 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
return 0;
}
- if (ctx->state & FIMC_CTX_CAP)
- return v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
+ if (ctx->state & FIMC_CTX_CAP) {
+ if (mutex_lock_interruptible(&ctx->fimc_dev->lock))
+ return -ERESTARTSYS;
+ ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
core, queryctrl, qc);
- return -EINVAL;
+ mutex_unlock(&ctx->fimc_dev->lock);
+ }
+ return ret;
}
int fimc_vidioc_g_ctrl(struct file *file, void *priv,
@@ -1115,7 +1120,7 @@ static int fimc_m2m_s_ctrl(struct file *file, void *priv,
return 0;
}
-int fimc_vidioc_cropcap(struct file *file, void *fh,
+static int fimc_m2m_cropcap(struct file *file, void *fh,
struct v4l2_cropcap *cr)
{
struct fimc_frame *frame;
@@ -1139,7 +1144,7 @@ int fimc_vidioc_cropcap(struct file *file, void *fh,
return 0;
}
-int fimc_vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
+static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
{
struct fimc_frame *frame;
struct fimc_ctx *ctx = file->private_data;
@@ -1167,22 +1172,22 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
struct fimc_frame *f;
u32 min_size, halign;
- f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
- &ctx->s_frame : &ctx->d_frame;
-
if (cr->c.top < 0 || cr->c.left < 0) {
v4l2_err(&fimc->m2m.v4l2_dev,
"doesn't support negative values for top & left\n");
return -EINVAL;
}
- f = ctx_get_frame(ctx, cr->type);
- if (IS_ERR(f))
- return PTR_ERR(f);
+ if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ f = (ctx->state & FIMC_CTX_CAP) ? &ctx->s_frame : &ctx->d_frame;
+ else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ ctx->state & FIMC_CTX_M2M)
+ f = &ctx->s_frame;
+ else
+ return -EINVAL;
- min_size = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- ? fimc->variant->min_inp_pixsize
- : fimc->variant->min_out_pixsize;
+ min_size = (f == &ctx->s_frame) ?
+ fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
if (ctx->state & FIMC_CTX_M2M) {
if (fimc->id == 1 && fimc->variant->pix_hoff)
@@ -1233,6 +1238,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
&ctx->s_frame : &ctx->d_frame;
+ if (mutex_lock_interruptible(&fimc->lock))
+ return -ERESTARTSYS;
+
spin_lock_irqsave(&ctx->slock, flags);
if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) {
/* Check to see if scaling ratio is within supported range */
@@ -1241,9 +1249,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
else
ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame);
if (ret) {
- spin_unlock_irqrestore(&ctx->slock, flags);
v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range");
- return -EINVAL;
+ ret = -EINVAL;
+ goto scr_unlock;
}
}
ctx->state |= FIMC_PARAMS;
@@ -1253,7 +1261,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
f->width = cr->c.width;
f->height = cr->c.height;
+scr_unlock:
spin_unlock_irqrestore(&ctx->slock, flags);
+ mutex_unlock(&fimc->lock);
return 0;
}
@@ -1285,9 +1295,9 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
.vidioc_g_ctrl = fimc_vidioc_g_ctrl,
.vidioc_s_ctrl = fimc_m2m_s_ctrl,
- .vidioc_g_crop = fimc_vidioc_g_crop,
+ .vidioc_g_crop = fimc_m2m_g_crop,
.vidioc_s_crop = fimc_m2m_s_crop,
- .vidioc_cropcap = fimc_vidioc_cropcap
+ .vidioc_cropcap = fimc_m2m_cropcap
};
@@ -1396,7 +1406,7 @@ static const struct v4l2_file_operations fimc_m2m_fops = {
.open = fimc_m2m_open,
.release = fimc_m2m_release,
.poll = fimc_m2m_poll,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.mmap = fimc_m2m_mmap,
};
@@ -1736,6 +1746,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
.pix_hoff = 1,
.has_inp_rot = 1,
.has_out_rot = 1,
+ .has_cistatus2 = 1,
.min_inp_pixsize = 16,
.min_out_pixsize = 16,
.hor_offs_align = 1,
@@ -1745,6 +1756,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
static struct samsung_fimc_variant fimc2_variant_s5pv310 = {
.pix_hoff = 1,
+ .has_cistatus2 = 1,
.min_inp_pixsize = 16,
.min_out_pixsize = 16,
.hor_offs_align = 1,
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index 3e107851656..4f047d35f8a 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -13,13 +13,15 @@
/*#define DEBUG*/
+#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/videodev2.h>
#include <media/videobuf-core.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mem2mem.h>
#include <media/v4l2-mediabus.h>
#include <media/s3c_fimc.h>
-#include <linux/videodev2.h>
+
#include "regs-fimc.h"
#define err(fmt, args...) \
@@ -369,6 +371,7 @@ struct fimc_pix_limit {
* @pix_hoff: indicate whether horizontal offset is in pixels or in bytes
* @has_inp_rot: set if has input rotator
* @has_out_rot: set if has output rotator
+ * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision
* @pix_limit: pixel size constraints for the scaler
* @min_inp_pixsize: minimum input pixel size
* @min_out_pixsize: minimum output pixel size
@@ -379,6 +382,7 @@ struct samsung_fimc_variant {
unsigned int pix_hoff:1;
unsigned int has_inp_rot:1;
unsigned int has_out_rot:1;
+ unsigned int has_cistatus2:1;
struct fimc_pix_limit *pix_limit;
u16 min_inp_pixsize;
u16 min_out_pixsize;
@@ -554,11 +558,19 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
return frame;
}
+/* Return an index to the buffer actually being written. */
static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
{
- u32 reg = readl(dev->regs + S5P_CISTATUS);
- return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
- S5P_CISTATUS_FRAMECNT_SHIFT;
+ u32 reg;
+
+ if (dev->variant->has_cistatus2) {
+ reg = readl(dev->regs + S5P_CISTATUS2) & 0x3F;
+ return reg > 0 ? --reg : reg;
+ } else {
+ reg = readl(dev->regs + S5P_CISTATUS);
+ return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
+ S5P_CISTATUS_FRAMECNT_SHIFT;
+ }
}
/* -----------------------------------------------------*/
@@ -594,10 +606,6 @@ int fimc_vidioc_g_fmt(struct file *file, void *priv,
struct v4l2_format *f);
int fimc_vidioc_try_fmt(struct file *file, void *priv,
struct v4l2_format *f);
-int fimc_vidioc_g_crop(struct file *file, void *fh,
- struct v4l2_crop *cr);
-int fimc_vidioc_cropcap(struct file *file, void *fh,
- struct v4l2_cropcap *cr);
int fimc_vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc);
int fimc_vidioc_g_ctrl(struct file *file, void *priv,
diff --git a/drivers/media/video/s5p-fimc/regs-fimc.h b/drivers/media/video/s5p-fimc/regs-fimc.h
index a57daedb5b5..57e33f84fcf 100644
--- a/drivers/media/video/s5p-fimc/regs-fimc.h
+++ b/drivers/media/video/s5p-fimc/regs-fimc.h
@@ -165,6 +165,9 @@
#define S5P_CISTATUS_VVALID_A (1 << 15)
#define S5P_CISTATUS_VVALID_B (1 << 14)
+/* Indexes to the last and the currently processed buffer. */
+#define S5P_CISTATUS2 0x68
+
/* Image capture control */
#define S5P_CIIMGCPT 0xc0
#define S5P_CIIMGCPT_IMGCPTEN (1 << 31)
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 5c209afb0ac..2486520582f 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -1980,7 +1980,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
* we complete the completion.
*/
- if (!csi2->driver || !csi2->driver->owner) {
+ if (!csi2->driver) {
complete(&wait.completion);
/* Either too late, or probing failed */
bus_unregister_notifier(&platform_bus_type, &wait.notifier);
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 335120c2021..052bd6dfa5a 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -405,13 +405,13 @@ static int soc_camera_open(struct file *file)
ret = soc_camera_set_fmt(icd, &f);
if (ret < 0)
goto esfmt;
+
+ ici->ops->init_videobuf(&icd->vb_vidq, icd);
}
file->private_data = icd;
dev_dbg(&icd->dev, "camera device open\n");
- ici->ops->init_videobuf(&icd->vb_vidq, icd);
-
mutex_unlock(&icd->video_lock);
return 0;