aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorAlex Gershgorin <alexg@meprolight.com>2012-08-02 11:32:41 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-15 19:04:08 -0400
commitc078ac18f3f94f643ab477949d0cd93667904e06 (patch)
tree936fed9f57ab4398fce0051d62a46dc465f7fbbf /drivers/media
parenteb68faaf6685dca904cc92dfbe1028eb5475d662 (diff)
[media] mt9v022: Add support for mt9v024
Driver for mt9v022 camera sensor is fully compatible for mt9v024 camera sensor with the exception of several registers which have been changed addresses. mt9v024 also has improved and additional features, but they are currently not in use. Signed-off-by: Alex Gershgorin <alexg@meprolight.com> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/i2c/soc_camera/Kconfig2
-rw-r--r--drivers/media/i2c/soc_camera/mt9v022.c36
2 files changed, 32 insertions, 6 deletions
diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig
index 73fe21d1b2df..6dff2b7ad520 100644
--- a/drivers/media/i2c/soc_camera/Kconfig
+++ b/drivers/media/i2c/soc_camera/Kconfig
@@ -34,7 +34,7 @@ config SOC_CAMERA_MT9T112
34 This driver supports MT9T112 cameras from Aptina. 34 This driver supports MT9T112 cameras from Aptina.
35 35
36config SOC_CAMERA_MT9V022 36config SOC_CAMERA_MT9V022
37 tristate "mt9v022 support" 37 tristate "mt9v022 and mt9v024 support"
38 depends on SOC_CAMERA && I2C 38 depends on SOC_CAMERA && I2C
39 select GPIO_PCA953X if MT9V022_PCA9536_SWITCH 39 select GPIO_PCA953X if MT9V022_PCA9536_SWITCH
40 help 40 help
diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c
index 2edea8489092..350d0d854447 100644
--- a/drivers/media/i2c/soc_camera/mt9v022.c
+++ b/drivers/media/i2c/soc_camera/mt9v022.c
@@ -57,6 +57,10 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
57#define MT9V022_AEC_AGC_ENABLE 0xAF 57#define MT9V022_AEC_AGC_ENABLE 0xAF
58#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD 58#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD
59 59
60/* mt9v024 partial list register addresses changes with respect to mt9v022 */
61#define MT9V024_PIXCLK_FV_LV 0x72
62#define MT9V024_MAX_TOTAL_SHUTTER_WIDTH 0xAD
63
60/* Progressive scan, master, defaults */ 64/* Progressive scan, master, defaults */
61#define MT9V022_CHIP_CONTROL_DEFAULT 0x188 65#define MT9V022_CHIP_CONTROL_DEFAULT 0x188
62 66
@@ -67,6 +71,8 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
67#define MT9V022_COLUMN_SKIP 1 71#define MT9V022_COLUMN_SKIP 1
68#define MT9V022_ROW_SKIP 4 72#define MT9V022_ROW_SKIP 4
69 73
74#define is_mt9v024(id) (id == 0x1324)
75
70/* MT9V022 has only one fixed colorspace per pixelcode */ 76/* MT9V022 has only one fixed colorspace per pixelcode */
71struct mt9v022_datafmt { 77struct mt9v022_datafmt {
72 enum v4l2_mbus_pixelcode code; 78 enum v4l2_mbus_pixelcode code;
@@ -101,6 +107,22 @@ static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
101 {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG}, 107 {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
102}; 108};
103 109
110/* only registers with different addresses on different mt9v02x sensors */
111struct mt9v02x_register {
112 u8 max_total_shutter_width;
113 u8 pixclk_fv_lv;
114};
115
116static const struct mt9v02x_register mt9v022_register = {
117 .max_total_shutter_width = MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
118 .pixclk_fv_lv = MT9V022_PIXCLK_FV_LV,
119};
120
121static const struct mt9v02x_register mt9v024_register = {
122 .max_total_shutter_width = MT9V024_MAX_TOTAL_SHUTTER_WIDTH,
123 .pixclk_fv_lv = MT9V024_PIXCLK_FV_LV,
124};
125
104struct mt9v022 { 126struct mt9v022 {
105 struct v4l2_subdev subdev; 127 struct v4l2_subdev subdev;
106 struct v4l2_ctrl_handler hdl; 128 struct v4l2_ctrl_handler hdl;
@@ -117,6 +139,7 @@ struct mt9v022 {
117 struct v4l2_rect rect; /* Sensor window */ 139 struct v4l2_rect rect; /* Sensor window */
118 const struct mt9v022_datafmt *fmt; 140 const struct mt9v022_datafmt *fmt;
119 const struct mt9v022_datafmt *fmts; 141 const struct mt9v022_datafmt *fmts;
142 const struct mt9v02x_register *reg;
120 int num_fmts; 143 int num_fmts;
121 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ 144 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
122 u16 chip_control; 145 u16 chip_control;
@@ -185,7 +208,7 @@ static int mt9v022_init(struct i2c_client *client)
185 if (!ret) 208 if (!ret)
186 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480); 209 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
187 if (!ret) 210 if (!ret)
188 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); 211 ret = reg_write(client, mt9v022->reg->max_total_shutter_width, 480);
189 if (!ret) 212 if (!ret)
190 /* default - auto */ 213 /* default - auto */
191 ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); 214 ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
@@ -238,7 +261,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
238 ret = reg_read(client, MT9V022_AEC_AGC_ENABLE); 261 ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
239 if (ret >= 0) { 262 if (ret >= 0) {
240 if (ret & 1) /* Autoexposure */ 263 if (ret & 1) /* Autoexposure */
241 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 264 ret = reg_write(client, mt9v022->reg->max_total_shutter_width,
242 rect.height + mt9v022->y_skip_top + 43); 265 rect.height + mt9v022->y_skip_top + 43);
243 else 266 else
244 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 267 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
@@ -585,14 +608,17 @@ static int mt9v022_video_probe(struct i2c_client *client)
585 /* Read out the chip version register */ 608 /* Read out the chip version register */
586 data = reg_read(client, MT9V022_CHIP_VERSION); 609 data = reg_read(client, MT9V022_CHIP_VERSION);
587 610
588 /* must be 0x1311 or 0x1313 */ 611 /* must be 0x1311, 0x1313 or 0x1324 */
589 if (data != 0x1311 && data != 0x1313) { 612 if (data != 0x1311 && data != 0x1313 && data != 0x1324) {
590 ret = -ENODEV; 613 ret = -ENODEV;
591 dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n", 614 dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
592 data); 615 data);
593 goto ei2c; 616 goto ei2c;
594 } 617 }
595 618
619 mt9v022->reg = is_mt9v024(data) ? &mt9v024_register :
620 &mt9v022_register;
621
596 /* Soft reset */ 622 /* Soft reset */
597 ret = reg_write(client, MT9V022_RESET, 1); 623 ret = reg_write(client, MT9V022_RESET, 1);
598 if (ret < 0) 624 if (ret < 0)
@@ -742,7 +768,7 @@ static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
742 if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)) 768 if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH))
743 pixclk |= 0x2; 769 pixclk |= 0x2;
744 770
745 ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk); 771 ret = reg_write(client, mt9v022->reg->pixclk_fv_lv, pixclk);
746 if (ret < 0) 772 if (ret < 0)
747 return ret; 773 return ret;
748 774