aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/mt9t031.c66
1 files changed, 62 insertions, 4 deletions
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index a9061bff79b2..78b4e091d2d5 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -8,14 +8,16 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#include <linux/videodev2.h> 11#include <linux/device.h>
12#include <linux/slab.h>
13#include <linux/i2c.h> 12#include <linux/i2c.h>
14#include <linux/log2.h> 13#include <linux/log2.h>
14#include <linux/pm.h>
15#include <linux/slab.h>
16#include <linux/videodev2.h>
15 17
16#include <media/v4l2-subdev.h>
17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h> 18#include <media/soc_camera.h>
19#include <media/v4l2-chip-ident.h>
20#include <media/v4l2-subdev.h>
19 21
20/* 22/*
21 * mt9t031 i2c address 0x5d 23 * mt9t031 i2c address 0x5d
@@ -681,12 +683,66 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
681} 683}
682 684
683/* 685/*
686 * Power Management:
687 * This function does nothing for now but must be present for pm to work
688 */
689static int mt9t031_runtime_suspend(struct device *dev)
690{
691 return 0;
692}
693
694/*
695 * Power Management:
696 * COLUMN_ADDRESS_MODE and ROW_ADDRESS_MODE are not rewritten if unchanged
697 * they are however changed at reset if the platform hook is present
698 * thus we rewrite them with the values stored by the driver
699 */
700static int mt9t031_runtime_resume(struct device *dev)
701{
702 struct video_device *vdev = to_video_device(dev);
703 struct soc_camera_device *icd = container_of(vdev->parent,
704 struct soc_camera_device, dev);
705 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
706 struct i2c_client *client = sd->priv;
707 struct mt9t031 *mt9t031 = to_mt9t031(client);
708
709 int ret;
710 u16 xbin, ybin;
711
712 xbin = min(mt9t031->xskip, (u16)3);
713 ybin = min(mt9t031->yskip, (u16)3);
714
715 ret = reg_write(client, MT9T031_COLUMN_ADDRESS_MODE,
716 ((xbin - 1) << 4) | (mt9t031->xskip - 1));
717 if (ret < 0)
718 return ret;
719
720 ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
721 ((ybin - 1) << 4) | (mt9t031->yskip - 1));
722 if (ret < 0)
723 return ret;
724
725 return 0;
726}
727
728static struct dev_pm_ops mt9t031_dev_pm_ops = {
729 .runtime_suspend = mt9t031_runtime_suspend,
730 .runtime_resume = mt9t031_runtime_resume,
731};
732
733static struct device_type mt9t031_dev_type = {
734 .name = "MT9T031",
735 .pm = &mt9t031_dev_pm_ops,
736};
737
738/*
684 * Interface active, can use i2c. If it fails, it can indeed mean, that 739 * Interface active, can use i2c. If it fails, it can indeed mean, that
685 * this wasn't our capture interface, so, we wait for the right one 740 * this wasn't our capture interface, so, we wait for the right one
686 */ 741 */
687static int mt9t031_video_probe(struct i2c_client *client) 742static int mt9t031_video_probe(struct i2c_client *client)
688{ 743{
689 struct mt9t031 *mt9t031 = to_mt9t031(client); 744 struct mt9t031 *mt9t031 = to_mt9t031(client);
745 struct video_device *vdev = soc_camera_i2c_to_vdev(client);
690 s32 data; 746 s32 data;
691 int ret; 747 int ret;
692 748
@@ -712,6 +768,8 @@ static int mt9t031_video_probe(struct i2c_client *client)
712 ret = mt9t031_idle(client); 768 ret = mt9t031_idle(client);
713 if (ret < 0) 769 if (ret < 0)
714 dev_err(&client->dev, "Failed to initialise the camera\n"); 770 dev_err(&client->dev, "Failed to initialise the camera\n");
771 else
772 vdev->dev.type = &mt9t031_dev_type;
715 773
716 /* mt9t031_idle() has reset the chip to default. */ 774 /* mt9t031_idle() has reset the chip to default. */
717 mt9t031->exposure = 255; 775 mt9t031->exposure = 255;