Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f3d092b84a855c44914fea0648695bef7d751266
Commit:     f3d092b84a855c44914fea0648695bef7d751266
Parent:     d55c7aec666658495e5b57a6b194c8c2a1ac255f
Author:     Hans Verkuil <[EMAIL PROTECTED]>
AuthorDate: Fri Feb 23 20:55:14 2007 -0300
Committer:  Mauro Carvalho Chehab <[EMAIL PROTECTED]>
CommitDate: Thu Mar 1 13:09:44 2007 -0200

    V4L/DVB (5304): Improve chip matching in v4l2_register
    
    The chip matching in struct v4l2_register for VIDIOC_DBG_G/S_REGISTER
    was rather primitive. It could not be extended to other busses besides
    i2c and it lacked a way to.
    
    Signed-off-by: Hans Verkuil <[EMAIL PROTECTED]>
    Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>
---
 drivers/media/video/cx25840/cx25840-core.c      |    2 +-
 drivers/media/video/cx88/cx88-video.c           |    4 +-
 drivers/media/video/pvrusb2/pvrusb2-hdw.c       |   11 +++++---
 drivers/media/video/pvrusb2/pvrusb2-hdw.h       |    7 +++--
 drivers/media/video/pvrusb2/pvrusb2-v4l2.c      |    4 +-
 drivers/media/video/saa7115.c                   |    2 +-
 drivers/media/video/saa7127.c                   |    2 +-
 drivers/media/video/tvp5150.c                   |    2 +-
 drivers/media/video/upd64031a.c                 |    2 +-
 drivers/media/video/upd64083.c                  |    2 +-
 drivers/media/video/usbvision/usbvision-video.c |    4 +-
 drivers/media/video/v4l2-common.c               |   30 +++++++++++++++++++++++
 include/linux/videodev2.h                       |   11 +++++++-
 include/media/v4l2-common.h                     |    8 ++++++
 14 files changed, 70 insertions(+), 21 deletions(-)

diff --git a/drivers/media/video/cx25840/cx25840-core.c 
b/drivers/media/video/cx25840/cx25840-core.c
index 3ff5fc0..774d253 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -633,7 +633,7 @@ static int cx25840_command(struct i2c_client *client, 
unsigned int cmd,
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_CX25840)
+               if (!v4l2_chip_match_i2c_client(client, reg->match_type, 
reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
diff --git a/drivers/media/video/cx88/cx88-video.c 
b/drivers/media/video/cx88/cx88-video.c
index a97be1b..bdfe2af 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1389,7 +1389,7 @@ static int vidioc_g_register (struct file *file, void *fh,
 {
        struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
 
-       if (reg->i2c_id != 0)
+       if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
                return -EINVAL;
        /* cx2388x has a 24-bit register space */
        reg->val = cx_read(reg->reg&0xffffff);
@@ -1401,7 +1401,7 @@ static int vidioc_s_register (struct file *file, void *fh,
 {
        struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
 
-       if (reg->i2c_id != 0)
+       if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
                return -EINVAL;
        cx_write(reg->reg&0xffffff, reg->val);
        return 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c 
b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index a1ca0f5..1cd4bb3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -3256,8 +3256,8 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
 
 
 int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
-                            u32 chip_id, u64 reg_id,
-                            int setFl,u32 *val_ptr)
+                            u32 match_type, u32 match_chip, u64 reg_id,
+                            int setFl,u64 *val_ptr)
 {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        struct list_head *item;
@@ -3268,13 +3268,16 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
 
        if (!capable(CAP_SYS_ADMIN)) return -EPERM;
 
-       req.i2c_id = chip_id;
+       req.match_type = match_type;
+       req.match_chip = match_chip;
        req.reg = reg_id;
        if (setFl) req.val = *val_ptr;
        mutex_lock(&hdw->i2c_list_lock); do {
                list_for_each(item,&hdw->i2c_clients) {
                        cp = list_entry(item,struct pvr2_i2c_client,list);
-                       if (cp->client->driver->id != chip_id) continue;
+                       if (!v4l2_chip_match_i2c_client(cp->client, 
req.match_type, req.match_chip)) {
+                               continue;
+                       }
                        stat = pvr2_i2c_client_cmd(
                                cp,(setFl ? VIDIOC_DBG_S_REGISTER :
                                    VIDIOC_DBG_G_REGISTER),&req);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h 
b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 566a8ef..0c9cca4 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -217,13 +217,14 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
                                     enum pvr2_v4l_type index,int);
 
 /* Direct read/write access to chip's registers:
-   chip_id - unique id of chip (e.g. I2C_DRIVERD_xxxx)
+   match_type - how to interpret match_chip (e.g. driver ID, i2c address)
+   match_chip - chip match value (e.g. I2C_DRIVERD_xxxx)
    reg_id  - register number to access
    setFl   - true to set the register, false to read it
    val_ptr - storage location for source / result. */
 int pvr2_hdw_register_access(struct pvr2_hdw *,
-                            u32 chip_id,u64 reg_id,
-                            int setFl,u32 *val_ptr);
+                            u32 match_type, u32 match_chip,u64 reg_id,
+                            int setFl,u64 *val_ptr);
 
 /* The following entry points are all lower level things you normally don't
    want to worry about. */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c 
b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 4fe4136..5313d34 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -740,11 +740,11 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct 
file *file,
        case VIDIOC_DBG_S_REGISTER:
        case VIDIOC_DBG_G_REGISTER:
        {
-               u32 val;
+               u64 val;
                struct v4l2_register *req = (struct v4l2_register *)arg;
                if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val;
                ret = pvr2_hdw_register_access(
-                       hdw,req->i2c_id,req->reg,
+                       hdw,req->match_type,req->match_chip,req->reg,
                        cmd == VIDIOC_DBG_S_REGISTER,&val);
                if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val;
                break;
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index c4f066d..7735b67 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1425,7 +1425,7 @@ static int saa711x_command(struct i2c_client *client, 
unsigned int cmd, void *ar
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_SAA711X)
+               if (!v4l2_chip_match_i2c_client(client, reg->match_type, 
reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index bd9c4f3..654863d 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -619,7 +619,7 @@ static int saa7127_command(struct i2c_client *client,
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_SAA7127)
+               if (!v4l2_chip_match_i2c_client(client, reg->match_type, 
reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 886b5df..d5ec05f 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -955,7 +955,7 @@ static int tvp5150_command(struct i2c_client *c,
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_TVP5150)
+               if (!v4l2_chip_match_i2c_client(c, reg->match_type, 
reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index b3b5fd5..28d1133 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -167,7 +167,7 @@ static int upd64031a_command(struct i2c_client *client, 
unsigned int cmd, void *
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_UPD64031A)
+               if (!v4l2_chip_match_i2c_client(client, reg->match_type, 
reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 8852903..fe38224 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -144,7 +144,7 @@ static int upd64083_command(struct i2c_client *client, 
unsigned int cmd, void *a
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_UPD64083)
+               if (!v4l2_chip_match_i2c_client(client, reg->match_type, 
reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
diff --git a/drivers/media/video/usbvision/usbvision-video.c 
b/drivers/media/video/usbvision/usbvision-video.c
index ae5f425..6fc1455 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -521,7 +521,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, 
struct file *file,
                        struct v4l2_register *reg = arg;
                        int errCode;
 
-                       if (reg->i2c_id != 0)
+                       if (!v4l2_chip_match_host(reg->match_type, 
reg->match_chip))
                                return -EINVAL;
                        if (!capable(CAP_SYS_ADMIN))
                                return -EPERM;
@@ -540,7 +540,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, 
struct file *file,
 
                        PDEBUG(DBG_IOCTL, "VIDIOC_DBG_%c_REGISTER reg=0x%02X, 
value=0x%02X",
                               cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S',
-                              (unsigned int)reg->reg, reg->val);
+                              (unsigned int)reg->reg, (unsigned int)reg->val);
                        return 0;
                }
 #endif
diff --git a/drivers/media/video/v4l2-common.c 
b/drivers/media/video/v4l2-common.c
index ddfd80c..3506cb6 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -51,6 +51,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <linux/i2c.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -947,6 +948,32 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 
id)
        return **ctrl_classes;
 }
 
+int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 
match_chip)
+{
+       switch (match_type) {
+       case V4L2_CHIP_MATCH_ALWAYS:
+               return 1;
+       case V4L2_CHIP_MATCH_I2C_DRIVER:
+               return (c != NULL && c->driver != NULL && c->driver->id == 
match_chip);
+       case V4L2_CHIP_MATCH_I2C_ADDR:
+               return (c != NULL && c->addr == match_chip);
+       default:
+               return 0;
+       }
+}
+
+int v4l2_chip_match_host(u32 match_type, u32 match_chip)
+{
+       switch (match_type) {
+       case V4L2_CHIP_MATCH_ALWAYS:
+               return 1;
+       case V4L2_CHIP_MATCH_HOST:
+               return match_chip == 0;
+       default:
+               return 0;
+       }
+}
+
 /* ----------------------------------------------------------------- */
 
 EXPORT_SYMBOL(v4l2_norm_to_name);
@@ -970,6 +997,9 @@ EXPORT_SYMBOL(v4l2_ctrl_query_menu);
 EXPORT_SYMBOL(v4l2_ctrl_query_fill);
 EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
 
+EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
+EXPORT_SYMBOL(v4l2_chip_match_host);
+
 /*
  * Local variables:
  * c-basic-offset: 8
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 65a165f..e3ab047 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1306,10 +1306,17 @@ struct v4l2_streamparm
  */
 
 /* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
+
+#define V4L2_CHIP_MATCH_ALWAYS     0  /* Match always (match_chip is not used) 
*/
+#define V4L2_CHIP_MATCH_HOST       1  /* Match against chip ID on host (0 for 
the host) */
+#define V4L2_CHIP_MATCH_I2C_DRIVER 2  /* Match against I2C driver ID */
+#define V4L2_CHIP_MATCH_I2C_ADDR   3  /* Match against I2C 7-bit address */
+
 struct v4l2_register {
+       __u32 match_type; /* Match type */
+       __u32 match_chip; /* Match this chip, meaning determined by match_type 
*/
        __u64 reg;
-       __u32 i2c_id; /* I2C driver ID of the I2C chip, or 0 for the host */
-       __u32 val;
+       __u64 val;
 };
 
 /*
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 244e440..6eaeec9 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -94,6 +94,14 @@ u32 v4l2_ctrl_next(const u32 * const *ctrl_classes, u32 id);
 
 /* ------------------------------------------------------------------------- */
 
+/* Register/chip ident helper function */
+
+struct i2c_client; /* forward reference */
+int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 id_type, u32 chip_id);
+int v4l2_chip_match_host(u32 id_type, u32 chip_id);
+
+/* ------------------------------------------------------------------------- */
+
 /* Internal ioctls */
 
 /* VIDIOC_INT_DECODE_VBI_LINE */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to