V4L/DVB (5163): Add checks for CAP_SYS_ADMIN to VIDIOC_DBG_G_REGISTER
[pandora-kernel.git] / drivers / media / video / saa7127.c
index 992c717..bd9c4f3 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/saa7127.h>
 
 static int debug = 0;
 static int test_image = 0;
@@ -141,6 +142,7 @@ struct i2c_reg_value {
 static const struct i2c_reg_value saa7129_init_config_extra[] = {
        { SAA7127_REG_OUTPUT_PORT_CONTROL,              0x38 },
        { SAA7127_REG_VTRIG,                            0xfa },
+       { 0, 0 }
 };
 
 static const struct i2c_reg_value saa7127_init_config_common[] = {
@@ -222,22 +224,6 @@ static struct i2c_reg_value saa7127_init_config_50hz[] = {
        { 0, 0 }
 };
 
-/* Enumeration for the Supported input types */
-enum saa7127_input_type {
-       SAA7127_INPUT_TYPE_NORMAL,
-       SAA7127_INPUT_TYPE_TEST_IMAGE
-};
-
-/* Enumeration for the Supported Output signal types */
-enum saa7127_output_type {
-       SAA7127_OUTPUT_TYPE_BOTH,
-       SAA7127_OUTPUT_TYPE_COMPOSITE,
-       SAA7127_OUTPUT_TYPE_SVIDEO,
-       SAA7127_OUTPUT_TYPE_RGB,
-       SAA7127_OUTPUT_TYPE_YUV_C,
-       SAA7127_OUTPUT_TYPE_YUV_V
-};
-
 /*
  **********************************************************************
  *
@@ -284,7 +270,7 @@ static const char * const wss_strs[] = {
        "letterbox 16:9 top",
        "invalid",
        "invalid",
-       "16:9 full format anamorphic"
+       "16:9 full format anamorphic",
        "4:3 full format",
        "invalid",
        "invalid",
@@ -561,7 +547,7 @@ static int saa7127_command(struct i2c_client *client,
 {
        struct saa7127_state *state = i2c_get_clientdata(client);
        struct v4l2_format *fmt = arg;
-       int *iarg = arg;
+       struct v4l2_routing *route = arg;
 
        switch (cmd) {
        case VIDIOC_S_STD:
@@ -573,15 +559,23 @@ static int saa7127_command(struct i2c_client *client,
                *(v4l2_std_id *)arg = state->std;
                break;
 
-       case VIDIOC_S_INPUT:
-               if (state->input_type == *iarg)
-                       break;
-               return saa7127_set_input_type(client, *iarg);
+       case VIDIOC_INT_G_VIDEO_ROUTING:
+               route->input = state->input_type;
+               route->output = state->output_type;
+               break;
 
-       case VIDIOC_S_OUTPUT:
-               if (state->output_type == *iarg)
-                       break;
-               return saa7127_set_output_type(client, *iarg);
+       case VIDIOC_INT_S_VIDEO_ROUTING:
+       {
+               int rc = 0;
+
+               if (state->input_type != route->input) {
+                       rc = saa7127_set_input_type(client, route->input);
+               }
+               if (rc == 0 && state->output_type != route->output) {
+                       rc = saa7127_set_output_type(client, route->output);
+               }
+               return rc;
+       }
 
        case VIDIOC_STREAMON:
        case VIDIOC_STREAMOFF:
@@ -620,17 +614,8 @@ static int saa7127_command(struct i2c_client *client,
                break;
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-       case VIDIOC_INT_G_REGISTER:
-       {
-               struct v4l2_register *reg = arg;
-
-               if (reg->i2c_id != I2C_DRIVERID_SAA7127)
-                       return -EINVAL;
-               reg->val = saa7127_read(client, reg->reg & 0xff);
-               break;
-       }
-
-       case VIDIOC_INT_S_REGISTER:
+       case VIDIOC_DBG_G_REGISTER:
+       case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
 
@@ -638,7 +623,10 @@ static int saa7127_command(struct i2c_client *client,
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
+               if (cmd == VIDIOC_DBG_G_REGISTER)
+                       reg->val = saa7127_read(client, reg->reg & 0xff);
+               else
+                       saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
                break;
        }
 #endif