Commit 27b350ef authored by Linus Torvalds's avatar Linus Torvalds

Automerge

parents 2e8a9bc4 b64b9783
...@@ -868,124 +868,108 @@ static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) { ...@@ -868,124 +868,108 @@ static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) {
/* video4linux integration */ /* video4linux integration */
/****************************************************************************/ /****************************************************************************/
static int meye_open(struct video_device *dev, int flags) { static int meye_open(struct inode *inode, struct file *file) {
int i; int i, err;
err = video_exclusive_open(inode,file);
if (err < 0)
return err;
down(&meye.lock);
if (meye.open_count) {
up(&meye.lock);
return -EBUSY;
}
meye.open_count++;
if (mchip_dma_alloc()) { if (mchip_dma_alloc()) {
printk(KERN_ERR "meye: mchip framebuffer allocation failed\n"); printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
up(&meye.lock); video_exclusive_release(inode,file);
return -ENOBUFS; return -ENOBUFS;
} }
mchip_hic_stop(); mchip_hic_stop();
meye_initq(&meye.grabq); meye_initq(&meye.grabq);
for (i = 0; i < MEYE_MAX_BUFNBRS; i++) for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
meye.grab_buffer[i].state = MEYE_BUF_UNUSED; meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
up(&meye.lock);
return 0; return 0;
} }
static void meye_close(struct video_device *dev) { static int meye_release(struct inode *inode, struct file *file) {
down(&meye.lock);
meye.open_count--;
mchip_hic_stop(); mchip_hic_stop();
up(&meye.lock); video_exclusive_release(inode,file);
return 0;
} }
static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) { static int meye_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg) {
switch (cmd) { switch (cmd) {
case VIDIOCGCAP: { case VIDIOCGCAP: {
struct video_capability b; struct video_capability *b = arg;
strcpy(b.name,meye.video_dev.name); strcpy(b->name,meye.video_dev.name);
b.type = VID_TYPE_CAPTURE; b->type = VID_TYPE_CAPTURE;
b.channels = 1; b->channels = 1;
b.audios = 0; b->audios = 0;
b.maxwidth = 640; b->maxwidth = 640;
b.maxheight = 480; b->maxheight = 480;
b.minwidth = 320; b->minwidth = 320;
b.minheight = 240; b->minheight = 240;
if(copy_to_user(arg,&b,sizeof(b)))
return -EFAULT;
break; break;
} }
case VIDIOCGCHAN: { case VIDIOCGCHAN: {
struct video_channel v; struct video_channel *v = arg;
if(copy_from_user(&v, arg,sizeof(v))) v->flags = 0;
return -EFAULT; v->tuners = 0;
v.flags = 0; v->type = VIDEO_TYPE_CAMERA;
v.tuners = 0; if (v->channel != 0)
v.type = VIDEO_TYPE_CAMERA;
if (v.channel != 0)
return -EINVAL; return -EINVAL;
strcpy(v.name,"Camera"); strcpy(v->name,"Camera");
if(copy_to_user(arg,&v,sizeof(v)))
return -EFAULT;
break; break;
} }
case VIDIOCSCHAN: { case VIDIOCSCHAN: {
struct video_channel v; struct video_channel *v = arg;
if(copy_from_user(&v, arg,sizeof(v))) if (v->channel != 0)
return -EFAULT;
if (v.channel != 0)
return -EINVAL; return -EINVAL;
break; break;
} }
case VIDIOCGPICT: { case VIDIOCGPICT: {
struct video_picture p = meye.picture; struct video_picture *p = arg;
if(copy_to_user(arg, &p, sizeof(p))) *p = meye.picture;
return -EFAULT;
break; break;
} }
case VIDIOCSPICT: { case VIDIOCSPICT: {
struct video_picture p; struct video_picture *p = arg;
if(copy_from_user(&p, arg,sizeof(p))) if (p->depth != 2)
return -EFAULT;
if (p.depth != 2)
return -EINVAL; return -EINVAL;
if (p.palette != VIDEO_PALETTE_YUV422) if (p->palette != VIDEO_PALETTE_YUV422)
return -EINVAL; return -EINVAL;
down(&meye.lock); down(&meye.lock);
sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS,
p.brightness >> 10); p->brightness >> 10);
sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE,
p.hue >> 10); p->hue >> 10);
sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR, sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR,
p.colour >> 10); p->colour >> 10);
sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST,
p.contrast >> 10); p->contrast >> 10);
memcpy(&meye.picture, &p, sizeof(p)); meye.picture = *p;
up(&meye.lock); up(&meye.lock);
break; break;
} }
case VIDIOCSYNC: { case VIDIOCSYNC: {
int i; int *i = arg;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
if(copy_from_user((void *)&i,arg,sizeof(int))) if (*i < 0 || *i >= gbuffers)
return -EFAULT;
if (i < 0 || i >= gbuffers)
return -EINVAL; return -EINVAL;
switch (meye.grab_buffer[i].state) { switch (meye.grab_buffer[*i].state) {
case MEYE_BUF_UNUSED: case MEYE_BUF_UNUSED:
return -EINVAL; return -EINVAL;
case MEYE_BUF_USING: case MEYE_BUF_USING:
add_wait_queue(&meye.grabq.proc_list, &wait); add_wait_queue(&meye.grabq.proc_list, &wait);
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
while (meye.grab_buffer[i].state == MEYE_BUF_USING) { while (meye.grab_buffer[*i].state == MEYE_BUF_USING) {
schedule(); schedule();
if(signal_pending(current)) { if(signal_pending(current)) {
remove_wait_queue(&meye.grabq.proc_list, &wait); remove_wait_queue(&meye.grabq.proc_list, &wait);
...@@ -997,36 +981,34 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) { ...@@ -997,36 +981,34 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) {
current->state = TASK_RUNNING; current->state = TASK_RUNNING;
/* fall through */ /* fall through */
case MEYE_BUF_DONE: case MEYE_BUF_DONE:
meye.grab_buffer[i].state = MEYE_BUF_UNUSED; meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
} }
break; break;
} }
case VIDIOCMCAPTURE: { case VIDIOCMCAPTURE: {
struct video_mmap vm; struct video_mmap *vm = arg;
int restart = 0; int restart = 0;
if(copy_from_user((void *) &vm, (void *) arg, sizeof(vm))) if (vm->frame >= gbuffers || vm->frame < 0)
return -EFAULT;
if (vm.frame >= gbuffers || vm.frame < 0)
return -EINVAL; return -EINVAL;
if (vm.format != VIDEO_PALETTE_YUV422) if (vm->format != VIDEO_PALETTE_YUV422)
return -EINVAL; return -EINVAL;
if (vm.height * vm.width * 2 > gbufsize) if (vm->height * vm->width * 2 > gbufsize)
return -EINVAL; return -EINVAL;
if (!meye.grab_fbuffer) if (!meye.grab_fbuffer)
return -EINVAL; return -EINVAL;
if (meye.grab_buffer[vm.frame].state != MEYE_BUF_UNUSED) if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED)
return -EBUSY; return -EBUSY;
down(&meye.lock); down(&meye.lock);
if (vm.width == 640 && vm.height == 480) { if (vm->width == 640 && vm->height == 480) {
if (meye.params.subsample) { if (meye.params.subsample) {
meye.params.subsample = 0; meye.params.subsample = 0;
restart = 1; restart = 1;
} }
} }
else if (vm.width == 320 && vm.height == 240) { else if (vm->width == 320 && vm->height == 240) {
if (!meye.params.subsample) { if (!meye.params.subsample) {
meye.params.subsample = 1; meye.params.subsample = 1;
restart = 1; restart = 1;
...@@ -1039,49 +1021,45 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) { ...@@ -1039,49 +1021,45 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) {
if (restart || meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT) if (restart || meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT)
mchip_continuous_start(); mchip_continuous_start();
meye.grab_buffer[vm.frame].state = MEYE_BUF_USING; meye.grab_buffer[vm->frame].state = MEYE_BUF_USING;
meye_pushq(&meye.grabq, vm.frame); meye_pushq(&meye.grabq, vm->frame);
up(&meye.lock); up(&meye.lock);
break; break;
} }
case VIDIOCGMBUF: { case VIDIOCGMBUF: {
struct video_mbuf vm; struct video_mbuf *vm = arg;
int i; int i;
memset(&vm, 0 , sizeof(vm)); memset(vm, 0 , sizeof(*vm));
vm.size = gbufsize * gbuffers; vm->size = gbufsize * gbuffers;
vm.frames = gbuffers; vm->frames = gbuffers;
for (i = 0; i < gbuffers; i++) for (i = 0; i < gbuffers; i++)
vm.offsets[i] = i * gbufsize; vm->offsets[i] = i * gbufsize;
if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
return -EFAULT;
break; break;
} }
case MEYEIOC_G_PARAMS: { case MEYEIOC_G_PARAMS: {
if (copy_to_user(arg, &meye.params, sizeof(meye.params))) struct meye_params *p = arg;
return -EFAULT; *p = meye.params;
break; break;
} }
case MEYEIOC_S_PARAMS: { case MEYEIOC_S_PARAMS: {
struct meye_params jp; struct meye_params *jp = arg;
if (copy_from_user(&jp, arg, sizeof(jp))) if (jp->subsample > 1)
return -EFAULT;
if (jp.subsample > 1)
return -EINVAL; return -EINVAL;
if (jp.quality > 10) if (jp->quality > 10)
return -EINVAL; return -EINVAL;
if (jp.sharpness > 63 || jp.agc > 63 || jp.picture > 63) if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63)
return -EINVAL; return -EINVAL;
if (jp.framerate > 31) if (jp->framerate > 31)
return -EINVAL; return -EINVAL;
down(&meye.lock); down(&meye.lock);
if (meye.params.subsample != jp.subsample || if (meye.params.subsample != jp->subsample ||
meye.params.quality != jp.quality) meye.params.quality != jp->quality)
mchip_hic_stop(); /* need restart */ mchip_hic_stop(); /* need restart */
memcpy(&meye.params, &jp, sizeof(jp)); meye.params = *jp;
sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS, sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS,
meye.params.sharpness); meye.params.sharpness);
sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC, sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC,
...@@ -1093,48 +1071,43 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) { ...@@ -1093,48 +1071,43 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) {
} }
case MEYEIOC_QBUF_CAPT: { case MEYEIOC_QBUF_CAPT: {
int nb; int *nb = arg;
if (copy_from_user((void *) &nb, (void *) arg, sizeof(int)))
return -EFAULT;
if (!meye.grab_fbuffer) if (!meye.grab_fbuffer)
return -EINVAL; return -EINVAL;
if (nb >= gbuffers) if (*nb >= gbuffers)
return -EINVAL; return -EINVAL;
if (nb < 0) { if (*nb < 0) {
/* stop capture */ /* stop capture */
mchip_hic_stop(); mchip_hic_stop();
return 0; return 0;
} }
if (meye.grab_buffer[nb].state != MEYE_BUF_UNUSED) if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED)
return -EBUSY; return -EBUSY;
down(&meye.lock); down(&meye.lock);
if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP) if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
mchip_cont_compression_start(); mchip_cont_compression_start();
meye.grab_buffer[nb].state = MEYE_BUF_USING; meye.grab_buffer[*nb].state = MEYE_BUF_USING;
meye_pushq(&meye.grabq, nb); meye_pushq(&meye.grabq, *nb);
up(&meye.lock); up(&meye.lock);
break; break;
} }
case MEYEIOC_SYNC: { case MEYEIOC_SYNC: {
int i; int *i = arg;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
if(copy_from_user((void *)&i,arg,sizeof(int))) if (*i < 0 || *i >= gbuffers)
return -EFAULT;
if (i < 0 || i >= gbuffers)
return -EINVAL; return -EINVAL;
switch (meye.grab_buffer[i].state) { switch (meye.grab_buffer[*i].state) {
case MEYE_BUF_UNUSED: case MEYE_BUF_UNUSED:
return -EINVAL; return -EINVAL;
case MEYE_BUF_USING: case MEYE_BUF_USING:
add_wait_queue(&meye.grabq.proc_list, &wait); add_wait_queue(&meye.grabq.proc_list, &wait);
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
while (meye.grab_buffer[i].state == MEYE_BUF_USING) { while (meye.grab_buffer[*i].state == MEYE_BUF_USING) {
schedule(); schedule();
if(signal_pending(current)) { if(signal_pending(current)) {
remove_wait_queue(&meye.grabq.proc_list, &wait); remove_wait_queue(&meye.grabq.proc_list, &wait);
...@@ -1146,11 +1119,9 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) { ...@@ -1146,11 +1119,9 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) {
current->state = TASK_RUNNING; current->state = TASK_RUNNING;
/* fall through */ /* fall through */
case MEYE_BUF_DONE: case MEYE_BUF_DONE:
meye.grab_buffer[i].state = MEYE_BUF_UNUSED; meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
} }
i = meye.grab_buffer[i].size; *i = meye.grab_buffer[*i].size;
if (copy_to_user(arg, (void *)&i, sizeof(int)))
return -EFAULT;
break; break;
} }
...@@ -1172,7 +1143,7 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) { ...@@ -1172,7 +1143,7 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) {
} }
case MEYEIOC_STILLJCAPT: { case MEYEIOC_STILLJCAPT: {
int len = -1; int *len = arg;
if (!meye.grab_fbuffer) if (!meye.grab_fbuffer)
return -EINVAL; return -EINVAL;
...@@ -1180,14 +1151,13 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) { ...@@ -1180,14 +1151,13 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) {
return -EBUSY; return -EBUSY;
down(&meye.lock); down(&meye.lock);
meye.grab_buffer[0].state = MEYE_BUF_USING; meye.grab_buffer[0].state = MEYE_BUF_USING;
while (len == -1) { *len = -1;
while (*len == -1) {
mchip_take_picture(); mchip_take_picture();
len = mchip_compress_frame(meye.grab_fbuffer, gbufsize); *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);
} }
meye.grab_buffer[0].state = MEYE_BUF_DONE; meye.grab_buffer[0].state = MEYE_BUF_DONE;
up(&meye.lock); up(&meye.lock);
if (copy_to_user(arg, (void *)&len, sizeof(int)))
return -EFAULT;
break; break;
} }
...@@ -1199,10 +1169,10 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) { ...@@ -1199,10 +1169,10 @@ static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) {
return 0; return 0;
} }
static int meye_mmap(struct vm_area_struct *vma, struct video_device *dev, const char *adr, static int meye_mmap(struct file *file, struct vm_area_struct *vma) {
unsigned long size) { unsigned long start = vma->vm_start;
unsigned long start=(unsigned long) adr; unsigned long size = vma->vm_end - vma->vm_start;
unsigned long page,pos; unsigned long page, pos;
down(&meye.lock); down(&meye.lock);
if (size > gbuffers * gbufsize) { if (size > gbuffers * gbufsize) {
...@@ -1234,15 +1204,22 @@ static int meye_mmap(struct vm_area_struct *vma, struct video_device *dev, const ...@@ -1234,15 +1204,22 @@ static int meye_mmap(struct vm_area_struct *vma, struct video_device *dev, const
return 0; return 0;
} }
static struct file_operations meye_fops = {
owner: THIS_MODULE,
open: meye_open,
release: meye_release,
mmap: meye_mmap,
ioctl: video_generic_ioctl,
llseek: no_llseek,
};
static struct video_device meye_template = { static struct video_device meye_template = {
owner: THIS_MODULE, owner: THIS_MODULE,
name: "meye", name: "meye",
type: VID_TYPE_CAPTURE, type: VID_TYPE_CAPTURE,
hardware: VID_HARDWARE_MEYE, hardware: VID_HARDWARE_MEYE,
open: meye_open, fops: &meye_fops,
close: meye_close, kernel_ioctl: meye_ioctl,
ioctl: meye_ioctl,
mmap: meye_mmap,
}; };
static int __devinit meye_probe(struct pci_dev *pcidev, static int __devinit meye_probe(struct pci_dev *pcidev,
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#define _MEYE_PRIV_H_ #define _MEYE_PRIV_H_
#define MEYE_DRIVER_MAJORVERSION 1 #define MEYE_DRIVER_MAJORVERSION 1
#define MEYE_DRIVER_MINORVERSION 2 #define MEYE_DRIVER_MINORVERSION 3
/****************************************************************************/ /****************************************************************************/
/* Motion JPEG chip registers */ /* Motion JPEG chip registers */
...@@ -300,7 +300,6 @@ struct meye { ...@@ -300,7 +300,6 @@ struct meye {
struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS]; struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS];
/* other */ /* other */
unsigned int open_count; /* open() count */
struct semaphore lock; /* semaphore for open/mmap... */ struct semaphore lock; /* semaphore for open/mmap... */
struct meye_queue grabq; /* queue for buffers to be grabbed */ struct meye_queue grabq; /* queue for buffers to be grabbed */
......
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