]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/media/video/mt9t031.c
i2c: Remove all i2c_set_clientdata(client, NULL) in drivers
[net-next-2.6.git] / drivers / media / video / mt9t031.c
index a9061bff79b2189b6e542beaab7417ff7ed35a3d..9f5ff2547f1993bde3f594aa95bf4bb11d23c50d 100644 (file)
@@ -8,14 +8,16 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/videodev2.h>
-#include <linux/slab.h>
+#include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/log2.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
 
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-subdev.h>
 
 /*
  * mt9t031 i2c address 0x5d
@@ -680,6 +682,59 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
        return 0;
 }
 
+/*
+ * Power Management:
+ * This function does nothing for now but must be present for pm to work
+ */
+static int mt9t031_runtime_suspend(struct device *dev)
+{
+       return 0;
+}
+
+/*
+ * Power Management:
+ * COLUMN_ADDRESS_MODE and ROW_ADDRESS_MODE are not rewritten if unchanged
+ * they are however changed at reset if the platform hook is present
+ * thus we rewrite them with the values stored by the driver
+ */
+static int mt9t031_runtime_resume(struct device *dev)
+{
+       struct video_device *vdev = to_video_device(dev);
+       struct soc_camera_device *icd = container_of(vdev->parent,
+               struct soc_camera_device, dev);
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+       struct i2c_client *client = sd->priv;
+       struct mt9t031 *mt9t031 = to_mt9t031(client);
+
+       int ret;
+       u16 xbin, ybin;
+
+       xbin = min(mt9t031->xskip, (u16)3);
+       ybin = min(mt9t031->yskip, (u16)3);
+
+       ret = reg_write(client, MT9T031_COLUMN_ADDRESS_MODE,
+               ((xbin - 1) << 4) | (mt9t031->xskip - 1));
+       if (ret < 0)
+               return ret;
+
+       ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
+               ((ybin - 1) << 4) | (mt9t031->yskip - 1));
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static struct dev_pm_ops mt9t031_dev_pm_ops = {
+       .runtime_suspend        = mt9t031_runtime_suspend,
+       .runtime_resume         = mt9t031_runtime_resume,
+};
+
+static struct device_type mt9t031_dev_type = {
+       .name   = "MT9T031",
+       .pm     = &mt9t031_dev_pm_ops,
+};
+
 /*
  * Interface active, can use i2c. If it fails, it can indeed mean, that
  * this wasn't our capture interface, so, we wait for the right one
@@ -687,6 +742,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 static int mt9t031_video_probe(struct i2c_client *client)
 {
        struct mt9t031 *mt9t031 = to_mt9t031(client);
+       struct video_device *vdev = soc_camera_i2c_to_vdev(client);
        s32 data;
        int ret;
 
@@ -712,6 +768,8 @@ static int mt9t031_video_probe(struct i2c_client *client)
        ret = mt9t031_idle(client);
        if (ret < 0)
                dev_err(&client->dev, "Failed to initialise the camera\n");
+       else
+               vdev->dev.type = &mt9t031_dev_type;
 
        /* mt9t031_idle() has reset the chip to default. */
        mt9t031->exposure = 255;
@@ -825,7 +883,6 @@ static int mt9t031_probe(struct i2c_client *client,
        if (ret) {
                if (icd)
                        icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(mt9t031);
        }
 
@@ -839,7 +896,6 @@ static int mt9t031_remove(struct i2c_client *client)
 
        if (icd)
                icd->ops = NULL;
-       i2c_set_clientdata(client, NULL);
        client->driver = NULL;
        kfree(mt9t031);