Commit 8f122be8 authored by Luca Risolia's avatar Luca Risolia Committed by Greg Kroah-Hartman

[PATCH] USB: SN9C10x driver updates

SN9C10x driver updates.

Changes:

@ Fix the sysfs interface
@ Fix allocated minor number after device detection
+ Add "force_munmap" module parameter
+ Documentation updates
+ Add support for old VIDIOC_S_PARM_OLD and VIDIOC_S_CTRL_OLD ioctl's
Signed-off-by: default avatarLuca Risolia <luca.risolia@studio.unibo.it>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 2abe301b
......@@ -26,7 +26,7 @@ Index
1. Copyright
============
Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>
Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>
2. Disclaimer
......@@ -165,6 +165,17 @@ Description: Specify V4L2 minor mode number:
other camera.
Default: -1
-------------------------------------------------------------------------------
Name: force_munmap;
Type: bool array (min = 0, max = 64)
Syntax: <0|1[,...]>
Description: Force the application to unmap previously mapped buffer memory
before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
all the applications support this feature. This parameter is
specific for each detected camera.
0 = do not force memory unmapping"
1 = force memory unmapping (save memory)"
Default: 0
-------------------------------------------------------------------------------
Name: debug
Type: int
Syntax: <n>
......@@ -362,11 +373,11 @@ rules:
file descriptor. Once it is selected, the application must close and reopen the
device to switch to the other I/O method;
- previously mapped buffer memory must always be unmapped before calling any
of the "VIDIOC_S_CROP", "VIDIOC_TRY_FMT" and "VIDIOC_S_FMT" ioctl's. The same
number of buffers as before will be allocated again to match the size of the
new video frames, so you have to map the buffers again before any I/O attempts
on them.
- although it is not mandatory, previously mapped buffer memory should always
be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's.
The same number of buffers as before will be allocated again to match the size
of the new video frames, so you have to map the buffers again before any I/O
attempts on them.
Consistently with the hardware limits, this driver also supports image
downscaling with arbitrary scaling factors from 1, 2 and 4 in both directions.
......
/***************************************************************************
* V4L2 driver for SN9C10x PC Camera Controllers *
* *
* Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
* Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
......@@ -42,6 +42,7 @@
#define SN9C102_DEBUG_LEVEL 2
#define SN9C102_MAX_DEVICES 64
#define SN9C102_PRESERVE_IMGSCALE 0
#define SN9C102_FORCE_MUNMAP 0
#define SN9C102_MAX_FRAMES 32
#define SN9C102_URBS 2
#define SN9C102_ISO_PACKETS 7
......@@ -55,8 +56,8 @@
#define SN9C102_MODULE_AUTHOR "(C) 2004 Luca Risolia"
#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
#define SN9C102_MODULE_LICENSE "GPL"
#define SN9C102_MODULE_VERSION "1:1.20"
#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 20)
#define SN9C102_MODULE_VERSION "1:1.22"
#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 22)
enum sn9c102_bridge {
BRIDGE_SN9C101 = 0x01,
......@@ -109,6 +110,10 @@ struct sn9c102_sysfs_attr {
sn9c102_sof_header_t frame_header;
};
struct sn9c102_module_param {
u8 force_munmap;
};
static DECLARE_MUTEX(sn9c102_sysfs_lock);
static DECLARE_RWSEM(sn9c102_disconnect);
......@@ -138,6 +143,8 @@ struct sn9c102_device {
sn9c102_sof_header_t sof_header;
u16 reg[32];
struct sn9c102_module_param module_param;
enum sn9c102_dev_state state;
u8 users;
......
/***************************************************************************
* V4L2 driver for SN9C10x PC Camera Controllers *
* *
* Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
* Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
......@@ -37,6 +37,7 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/page-flags.h>
#include <linux/byteorder/generic.h>
#include <asm/page.h>
#include <asm/uaccess.h>
......@@ -65,6 +66,20 @@ MODULE_PARM_DESC(video_nr,
"\none and for every other camera."
"\n");
static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] =
SN9C102_FORCE_MUNMAP};
module_param_array(force_munmap, bool, NULL, 0444);
MODULE_PARM_DESC(force_munmap,
"\n<0|1[,...]> Force the application to unmap previously "
"\nmapped buffer memory before calling any VIDIOC_S_CROP or "
"\nVIDIOC_S_FMT ioctl's. Not all the applications support "
"\nthis feature. This parameter is specific for each "
"\ndetected camera."
"\n 0 = do not force memory unmapping"
"\n 1 = force memory unmapping (save memory)"
"\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
"\n");
#ifdef SN9C102_DEBUG
static unsigned short debug = SN9C102_DEBUG_LEVEL;
module_param(debug, ushort, 0644);
......@@ -141,10 +156,16 @@ static void rvfree(void* mem, size_t size)
}
static u32 sn9c102_request_buffers(struct sn9c102_device* cam, u32 count)
static u32
sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
enum sn9c102_io_method io)
{
struct v4l2_pix_format* p = &(cam->sensor->pix_format);
const size_t imagesize = (p->width * p->height * p->priv)/8;
struct v4l2_rect* r = &(cam->sensor->cropcap.bounds);
const size_t imagesize = cam->module_param.force_munmap ||
io == IO_READ ?
(p->width * p->height * p->priv)/8 :
(r->width * r->height * p->priv)/8;
void* buff = NULL;
u32 i;
......@@ -911,11 +932,6 @@ sn9c102_store_val(struct class_device* cd, const char* buf, size_t len)
return -ENODEV;
}
if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) {
up(&sn9c102_sysfs_lock);
return -ENOSYS;
}
value = sn9c102_strtou8(buf, len, &count);
if (!count) {
up(&sn9c102_sysfs_lock);
......@@ -1047,6 +1063,11 @@ sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
return -ENODEV;
}
if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) {
up(&sn9c102_sysfs_lock);
return -ENOSYS;
}
value = sn9c102_strtou8(buf, len, &count);
if (!count) {
up(&sn9c102_sysfs_lock);
......@@ -1514,7 +1535,7 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
}
if (cam->io == IO_NONE) {
if (!sn9c102_request_buffers(cam, cam->nreadbuffers)) {
if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
DBG(1, "read() failed, not enough memory")
up(&cam->fileop_sem);
return -ENOMEM;
......@@ -1594,7 +1615,7 @@ static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
}
if (cam->io == IO_NONE) {
if (!sn9c102_request_buffers(cam, 2)) {
if (!sn9c102_request_buffers(cam, 2, IO_READ)) {
DBG(1, "poll() failed, not enough memory")
goto error;
}
......@@ -1811,6 +1832,7 @@ static int sn9c102_v4l2_ioctl(struct inode* inode, struct file* filp,
return err;
}
case VIDIOC_S_CTRL_OLD:
case VIDIOC_S_CTRL:
{
struct sn9c102_sensor* s = cam->sensor;
......@@ -1895,6 +1917,7 @@ static int sn9c102_v4l2_ioctl(struct inode* inode, struct file* filp,
if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
if (cam->module_param.force_munmap)
for (i = 0; i < cam->nbuffers; i++)
if (cam->frame[i].vma_use_count) {
DBG(3, "VIDIOC_S_CROP failed. "
......@@ -1947,6 +1970,7 @@ static int sn9c102_v4l2_ioctl(struct inode* inode, struct file* filp,
return -EFAULT;
}
if (cam->module_param.force_munmap)
sn9c102_release_buffers(cam);
err = sn9c102_set_crop(cam, rect);
......@@ -1966,7 +1990,9 @@ static int sn9c102_v4l2_ioctl(struct inode* inode, struct file* filp,
s->pix_format.height = rect->height/scale;
memcpy(&(s->_rect), rect, sizeof(*rect));
if (nbuffers != sn9c102_request_buffers(cam, nbuffers)) {
if (cam->module_param.force_munmap &&
nbuffers != sn9c102_request_buffers(cam, nbuffers,
cam->io)) {
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_CROP failed because of not enough "
"memory. To use the camera, close and open "
......@@ -2103,6 +2129,7 @@ static int sn9c102_v4l2_ioctl(struct inode* inode, struct file* filp,
return 0;
}
if (cam->module_param.force_munmap)
for (i = 0; i < cam->nbuffers; i++)
if (cam->frame[i].vma_use_count) {
DBG(3, "VIDIOC_S_FMT failed. "
......@@ -2119,6 +2146,7 @@ static int sn9c102_v4l2_ioctl(struct inode* inode, struct file* filp,
return -EFAULT;
}
if (cam->module_param.force_munmap)
sn9c102_release_buffers(cam);
err += sn9c102_set_pix_format(cam, pix);
......@@ -2140,7 +2168,9 @@ static int sn9c102_v4l2_ioctl(struct inode* inode, struct file* filp,
memcpy(pfmt, pix, sizeof(*pix));
memcpy(&(s->_rect), &rect, sizeof(rect));
if (nbuffers != sn9c102_request_buffers(cam, nbuffers)) {
if (cam->module_param.force_munmap &&
nbuffers != sn9c102_request_buffers(cam, nbuffers,
cam->io)) {
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_FMT failed because of not enough "
"memory. To use the camera, close and open "
......@@ -2228,7 +2258,8 @@ static int sn9c102_v4l2_ioctl(struct inode* inode, struct file* filp,
sn9c102_release_buffers(cam);
if (rb.count)
rb.count = sn9c102_request_buffers(cam, rb.count);
rb.count = sn9c102_request_buffers(cam, rb.count,
IO_MMAP);
if (copy_to_user(arg, &rb, sizeof(rb))) {
sn9c102_release_buffers(cam);
......@@ -2402,6 +2433,7 @@ static int sn9c102_v4l2_ioctl(struct inode* inode, struct file* filp,
return 0;
}
case VIDIOC_S_PARM_OLD:
case VIDIOC_S_PARM:
{
struct v4l2_streamparm sp;
......@@ -2496,8 +2528,10 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
n = sizeof(sn9c102_id_table)/sizeof(sn9c102_id_table[0]);
for (i = 0; i < n-1; i++)
if (le16_to_cpu(udev->descriptor.idVendor) == sn9c102_id_table[i].idVendor &&
le16_to_cpu(udev->descriptor.idProduct) == sn9c102_id_table[i].idProduct)
if (le16_to_cpu(udev->descriptor.idVendor) ==
sn9c102_id_table[i].idVendor &&
le16_to_cpu(udev->descriptor.idProduct) ==
sn9c102_id_table[i].idProduct)
break;
if (i == n-1)
return -ENODEV;
......@@ -2596,6 +2630,10 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor)
cam->module_param.force_munmap = force_munmap[dev_nr];
dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
sn9c102_create_sysfs(cam);
DBG(2, "Optional device control through 'sysfs' interface ready")
......
......@@ -2,7 +2,7 @@
* Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera *
* Controllers *
* *
* Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
* Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
......
......@@ -2,7 +2,7 @@
* Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera *
* Controllers *
* *
* Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
* Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
......
......@@ -2,7 +2,7 @@
* Plug-in for PAS106B image sensor connected to the SN9C10x PC Camera *
* Controllers *
* *
* Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
* Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
......
/***************************************************************************
* API for image sensors connected to the SN9C10x PC Camera Controllers *
* *
* Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
* Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
......
......@@ -2,7 +2,7 @@
* Plug-in for TAS5110C1B image sensor connected to the SN9C10x PC Camera *
* Controllers *
* *
* Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
* Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
......
......@@ -2,7 +2,7 @@
* Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera *
* Controllers *
* *
* Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
* Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
......
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