Commit e82bb314 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 79534f23 501aaa11
...@@ -26,8 +26,8 @@ static struct ir_scancode rc6_mce[] = { ...@@ -26,8 +26,8 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f040a, KEY_DELETE }, { 0x800f040a, KEY_DELETE },
{ 0x800f040b, KEY_ENTER }, { 0x800f040b, KEY_ENTER },
{ 0x800f040c, KEY_POWER }, { 0x800f040c, KEY_POWER }, /* PC Power */
{ 0x800f040d, KEY_PROG1 }, /* Windows MCE button */ { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
{ 0x800f040e, KEY_MUTE }, { 0x800f040e, KEY_MUTE },
{ 0x800f040f, KEY_INFO }, { 0x800f040f, KEY_INFO },
...@@ -56,31 +56,32 @@ static struct ir_scancode rc6_mce[] = { ...@@ -56,31 +56,32 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f0422, KEY_OK }, { 0x800f0422, KEY_OK },
{ 0x800f0423, KEY_EXIT }, { 0x800f0423, KEY_EXIT },
{ 0x800f0424, KEY_DVD }, { 0x800f0424, KEY_DVD },
{ 0x800f0425, KEY_TUNER }, /* LiveTV */ { 0x800f0425, KEY_TUNER }, /* LiveTV */
{ 0x800f0426, KEY_EPG }, /* Guide */ { 0x800f0426, KEY_EPG }, /* Guide */
{ 0x800f0427, KEY_ZOOM }, /* Aspect */ { 0x800f0427, KEY_ZOOM }, /* Aspect */
{ 0x800f043a, KEY_BRIGHTNESSUP }, { 0x800f043a, KEY_BRIGHTNESSUP },
{ 0x800f0446, KEY_TV }, { 0x800f0446, KEY_TV },
{ 0x800f0447, KEY_AUDIO }, /* My Music */ { 0x800f0447, KEY_AUDIO }, /* My Music */
{ 0x800f0448, KEY_PVR }, /* RecordedTV */ { 0x800f0448, KEY_PVR }, /* RecordedTV */
{ 0x800f0449, KEY_CAMERA }, { 0x800f0449, KEY_CAMERA },
{ 0x800f044a, KEY_VIDEO }, { 0x800f044a, KEY_VIDEO },
{ 0x800f044c, KEY_LANGUAGE }, { 0x800f044c, KEY_LANGUAGE },
{ 0x800f044d, KEY_TITLE }, { 0x800f044d, KEY_TITLE },
{ 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */ { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
{ 0x800f0450, KEY_RADIO }, { 0x800f0450, KEY_RADIO },
{ 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */ { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
{ 0x800f045b, KEY_RED }, { 0x800f045b, KEY_RED },
{ 0x800f045c, KEY_GREEN }, { 0x800f045c, KEY_GREEN },
{ 0x800f045d, KEY_YELLOW }, { 0x800f045d, KEY_YELLOW },
{ 0x800f045e, KEY_BLUE }, { 0x800f045e, KEY_BLUE },
{ 0x800f0465, KEY_POWER2 }, /* TV Power */
{ 0x800f046e, KEY_PLAYPAUSE }, { 0x800f046e, KEY_PLAYPAUSE },
{ 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */ { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
{ 0x800f0480, KEY_BRIGHTNESSDOWN }, { 0x800f0480, KEY_BRIGHTNESSDOWN },
{ 0x800f0481, KEY_PLAYPAUSE }, { 0x800f0481, KEY_PLAYPAUSE },
......
...@@ -522,10 +522,8 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait) ...@@ -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); dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
if (!ir->attached) { if (!ir->attached)
mutex_unlock(&ir->irctl_lock);
return POLLERR; return POLLERR;
}
poll_wait(file, &ir->buf->wait_poll, wait); poll_wait(file, &ir->buf->wait_poll, wait);
...@@ -649,18 +647,18 @@ ssize_t lirc_dev_fop_read(struct file *file, ...@@ -649,18 +647,18 @@ ssize_t lirc_dev_fop_read(struct file *file,
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
if (mutex_lock_interruptible(&ir->irctl_lock)) if (mutex_lock_interruptible(&ir->irctl_lock)) {
return -ERESTARTSYS; ret = -ERESTARTSYS;
goto out_unlocked;
}
if (!ir->attached) { if (!ir->attached) {
mutex_unlock(&ir->irctl_lock); ret = -ENODEV;
return -ENODEV; goto out_locked;
} }
if (length % ir->chunk_size) { if (length % ir->chunk_size) {
dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n", ret = -EINVAL;
ir->d.name, ir->d.minor); goto out_locked;
mutex_unlock(&ir->irctl_lock);
return -EINVAL;
} }
/* /*
...@@ -711,18 +709,23 @@ ssize_t lirc_dev_fop_read(struct file *file, ...@@ -711,18 +709,23 @@ ssize_t lirc_dev_fop_read(struct file *file,
lirc_buffer_read(ir->buf, buf); lirc_buffer_read(ir->buf, buf);
ret = copy_to_user((void *)buffer+written, buf, ret = copy_to_user((void *)buffer+written, buf,
ir->buf->chunk_size); 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); remove_wait_queue(&ir->buf->wait_poll, &wait);
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
out_locked:
mutex_unlock(&ir->irctl_lock); mutex_unlock(&ir->irctl_lock);
out_unlocked: out_unlocked:
kfree(buf); kfree(buf);
dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n", 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; return ret ? ret : written;
} }
......
This diff is collapsed.
...@@ -603,6 +603,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) ...@@ -603,6 +603,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
count = nvt->pkts; count = nvt->pkts;
nvt_dbg_verbose("Processing buffer of len %d", count); nvt_dbg_verbose("Processing buffer of len %d", count);
init_ir_raw_event(&rawir);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
nvt->pkts--; nvt->pkts--;
sample = nvt->buf[i]; sample = nvt->buf[i];
...@@ -643,11 +645,15 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) ...@@ -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 * indicates end of IR signal, but new data incoming. In both
* cases, it means we're ready to call ir_raw_event_handle * cases, it means we're ready to call ir_raw_event_handle
*/ */
if (sample == BUF_PULSE_BIT || ((sample != BUF_LEN_MASK) && if ((sample == BUF_PULSE_BIT) && nvt->pkts) {
(sample & BUF_REPEAT_MASK) == BUF_REPEAT_BYTE)) nvt_dbg("Calling ir_raw_event_handle (signal end)\n");
ir_raw_event_handle(nvt->rdev); 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) { if (nvt->pkts) {
nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts); nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts);
nvt->pkts = 0; nvt->pkts = 0;
......
...@@ -34,8 +34,9 @@ ...@@ -34,8 +34,9 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/usb.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <media/ir-core.h> #include <media/ir-core.h>
#define DRIVER_VERSION "1.61" #define DRIVER_VERSION "1.61"
...@@ -140,7 +141,9 @@ static struct usb_driver streamzap_driver = { ...@@ -140,7 +141,9 @@ static struct usb_driver streamzap_driver = {
static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir) 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, static void sz_push_full_pulse(struct streamzap_ir *sz,
...@@ -167,7 +170,6 @@ 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 *= 1000;
rawir.duration &= IR_MAX_DURATION; rawir.duration &= IR_MAX_DURATION;
} }
dev_dbg(sz->dev, "ls %u\n", rawir.duration);
sz_push(sz, rawir); sz_push(sz, rawir);
sz->idle = false; sz->idle = false;
...@@ -180,7 +182,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, ...@@ -180,7 +182,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
sz->sum += rawir.duration; sz->sum += rawir.duration;
rawir.duration *= 1000; rawir.duration *= 1000;
rawir.duration &= IR_MAX_DURATION; rawir.duration &= IR_MAX_DURATION;
dev_dbg(sz->dev, "p %u\n", rawir.duration);
sz_push(sz, rawir); sz_push(sz, rawir);
} }
...@@ -200,7 +201,6 @@ static void sz_push_full_space(struct streamzap_ir *sz, ...@@ -200,7 +201,6 @@ static void sz_push_full_space(struct streamzap_ir *sz,
rawir.duration += SZ_RESOLUTION / 2; rawir.duration += SZ_RESOLUTION / 2;
sz->sum += rawir.duration; sz->sum += rawir.duration;
rawir.duration *= 1000; rawir.duration *= 1000;
dev_dbg(sz->dev, "s %u\n", rawir.duration);
sz_push(sz, rawir); sz_push(sz, rawir);
} }
...@@ -221,8 +221,6 @@ static void streamzap_callback(struct urb *urb) ...@@ -221,8 +221,6 @@ static void streamzap_callback(struct urb *urb)
struct streamzap_ir *sz; struct streamzap_ir *sz;
unsigned int i; unsigned int i;
int len; int len;
static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
IR_MAX_DURATION) | 0x03000000);
if (!urb) if (!urb)
return; return;
...@@ -246,7 +244,7 @@ static void streamzap_callback(struct urb *urb) ...@@ -246,7 +244,7 @@ static void streamzap_callback(struct urb *urb)
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
for (i = 0; i < len; i++) { 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]); i, (unsigned char)sz->buf_in[i]);
switch (sz->decoder_state) { switch (sz->decoder_state) {
case PulseSpace: case PulseSpace:
...@@ -273,7 +271,7 @@ static void streamzap_callback(struct urb *urb) ...@@ -273,7 +271,7 @@ static void streamzap_callback(struct urb *urb)
DEFINE_IR_RAW_EVENT(rawir); DEFINE_IR_RAW_EVENT(rawir);
rawir.pulse = false; rawir.pulse = false;
rawir.duration = timeout; rawir.duration = sz->props->timeout;
sz->idle = true; sz->idle = true;
if (sz->timeout_enabled) if (sz->timeout_enabled)
sz_push(sz, rawir); sz_push(sz, rawir);
...@@ -335,6 +333,9 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz) ...@@ -335,6 +333,9 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
sz->props = props; 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); ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "remote input device register failed\n"); dev_err(dev, "remote input device register failed\n");
...@@ -444,6 +445,8 @@ static int __devinit streamzap_probe(struct usb_interface *intf, ...@@ -444,6 +445,8 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
sz->decoder_state = PulseSpace; sz->decoder_state = PulseSpace;
/* FIXME: don't yet have a way to set this */ /* FIXME: don't yet have a way to set this */
sz->timeout_enabled = true; sz->timeout_enabled = true;
sz->props->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
IR_MAX_DURATION) | 0x03000000);
#if 0 #if 0
/* not yet supported, depends on patches from maxim */ /* not yet supported, depends on patches from maxim */
/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */ /* 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, ...@@ -807,8 +807,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd,
if (common_flags & SOCAM_PCLK_SAMPLE_RISING) if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
csicr1 |= CSICR1_REDGE; csicr1 |= CSICR1_REDGE;
if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
csicr1 |= CSICR1_INV_PCLK;
if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
csicr1 |= CSICR1_SOF_POL; csicr1 |= CSICR1_SOF_POL;
if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH) if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH)
......
...@@ -522,6 +522,7 @@ static int fimc_cap_streamon(struct file *file, void *priv, ...@@ -522,6 +522,7 @@ static int fimc_cap_streamon(struct file *file, void *priv,
INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
fimc->vid_cap.active_buf_cnt = 0; fimc->vid_cap.active_buf_cnt = 0;
fimc->vid_cap.frame_count = 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); set_bit(ST_CAPT_PEND, &fimc->state);
ret = videobuf_streamon(&fimc->vid_cap.vbq); ret = videobuf_streamon(&fimc->vid_cap.vbq);
...@@ -652,6 +653,50 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv, ...@@ -652,6 +653,50 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
return ret; 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, static int fimc_cap_s_crop(struct file *file, void *fh,
struct v4l2_crop *cr) struct v4l2_crop *cr)
{ {
...@@ -716,9 +761,9 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { ...@@ -716,9 +761,9 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
.vidioc_g_ctrl = fimc_vidioc_g_ctrl, .vidioc_g_ctrl = fimc_vidioc_g_ctrl,
.vidioc_s_ctrl = fimc_cap_s_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_s_crop = fimc_cap_s_crop,
.vidioc_cropcap = fimc_vidioc_cropcap, .vidioc_cropcap = fimc_cap_cropcap,
.vidioc_enum_input = fimc_cap_enum_input, .vidioc_enum_input = fimc_cap_enum_input,
.vidioc_s_input = fimc_cap_s_input, .vidioc_s_input = fimc_cap_s_input,
...@@ -785,7 +830,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc) ...@@ -785,7 +830,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops, videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops,
vid_cap->v4l2_dev.dev, &fimc->irqlock, vid_cap->v4l2_dev.dev, &fimc->irqlock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, 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); ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
if (ret) { if (ret) {
......
...@@ -50,8 +50,8 @@ static struct fimc_fmt fimc_formats[] = { ...@@ -50,8 +50,8 @@ static struct fimc_fmt fimc_formats[] = {
.planes_cnt = 1, .planes_cnt = 1,
.flags = FMT_FLAGS_M2M, .flags = FMT_FLAGS_M2M,
}, { }, {
.name = "XRGB-8-8-8-8, 24 bpp", .name = "XRGB-8-8-8-8, 32 bpp",
.fourcc = V4L2_PIX_FMT_RGB24, .fourcc = V4L2_PIX_FMT_RGB32,
.depth = 32, .depth = 32,
.color = S5P_FIMC_RGB888, .color = S5P_FIMC_RGB888,
.buff_cnt = 1, .buff_cnt = 1,
...@@ -983,6 +983,7 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv, ...@@ -983,6 +983,7 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
{ {
struct fimc_ctx *ctx = priv; struct fimc_ctx *ctx = priv;
struct v4l2_queryctrl *c; struct v4l2_queryctrl *c;
int ret = -EINVAL;
c = get_ctrl(qc->id); c = get_ctrl(qc->id);
if (c) { if (c) {
...@@ -990,10 +991,14 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv, ...@@ -990,10 +991,14 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
return 0; return 0;
} }
if (ctx->state & FIMC_CTX_CAP) if (ctx->state & FIMC_CTX_CAP) {
return v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd, if (mutex_lock_interruptible(&ctx->fimc_dev->lock))
return -ERESTARTSYS;
ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
core, queryctrl, qc); core, queryctrl, qc);
return -EINVAL; mutex_unlock(&ctx->fimc_dev->lock);
}
return ret;
} }
int fimc_vidioc_g_ctrl(struct file *file, void *priv, 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, ...@@ -1115,7 +1120,7 @@ static int fimc_m2m_s_ctrl(struct file *file, void *priv,
return 0; 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 v4l2_cropcap *cr)
{ {
struct fimc_frame *frame; struct fimc_frame *frame;
...@@ -1139,7 +1144,7 @@ int fimc_vidioc_cropcap(struct file *file, void *fh, ...@@ -1139,7 +1144,7 @@ int fimc_vidioc_cropcap(struct file *file, void *fh,
return 0; 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_frame *frame;
struct fimc_ctx *ctx = file->private_data; struct fimc_ctx *ctx = file->private_data;
...@@ -1167,22 +1172,22 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr) ...@@ -1167,22 +1172,22 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
struct fimc_frame *f; struct fimc_frame *f;
u32 min_size, halign; 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) { if (cr->c.top < 0 || cr->c.left < 0) {
v4l2_err(&fimc->m2m.v4l2_dev, v4l2_err(&fimc->m2m.v4l2_dev,
"doesn't support negative values for top & left\n"); "doesn't support negative values for top & left\n");
return -EINVAL; return -EINVAL;
} }
f = ctx_get_frame(ctx, cr->type); if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
if (IS_ERR(f)) f = (ctx->state & FIMC_CTX_CAP) ? &ctx->s_frame : &ctx->d_frame;
return PTR_ERR(f); 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) min_size = (f == &ctx->s_frame) ?
? fimc->variant->min_inp_pixsize fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
: fimc->variant->min_out_pixsize;
if (ctx->state & FIMC_CTX_M2M) { if (ctx->state & FIMC_CTX_M2M) {
if (fimc->id == 1 && fimc->variant->pix_hoff) 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) ...@@ -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) ? f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
&ctx->s_frame : &ctx->d_frame; &ctx->s_frame : &ctx->d_frame;
if (mutex_lock_interruptible(&fimc->lock))
return -ERESTARTSYS;
spin_lock_irqsave(&ctx->slock, flags); spin_lock_irqsave(&ctx->slock, flags);
if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) { if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) {
/* Check to see if scaling ratio is within supported range */ /* 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) ...@@ -1241,9 +1249,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
else else
ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame); ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame);
if (ret) { if (ret) {
spin_unlock_irqrestore(&ctx->slock, flags);
v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range");
return -EINVAL; ret = -EINVAL;
goto scr_unlock;
} }
} }
ctx->state |= FIMC_PARAMS; ctx->state |= FIMC_PARAMS;
...@@ -1253,7 +1261,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) ...@@ -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->width = cr->c.width;
f->height = cr->c.height; f->height = cr->c.height;
scr_unlock:
spin_unlock_irqrestore(&ctx->slock, flags); spin_unlock_irqrestore(&ctx->slock, flags);
mutex_unlock(&fimc->lock);
return 0; return 0;
} }
...@@ -1285,9 +1295,9 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { ...@@ -1285,9 +1295,9 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
.vidioc_g_ctrl = fimc_vidioc_g_ctrl, .vidioc_g_ctrl = fimc_vidioc_g_ctrl,
.vidioc_s_ctrl = fimc_m2m_s_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_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 = { ...@@ -1396,7 +1406,7 @@ static const struct v4l2_file_operations fimc_m2m_fops = {
.open = fimc_m2m_open, .open = fimc_m2m_open,
.release = fimc_m2m_release, .release = fimc_m2m_release,
.poll = fimc_m2m_poll, .poll = fimc_m2m_poll,
.ioctl = video_ioctl2, .unlocked_ioctl = video_ioctl2,
.mmap = fimc_m2m_mmap, .mmap = fimc_m2m_mmap,
}; };
...@@ -1736,6 +1746,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = { ...@@ -1736,6 +1746,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
.pix_hoff = 1, .pix_hoff = 1,
.has_inp_rot = 1, .has_inp_rot = 1,
.has_out_rot = 1, .has_out_rot = 1,
.has_cistatus2 = 1,
.min_inp_pixsize = 16, .min_inp_pixsize = 16,
.min_out_pixsize = 16, .min_out_pixsize = 16,
.hor_offs_align = 1, .hor_offs_align = 1,
...@@ -1745,6 +1756,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = { ...@@ -1745,6 +1756,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
static struct samsung_fimc_variant fimc2_variant_s5pv310 = { static struct samsung_fimc_variant fimc2_variant_s5pv310 = {
.pix_hoff = 1, .pix_hoff = 1,
.has_cistatus2 = 1,
.min_inp_pixsize = 16, .min_inp_pixsize = 16,
.min_out_pixsize = 16, .min_out_pixsize = 16,
.hor_offs_align = 1, .hor_offs_align = 1,
......
...@@ -13,13 +13,15 @@ ...@@ -13,13 +13,15 @@
/*#define DEBUG*/ /*#define DEBUG*/
#include <linux/sched.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/videodev2.h>
#include <media/videobuf-core.h> #include <media/videobuf-core.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>
#include <media/v4l2-mem2mem.h> #include <media/v4l2-mem2mem.h>
#include <media/v4l2-mediabus.h> #include <media/v4l2-mediabus.h>
#include <media/s3c_fimc.h> #include <media/s3c_fimc.h>
#include <linux/videodev2.h>
#include "regs-fimc.h" #include "regs-fimc.h"
#define err(fmt, args...) \ #define err(fmt, args...) \
...@@ -369,6 +371,7 @@ struct fimc_pix_limit { ...@@ -369,6 +371,7 @@ struct fimc_pix_limit {
* @pix_hoff: indicate whether horizontal offset is in pixels or in bytes * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes
* @has_inp_rot: set if has input rotator * @has_inp_rot: set if has input rotator
* @has_out_rot: set if has output 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 * @pix_limit: pixel size constraints for the scaler
* @min_inp_pixsize: minimum input pixel size * @min_inp_pixsize: minimum input pixel size
* @min_out_pixsize: minimum output pixel size * @min_out_pixsize: minimum output pixel size
...@@ -379,6 +382,7 @@ struct samsung_fimc_variant { ...@@ -379,6 +382,7 @@ struct samsung_fimc_variant {
unsigned int pix_hoff:1; unsigned int pix_hoff:1;
unsigned int has_inp_rot:1; unsigned int has_inp_rot:1;
unsigned int has_out_rot:1; unsigned int has_out_rot:1;
unsigned int has_cistatus2:1;
struct fimc_pix_limit *pix_limit; struct fimc_pix_limit *pix_limit;
u16 min_inp_pixsize; u16 min_inp_pixsize;
u16 min_out_pixsize; u16 min_out_pixsize;
...@@ -554,11 +558,19 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx, ...@@ -554,11 +558,19 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
return frame; return frame;
} }
/* Return an index to the buffer actually being written. */
static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev) static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
{ {
u32 reg = readl(dev->regs + S5P_CISTATUS); u32 reg;
return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
S5P_CISTATUS_FRAMECNT_SHIFT; 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, ...@@ -594,10 +606,6 @@ int fimc_vidioc_g_fmt(struct file *file, void *priv,
struct v4l2_format *f); struct v4l2_format *f);
int fimc_vidioc_try_fmt(struct file *file, void *priv, int fimc_vidioc_try_fmt(struct file *file, void *priv,
struct v4l2_format *f); 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, int fimc_vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc); struct v4l2_queryctrl *qc);
int fimc_vidioc_g_ctrl(struct file *file, void *priv, int fimc_vidioc_g_ctrl(struct file *file, void *priv,
......
...@@ -165,6 +165,9 @@ ...@@ -165,6 +165,9 @@
#define S5P_CISTATUS_VVALID_A (1 << 15) #define S5P_CISTATUS_VVALID_A (1 << 15)
#define S5P_CISTATUS_VVALID_B (1 << 14) #define S5P_CISTATUS_VVALID_B (1 << 14)
/* Indexes to the last and the currently processed buffer. */
#define S5P_CISTATUS2 0x68
/* Image capture control */ /* Image capture control */
#define S5P_CIIMGCPT 0xc0 #define S5P_CIIMGCPT 0xc0
#define S5P_CIIMGCPT_IMGCPTEN (1 << 31) #define S5P_CIIMGCPT_IMGCPTEN (1 << 31)
......
...@@ -1980,7 +1980,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev) ...@@ -1980,7 +1980,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
* we complete the completion. * we complete the completion.
*/ */
if (!csi2->driver || !csi2->driver->owner) { if (!csi2->driver) {
complete(&wait.completion); complete(&wait.completion);
/* Either too late, or probing failed */ /* Either too late, or probing failed */
bus_unregister_notifier(&platform_bus_type, &wait.notifier); bus_unregister_notifier(&platform_bus_type, &wait.notifier);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment