]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/mt9m001.c
V4L/DVB (7479): proper prototype for zoran_device.c:zr36016_write()
[linux-2.6-omap-h63xx.git] / drivers / media / video / mt9m001.c
index 4ad834326fa84a4da900b4412feb05d239263c46..2ea133e8a625ce4a488b23be190ef80032ed0e19 100644 (file)
@@ -210,40 +210,64 @@ static int bus_switch_act(struct mt9m001 *mt9m001, int go8bit)
 #endif
 }
 
-static int mt9m001_set_capture_format(struct soc_camera_device *icd,
-               __u32 pixfmt, struct v4l2_rect *rect, unsigned int flags)
+static int bus_switch_possible(struct mt9m001 *mt9m001)
+{
+#ifdef CONFIG_MT9M001_PCA9536_SWITCH
+       return gpio_is_valid(mt9m001->switch_gpio);
+#else
+       return 0;
+#endif
+}
+
+static int mt9m001_set_bus_param(struct soc_camera_device *icd,
+                                unsigned long flags)
 {
        struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-       unsigned int width_flag = flags & (IS_DATAWIDTH_10 | IS_DATAWIDTH_9 |
-                                          IS_DATAWIDTH_8);
+       unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
        int ret;
-       const u16 hblank = 9, vblank = 25;
 
-       /* MT9M001 has all capture_format parameters fixed */
-       if (!(flags & IS_MASTER) ||
-           !(flags & IS_PCLK_SAMPLE_RISING) ||
-           !(flags & IS_HSYNC_ACTIVE_HIGH) ||
-           !(flags & IS_VSYNC_ACTIVE_HIGH))
-               return -EINVAL;
-
-       /* Only one width bit may be set */
-       if (!is_power_of_2(width_flag))
-               return -EINVAL;
+       /* Flags validity verified in test_bus_param */
 
-       if ((mt9m001->datawidth != 10 && (width_flag == IS_DATAWIDTH_10)) ||
-           (mt9m001->datawidth != 9  && (width_flag == IS_DATAWIDTH_9)) ||
-           (mt9m001->datawidth != 8  && (width_flag == IS_DATAWIDTH_8))) {
+       if ((mt9m001->datawidth != 10 && (width_flag == SOCAM_DATAWIDTH_10)) ||
+           (mt9m001->datawidth != 9  && (width_flag == SOCAM_DATAWIDTH_9)) ||
+           (mt9m001->datawidth != 8  && (width_flag == SOCAM_DATAWIDTH_8))) {
                /* Well, we actually only can do 10 or 8 bits... */
-               if (width_flag == IS_DATAWIDTH_9)
+               if (width_flag == SOCAM_DATAWIDTH_9)
                        return -EINVAL;
                ret = bus_switch_act(mt9m001,
-                                    width_flag == IS_DATAWIDTH_8);
+                                    width_flag == SOCAM_DATAWIDTH_8);
                if (ret < 0)
                        return ret;
 
-               mt9m001->datawidth = width_flag == IS_DATAWIDTH_8 ? 8 : 10;
+               mt9m001->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10;
        }
 
+       return 0;
+}
+
+static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
+{
+       struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+       unsigned int width_flag = SOCAM_DATAWIDTH_10;
+
+       if (bus_switch_possible(mt9m001))
+               width_flag |= SOCAM_DATAWIDTH_8;
+
+       /* MT9M001 has all capture_format parameters fixed */
+       return SOCAM_PCLK_SAMPLE_RISING |
+               SOCAM_HSYNC_ACTIVE_HIGH |
+               SOCAM_VSYNC_ACTIVE_HIGH |
+               SOCAM_MASTER |
+               width_flag;
+}
+
+static int mt9m001_set_fmt_cap(struct soc_camera_device *icd,
+               __u32 pixfmt, struct v4l2_rect *rect)
+{
+       struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+       int ret;
+       const u16 hblank = 9, vblank = 25;
+
        /* Blanking and start values - default... */
        ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank);
        if (ret >= 0)
@@ -348,12 +372,6 @@ static int mt9m001_set_register(struct soc_camera_device *icd,
 }
 #endif
 
-static unsigned int mt9m001_get_datawidth(struct soc_camera_device *icd)
-{
-       struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-       return mt9m001->datawidth;
-}
-
 const struct v4l2_queryctrl mt9m001_controls[] = {
        {
                .id             = V4L2_CID_VFLIP,
@@ -392,20 +410,23 @@ const struct v4l2_queryctrl mt9m001_controls[] = {
        }
 };
 
-static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl);
-static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl);
+static int mt9m001_video_probe(struct soc_camera_device *);
+static void mt9m001_video_remove(struct soc_camera_device *);
+static int mt9m001_get_control(struct soc_camera_device *, struct v4l2_control *);
+static int mt9m001_set_control(struct soc_camera_device *, struct v4l2_control *);
 
 static struct soc_camera_ops mt9m001_ops = {
        .owner                  = THIS_MODULE,
+       .probe                  = mt9m001_video_probe,
+       .remove                 = mt9m001_video_remove,
        .init                   = mt9m001_init,
        .release                = mt9m001_release,
        .start_capture          = mt9m001_start_capture,
        .stop_capture           = mt9m001_stop_capture,
-       .set_capture_format     = mt9m001_set_capture_format,
+       .set_fmt_cap            = mt9m001_set_fmt_cap,
        .try_fmt_cap            = mt9m001_try_fmt_cap,
-       .formats                = NULL, /* Filled in later depending on the */
-       .num_formats            = 0,    /* camera type and data widths */
-       .get_datawidth          = mt9m001_get_datawidth,
+       .set_bus_param          = mt9m001_set_bus_param,
+       .query_bus_param        = mt9m001_query_bus_param,
        .controls               = mt9m001_controls,
        .num_controls           = ARRAY_SIZE(mt9m001_controls),
        .get_control            = mt9m001_get_control,
@@ -554,19 +575,19 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
        case 0x8411:
        case 0x8421:
                mt9m001->model = V4L2_IDENT_MT9M001C12ST;
-               mt9m001_ops.formats = mt9m001_colour_formats;
+               icd->formats = mt9m001_colour_formats;
                if (mt9m001->client->dev.platform_data)
-                       mt9m001_ops.num_formats = ARRAY_SIZE(mt9m001_colour_formats);
+                       icd->num_formats = ARRAY_SIZE(mt9m001_colour_formats);
                else
-                       mt9m001_ops.num_formats = 1;
+                       icd->num_formats = 1;
                break;
        case 0x8431:
                mt9m001->model = V4L2_IDENT_MT9M001C12STM;
-               mt9m001_ops.formats = mt9m001_monochrome_formats;
+               icd->formats = mt9m001_monochrome_formats;
                if (mt9m001->client->dev.platform_data)
-                       mt9m001_ops.num_formats = ARRAY_SIZE(mt9m001_monochrome_formats);
+                       icd->num_formats = ARRAY_SIZE(mt9m001_monochrome_formats);
                else
-                       mt9m001_ops.num_formats = 1;
+                       icd->num_formats = 1;
                break;
        default:
                ret = -ENODEV;
@@ -627,8 +648,6 @@ static int mt9m001_probe(struct i2c_client *client)
 
        /* Second stage probe - when a capture adapter is there */
        icd = &mt9m001->icd;
-       icd->probe      = mt9m001_video_probe;
-       icd->remove     = mt9m001_video_remove;
        icd->ops        = &mt9m001_ops;
        icd->control    = &client->dev;
        icd->x_min      = 20;