Commit 06cc1d27 authored by Mark W. McClelland's avatar Mark W. McClelland Committed by Greg Kroah-Hartman

[PATCH] USB: ov511 sysfs conversion (1/3)

This is the first in a series of three patches to convert the ov511
driver's /proc/video interface to sysfs. All V4L drivers must undergo
this conversion now that /proc/video has been removed from the core.

This patch removes ov511's /proc/video support, which allows it to
compile again.
parent ea027460
......@@ -38,13 +38,10 @@
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/ctype.h>
#include <linux/pagemap.h>
#include <asm/io.h>
#include <asm/semaphore.h>
#include <asm/processor.h>
#include <linux/mm.h>
......@@ -381,270 +378,6 @@ rvfree(void *mem, unsigned long size)
vfree(mem);
}
/**********************************************************************
* /proc interface
* Based on the CPiA driver version 0.7.4 -claudio
**********************************************************************/
#if defined(CONFIG_VIDEO_PROC_FS)
static struct proc_dir_entry *ov511_proc_entry = NULL;
extern struct proc_dir_entry *video_proc_entry;
/* Prototypes */
static void ov51x_clear_snapshot(struct usb_ov511 *);
static int sensor_get_picture(struct usb_ov511 *, struct video_picture *);
static int sensor_get_exposure(struct usb_ov511 *, unsigned char *);
static int ov51x_check_snapshot(struct usb_ov511 *);
static int ov51x_control_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
static struct file_operations ov511_control_fops = {
.owner = THIS_MODULE,
.ioctl = ov51x_control_ioctl,
};
#define YES_NO(x) ((x) ? "yes" : "no")
/* /proc/video/ov511/<minor#>/info */
static int
ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
void *data)
{
char *out = page;
int i, len;
struct usb_ov511 *ov = data;
struct video_picture p;
unsigned char exp;
if (!ov || !ov->dev)
return -ENODEV;
sensor_get_picture(ov, &p);
sensor_get_exposure(ov, &exp);
/* IMPORTANT: This output MUST be kept under PAGE_SIZE
* or we need to get more sophisticated. */
out += sprintf(out, "driver_version : %s\n", DRIVER_VERSION);
out += sprintf(out, "custom_id : %d\n", ov->customid);
out += sprintf(out, "model : %s\n", ov->desc);
out += sprintf(out, "streaming : %s\n", YES_NO(ov->streaming));
out += sprintf(out, "grabbing : %s\n", YES_NO(ov->grabbing));
out += sprintf(out, "compress : %s\n", YES_NO(ov->compress));
out += sprintf(out, "subcapture : %s\n", YES_NO(ov->sub_flag));
out += sprintf(out, "sub_size : %d %d %d %d\n",
ov->subx, ov->suby, ov->subw, ov->subh);
out += sprintf(out, "brightness : %d\n", p.brightness >> 8);
out += sprintf(out, "colour : %d\n", p.colour >> 8);
out += sprintf(out, "contrast : %d\n", p.contrast >> 8);
out += sprintf(out, "hue : %d\n", p.hue >> 8);
out += sprintf(out, "exposure : %d\n", exp);
out += sprintf(out, "num_frames : %d\n", OV511_NUMFRAMES);
for (i = 0; i < OV511_NUMFRAMES; i++) {
out += sprintf(out, "frame : %d\n", i);
out += sprintf(out, " depth : %d\n",
ov->frame[i].depth);
out += sprintf(out, " size : %d %d\n",
ov->frame[i].width, ov->frame[i].height);
out += sprintf(out, " format : %s\n",
symbolic(v4l1_plist, ov->frame[i].format));
out += sprintf(out, " data_buffer : 0x%p\n",
ov->frame[i].data);
}
out += sprintf(out, "snap_enabled : %s\n", YES_NO(ov->snap_enabled));
out += sprintf(out, "bridge : %s\n",
symbolic(brglist, ov->bridge));
out += sprintf(out, "sensor : %s\n",
symbolic(senlist, ov->sensor));
out += sprintf(out, "packet_size : %d\n", ov->packet_size);
out += sprintf(out, "framebuffer : 0x%p\n", ov->fbuf);
out += sprintf(out, "packet_numbering: %d\n", ov->packet_numbering);
out += sprintf(out, "topology : %s\n", ov->usb_path);
len = out - page;
len -= off;
if (len < count) {
*eof = 1;
if (len <= 0)
return 0;
} else
len = count;
*start = page + off;
return len;
}
/* /proc/video/ov511/<minor#>/button
*
* When the camera's button is pressed, the output of this will change from a
* 0 to a 1 (ASCII). It will retain this value until it is read, after which
* it will reset to zero.
*
* SECURITY NOTE: Since reading this file can change the state of the snapshot
* status, it is important for applications that open it to keep it locked
* against access by other processes, using flock() or a similar mechanism. No
* locking is provided by this driver.
*/
static int
ov511_read_proc_button(char *page, char **start, off_t off, int count, int *eof,
void *data)
{
char *out = page;
int len, status;
struct usb_ov511 *ov = data;
if (!ov || !ov->dev)
return -ENODEV;
status = ov51x_check_snapshot(ov);
out += sprintf(out, "%d", status);
if (status)
ov51x_clear_snapshot(ov);
len = out - page;
len -= off;
if (len < count) {
*eof = 1;
if (len <= 0)
return 0;
} else {
len = count;
}
*start = page + off;
return len;
}
static void
create_proc_ov511_cam(struct usb_ov511 *ov)
{
char dirname[10];
if (!ov511_proc_entry || !ov)
return;
/* Create per-device directory */
snprintf(dirname, 10, "%d", ov->vdev.minor);
PDEBUG(4, "creating /proc/video/ov511/%s/", dirname);
ov->proc_devdir = create_proc_entry(dirname, S_IFDIR, ov511_proc_entry);
if (!ov->proc_devdir)
return;
ov->proc_devdir->owner = THIS_MODULE;
/* Create "info" entry (human readable device information) */
PDEBUG(4, "creating /proc/video/ov511/%s/info", dirname);
ov->proc_info = create_proc_read_entry("info", S_IFREG|S_IRUGO|S_IWUSR,
ov->proc_devdir, ov511_read_proc_info, ov);
if (!ov->proc_info)
return;
ov->proc_info->owner = THIS_MODULE;
/* Don't create it if old snapshot mode on (would cause race cond.) */
if (!snapshot) {
/* Create "button" entry (snapshot button status) */
PDEBUG(4, "creating /proc/video/ov511/%s/button", dirname);
ov->proc_button = create_proc_read_entry("button",
S_IFREG|S_IRUGO|S_IWUSR, ov->proc_devdir,
ov511_read_proc_button, ov);
if (!ov->proc_button)
return;
ov->proc_button->owner = THIS_MODULE;
}
/* Create "control" entry (ioctl() interface) */
PDEBUG(4, "creating /proc/video/ov511/%s/control", dirname);
lock_kernel();
ov->proc_control = create_proc_entry("control", S_IFREG|S_IRUGO|S_IWUSR,
ov->proc_devdir);
if (!ov->proc_control) {
unlock_kernel();
return;
}
ov->proc_control->owner = THIS_MODULE;
ov->proc_control->data = ov;
ov->proc_control->proc_fops = &ov511_control_fops;
unlock_kernel();
}
static void
destroy_proc_ov511_cam(struct usb_ov511 *ov)
{
char dirname[10];
if (!ov || !ov->proc_devdir)
return;
snprintf(dirname, 10, "%d", ov->vdev.minor);
/* Destroy "control" entry */
if (ov->proc_control) {
PDEBUG(4, "destroying /proc/video/ov511/%s/control", dirname);
remove_proc_entry("control", ov->proc_devdir);
ov->proc_control = NULL;
}
/* Destroy "button" entry */
if (ov->proc_button) {
PDEBUG(4, "destroying /proc/video/ov511/%s/button", dirname);
remove_proc_entry("button", ov->proc_devdir);
ov->proc_button = NULL;
}
/* Destroy "info" entry */
if (ov->proc_info) {
PDEBUG(4, "destroying /proc/video/ov511/%s/info", dirname);
remove_proc_entry("info", ov->proc_devdir);
ov->proc_info = NULL;
}
/* Destroy per-device directory */
PDEBUG(4, "destroying /proc/video/ov511/%s/", dirname);
remove_proc_entry(dirname, ov511_proc_entry);
ov->proc_devdir = NULL;
}
static void
proc_ov511_create(void)
{
/* No current standard here. Alan prefers /proc/video/ as it keeps
* /proc "less cluttered than /proc/randomcardifoundintheshed/"
* -claudio
*/
if (video_proc_entry == NULL) {
err("Error: /proc/video/ does not exist");
return;
}
ov511_proc_entry = create_proc_entry("ov511", S_IFDIR,
video_proc_entry);
if (ov511_proc_entry)
ov511_proc_entry->owner = THIS_MODULE;
else
err("Unable to create /proc/video/ov511");
}
static void
proc_ov511_destroy(void)
{
PDEBUG(3, "removing /proc/video/ov511");
if (ov511_proc_entry == NULL)
return;
remove_proc_entry("ov511", video_proc_entry);
}
#else
static inline void create_proc_ov511_cam(struct usb_ov511 *ov) { }
static inline void destroy_proc_ov511_cam(struct usb_ov511 *ov) { }
static inline void proc_ov511_create(void) { }
static inline void proc_ov511_destroy(void) { }
#endif /* #ifdef CONFIG_VIDEO_PROC_FS */
/**********************************************************************
*
* Register I/O
......@@ -5074,225 +4807,6 @@ static struct video_device vdev_template = {
.fops = &ov511_fops,
};
#if defined(CONFIG_VIDEO_PROC_FS)
static int
ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long ularg)
{
struct proc_dir_entry *pde = PDE(inode);
struct usb_ov511 *ov;
void *arg = (void *) ularg;
int rc = 0;
if (!pde)
return -ENOENT;
ov = pde->data;
if (!ov)
return -ENODEV;
if (!ov->dev)
return -EIO;
/* Should we pass through standard V4L IOCTLs? */
switch (cmd) {
case OV511IOC_GINTVER:
{
int ver = OV511_INTERFACE_VER;
PDEBUG(4, "Get interface version: %d", ver);
if (copy_to_user(arg, &ver, sizeof(ver)))
rc = -EFAULT;
break;
}
case OV511IOC_GUSHORT:
{
struct ov511_ushort_opt opt;
if (copy_from_user(&opt, arg, sizeof(opt))) {
rc = -EFAULT;
break;
}
switch (opt.optnum) {
case OV511_USOPT_BRIGHT:
rc = sensor_get_brightness(ov, &(opt.val));
break;
case OV511_USOPT_SAT:
rc = sensor_get_saturation(ov, &(opt.val));
break;
case OV511_USOPT_HUE:
rc = sensor_get_hue(ov, &(opt.val));
break;
case OV511_USOPT_CONTRAST:
rc = sensor_get_contrast(ov, &(opt.val));
break;
default:
err("Invalid get short option number");
rc = -EINVAL;
}
if (rc < 0)
break;
if (copy_to_user(arg, &opt, sizeof(opt)))
rc = -EFAULT;
break;
}
case OV511IOC_SUSHORT:
{
struct ov511_ushort_opt opt;
if (copy_from_user(&opt, arg, sizeof(opt))) {
rc = -EFAULT;
break;
}
switch (opt.optnum) {
case OV511_USOPT_BRIGHT:
rc = sensor_set_brightness(ov, opt.val);
break;
case OV511_USOPT_SAT:
rc = sensor_set_saturation(ov, opt.val);
break;
case OV511_USOPT_HUE:
rc = sensor_set_hue(ov, opt.val);
break;
case OV511_USOPT_CONTRAST:
rc = sensor_set_contrast(ov, opt.val);
break;
default:
err("Invalid set short option number");
rc = -EINVAL;
}
break;
}
case OV511IOC_GUINT:
{
struct ov511_uint_opt opt;
if (copy_from_user(&opt, arg, sizeof(opt))) {
rc = -EFAULT;
break;
}
switch (opt.optnum) {
case OV511_UIOPT_POWER_FREQ:
opt.val = ov->lightfreq;
break;
case OV511_UIOPT_BFILTER:
opt.val = ov->bandfilt;
break;
case OV511_UIOPT_LED:
opt.val = ov->led_policy;
break;
case OV511_UIOPT_DEBUG:
opt.val = debug;
break;
case OV511_UIOPT_COMPRESS:
opt.val = ov->compress;
break;
default:
err("Invalid get int option number");
rc = -EINVAL;
}
if (rc < 0)
break;
if (copy_to_user(arg, &opt, sizeof(opt)))
rc = -EFAULT;
break;
}
case OV511IOC_SUINT:
{
struct ov511_uint_opt opt;
if (copy_from_user(&opt, arg, sizeof(opt))) {
rc = -EFAULT;
break;
}
switch (opt.optnum) {
case OV511_UIOPT_POWER_FREQ:
rc = sensor_set_light_freq(ov, opt.val);
break;
case OV511_UIOPT_BFILTER:
rc = sensor_set_banding_filter(ov, opt.val);
break;
case OV511_UIOPT_LED:
if (opt.val <= 2) {
ov->led_policy = opt.val;
if (ov->led_policy == LED_OFF)
ov51x_led_control(ov, 0);
else if (ov->led_policy == LED_ON)
ov51x_led_control(ov, 1);
} else
rc = -EINVAL;
break;
case OV511_UIOPT_DEBUG:
if (opt.val <= 5)
debug = opt.val;
else
rc = -EINVAL;
break;
case OV511_UIOPT_COMPRESS:
ov->compress = opt.val;
if (ov->compress) {
if (ov->bclass == BCL_OV511)
ov511_init_compression(ov);
else if (ov->bclass == BCL_OV518)
ov518_init_compression(ov);
}
break;
default:
err("Invalid get int option number");
rc = -EINVAL;
}
break;
}
case OV511IOC_WI2C:
{
struct ov511_i2c_struct w;
if (copy_from_user(&w, arg, sizeof(w))) {
rc = -EFAULT;
break;
}
rc = i2c_w_slave(ov, w.slave, w.reg, w.value, w.mask);
break;
}
case OV511IOC_RI2C:
{
struct ov511_i2c_struct r;
if (copy_from_user(&r, arg, sizeof(r))) {
rc = -EFAULT;
break;
}
rc = i2c_r_slave(ov, r.slave, r.reg);
if (rc < 0)
break;
r.value = rc;
if (copy_to_user(arg, &r, sizeof(r)))
rc = -EFAULT;
break;
}
default:
rc = -EINVAL;
} /* end switch */
return rc;
}
#endif
/****************************************************************************
*
* OV511 and sensor configuration
......@@ -6318,13 +5832,11 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
info("Device at %s registered to minor %d", ov->usb_path,
ov->vdev.minor);
create_proc_ov511_cam(ov);
usb_set_intfdata (intf, ov);
return 0;
error:
destroy_proc_ov511_cam(ov);
if (ov->cbuf) {
down(&ov->cbuf_lock);
......@@ -6375,7 +5887,6 @@ ov51x_disconnect(struct usb_interface *intf)
ov->streaming = 0;
ov51x_unlink_isoc(ov);
destroy_proc_ov511_cam(ov);
ov->dev = NULL;
......@@ -6487,7 +5998,6 @@ ov511_deregister_decomp_module(int ov518, int mmx)
static int __init
usb_ov511_init(void)
{
proc_ov511_create();
if (usb_register(&ov511_driver) < 0)
return -1;
......@@ -6503,7 +6013,6 @@ usb_ov511_exit(void)
usb_deregister(&ov511_driver);
info("driver deregistered");
proc_ov511_destroy();
}
module_init(usb_ov511_init);
......
......@@ -321,35 +321,6 @@ enum {
RAWFMT_GBR422,
};
/* Unsigned short option numbers */
enum {
OV511_USOPT_INVALID,
OV511_USOPT_BRIGHT,
OV511_USOPT_SAT,
OV511_USOPT_HUE,
OV511_USOPT_CONTRAST,
};
/* Unsigned int option numbers */
enum {
OV511_UIOPT_INVALID,
OV511_UIOPT_POWER_FREQ,
OV511_UIOPT_BFILTER,
OV511_UIOPT_LED,
OV511_UIOPT_DEBUG,
OV511_UIOPT_COMPRESS,
};
struct ov511_ushort_opt {
int optnum; /* Specific option number */
unsigned short val;
};
struct ov511_uint_opt {
int optnum; /* Specific option number */
unsigned int val;
};
struct ov511_i2c_struct {
unsigned char slave; /* Write slave ID (read ID - 1) */
unsigned char reg; /* Index of register */
......@@ -358,15 +329,6 @@ struct ov511_i2c_struct {
};
/* ioctls */
#define OV511IOC_GINTVER _IOR('v', BASE_VIDIOCPRIVATE + 0, int)
#define OV511IOC_GUSHORT _IOWR('v', BASE_VIDIOCPRIVATE + 1, \
struct ov511_ushort_opt)
#define OV511IOC_SUSHORT _IOW('v', BASE_VIDIOCPRIVATE + 2, \
struct ov511_ushort_opt)
#define OV511IOC_GUINT _IOWR('v', BASE_VIDIOCPRIVATE + 3, \
struct ov511_uint_opt)
#define OV511IOC_SUINT _IOW('v', BASE_VIDIOCPRIVATE + 4, \
struct ov511_uint_opt)
#define OV511IOC_WI2C _IOW('v', BASE_VIDIOCPRIVATE + 5, \
struct ov511_i2c_struct)
#define OV511IOC_RI2C _IOWR('v', BASE_VIDIOCPRIVATE + 6, \
......@@ -515,12 +477,6 @@ struct usb_ov511 {
struct semaphore param_lock; /* params lock for this camera */
/* /proc entries, relative to /proc/video/ov511/ */
struct proc_dir_entry *proc_devdir; /* Per-device proc directory */
struct proc_dir_entry *proc_info; /* <minor#>/info entry */
struct proc_dir_entry *proc_button; /* <minor#>/button entry */
struct proc_dir_entry *proc_control; /* <minor#>/control entry */
/* Framebuffer/sbuf management */
int buf_state;
struct semaphore buf_lock;
......
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