mirror of https://gitee.com/openkylin/linux.git
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (21 commits) [media] mceusb: set a default rx timeout [media] mceusb: fix inverted mask inversion logic [media] mceusb: add another Fintek device ID [media] lirc_dev: fixes in lirc_dev_fop_read() [media] lirc_dev: stray unlock in lirc_dev_fop_poll() [media] rc: fix sysfs entry for mceusb and streamzap [media] streamzap: merge timeout space with trailing space [media] mceusb: fix keybouce issue after parser simplification [media] IR: add tv power scancode to rc6 mce keymap [media] mceusb: buffer parsing fixups for 1st-gen device [media] mceusb: fix up reporting of trailing space [media] nuvoton-cir: improve buffer parsing responsiveness [media] mceusb: add support for Conexant Hybrid TV RDU253S [media] s5p-fimc: Fix output DMA handling in S5PV310 IP revisions [media] s5p-fimc: Use correct fourcc code for 32-bit RGB format [media] s5p-fimc: Convert m2m driver to unlocked_ioctl [media] s5p-fimc: Explicitly add required header file [media] s5p-fimc: Fix vidioc_g_crop/cropcap on camera sensor [media] s5p-fimc: BKL lock removal - compilation fix [media] soc-camera: fix static build of the sh_mobile_csi2.c driver ...
This commit is contained in:
commit
e82bb314ea
|
@ -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 },
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
|
|||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue