11 #include <linux/videodev2.h>
12 #include <linux/slab.h>
13 #include <linux/i2c.h>
16 #include <linux/module.h>
30 static char *sensor_type;
35 #define MT9V022_CHIP_VERSION 0x00
36 #define MT9V022_COLUMN_START 0x01
37 #define MT9V022_ROW_START 0x02
38 #define MT9V022_WINDOW_HEIGHT 0x03
39 #define MT9V022_WINDOW_WIDTH 0x04
40 #define MT9V022_HORIZONTAL_BLANKING 0x05
41 #define MT9V022_VERTICAL_BLANKING 0x06
42 #define MT9V022_CHIP_CONTROL 0x07
43 #define MT9V022_SHUTTER_WIDTH1 0x08
44 #define MT9V022_SHUTTER_WIDTH2 0x09
45 #define MT9V022_SHUTTER_WIDTH_CTRL 0x0a
46 #define MT9V022_TOTAL_SHUTTER_WIDTH 0x0b
47 #define MT9V022_RESET 0x0c
48 #define MT9V022_READ_MODE 0x0d
49 #define MT9V022_MONITOR_MODE 0x0e
50 #define MT9V022_PIXEL_OPERATION_MODE 0x0f
51 #define MT9V022_LED_OUT_CONTROL 0x1b
52 #define MT9V022_ADC_MODE_CONTROL 0x1c
53 #define MT9V022_ANALOG_GAIN 0x35
54 #define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47
55 #define MT9V022_PIXCLK_FV_LV 0x74
56 #define MT9V022_DIGITAL_TEST_PATTERN 0x7f
57 #define MT9V022_AEC_AGC_ENABLE 0xAF
58 #define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD
61 #define MT9V024_PIXCLK_FV_LV 0x72
62 #define MT9V024_MAX_TOTAL_SHUTTER_WIDTH 0xAD
65 #define MT9V022_CHIP_CONTROL_DEFAULT 0x188
67 #define MT9V022_MAX_WIDTH 752
68 #define MT9V022_MAX_HEIGHT 480
69 #define MT9V022_MIN_WIDTH 48
70 #define MT9V022_MIN_HEIGHT 32
71 #define MT9V022_COLUMN_SKIP 1
72 #define MT9V022_ROW_SKIP 4
74 #define is_mt9v024(id) (id == 0x1324)
88 for (i = 0; i <
n; i++)
89 if (fmt[i].code == code)
156 return i2c_smbus_read_word_swapped(client, reg);
162 return i2c_smbus_write_word_swapped(client, reg, data);
173 return reg_write(client, reg, ret | data);
184 return reg_write(client, reg, ret & ~data);
187 static int mt9v022_init(
struct i2c_client *client)
211 ret =
reg_write(client, mt9v022->
reg->max_total_shutter_width, 480);
225 struct i2c_client *client = v4l2_get_subdevdata(sd);
226 struct mt9v022 *mt9v022 = to_mt9v022(client);
242 struct i2c_client *client = v4l2_get_subdevdata(sd);
243 struct mt9v022 *mt9v022 = to_mt9v022(client);
248 if (mt9v022->
fmts == mt9v022_colour_fmts) {
254 soc_camera_limit_side(&rect.
left, &rect.
width,
257 soc_camera_limit_side(&rect.
top, &rect.
height,
264 ret =
reg_write(client, mt9v022->
reg->max_total_shutter_width,
286 rect.
width > 660 - 43 ? 43 :
301 mt9v022->
rect = rect;
308 struct i2c_client *client = v4l2_get_subdevdata(sd);
309 struct mt9v022 *mt9v022 = to_mt9v022(client);
311 a->
c = mt9v022->
rect;
332 struct v4l2_mbus_framefmt *mf)
334 struct i2c_client *client = v4l2_get_subdevdata(sd);
335 struct mt9v022 *mt9v022 = to_mt9v022(client);
337 mf->width = mt9v022->
rect.width;
338 mf->height = mt9v022->
rect.height;
339 mf->code = mt9v022->
fmt->code;
340 mf->colorspace = mt9v022->
fmt->colorspace;
347 struct v4l2_mbus_framefmt *mf)
349 struct i2c_client *client = v4l2_get_subdevdata(sd);
350 struct mt9v022 *mt9v022 = to_mt9v022(client);
353 .left = mt9v022->
rect.left,
354 .top = mt9v022->
rect.top,
356 .height = mf->height,
381 ret = mt9v022_s_crop(sd, &a);
383 mf->width = mt9v022->
rect.width;
384 mf->height = mt9v022->
rect.height;
385 mt9v022->
fmt = mt9v022_find_datafmt(mf->code,
387 mf->colorspace = mt9v022->
fmt->colorspace;
394 struct v4l2_mbus_framefmt *mf)
396 struct i2c_client *client = v4l2_get_subdevdata(sd);
397 struct mt9v022 *mt9v022 = to_mt9v022(client);
407 fmt = mt9v022_find_datafmt(mf->code, mt9v022->
fmts,
411 mf->code = fmt->
code;
419 static int mt9v022_g_chip_ident(
struct v4l2_subdev *sd,
422 struct i2c_client *client = v4l2_get_subdevdata(sd);
423 struct mt9v022 *mt9v022 = to_mt9v022(client);
431 id->ident = mt9v022->
model;
437 #ifdef CONFIG_VIDEO_ADV_DEBUG
438 static int mt9v022_g_register(
struct v4l2_subdev *sd,
441 struct i2c_client *client = v4l2_get_subdevdata(sd);
452 if (reg->
val > 0xffff)
458 static int mt9v022_s_register(
struct v4l2_subdev *sd,
461 struct i2c_client *client = v4l2_get_subdevdata(sd);
476 static int mt9v022_s_power(
struct v4l2_subdev *sd,
int on)
478 struct i2c_client *client = v4l2_get_subdevdata(sd);
481 return soc_camera_set_power(&client->
dev, icl, on);
487 struct mt9v022,
hdl);
489 struct i2c_client *client = v4l2_get_subdevdata(sd);
502 gain->
val = ((data - 16) * range + 24) / 48 + gain->
minimum;
510 exp->
val = ((data - 1) * range + 239) / 479 + exp->
minimum;
516 static int mt9v022_s_ctrl(
struct v4l2_ctrl *ctrl)
519 struct mt9v022,
hdl);
521 struct i2c_client *client = v4l2_get_subdevdata(sd);
550 unsigned long gain_val = ((gain->
val - gain->
minimum) *
551 48 + range / 2) / range + 16;
563 dev_dbg(&client->
dev,
"Setting gain from %d to %lu\n",
575 unsigned long shutter = ((exp->
val - exp->
minimum) *
576 479 + range / 2) / range + 1;
585 dev_dbg(&client->
dev,
"Shutter width from %d to %lu\n",
601 static int mt9v022_video_probe(
struct i2c_client *client)
603 struct mt9v022 *mt9v022 = to_mt9v022(client);
609 ret = mt9v022_s_power(&mt9v022->
subdev, 1);
617 if (data != 0x1311 && data != 0x1313 && data != 0x1324) {
619 dev_info(&client->
dev,
"No MT9V022 found, ID register 0x%x\n",
634 dev_err(&client->
dev,
"Resetting MT9V022 failed!\n");
641 if (sensor_type && (!
strcmp(
"colour", sensor_type) ||
642 !
strcmp(
"color", sensor_type))) {
645 mt9v022->
fmts = mt9v022_colour_fmts;
649 mt9v022->
fmts = mt9v022_monochrome_fmts;
667 if (flags & SOCAM_DATAWIDTH_10)
672 if (flags & SOCAM_DATAWIDTH_8)
675 mt9v022->
fmt = &mt9v022->
fmts[0];
677 dev_info(&client->
dev,
"Detected a MT9V022 chip ID %x, %s sensor\n",
679 "monochrome" :
"colour");
681 ret = mt9v022_init(client);
683 dev_err(&client->
dev,
"Failed to initialise the camera\n");
686 mt9v022_s_power(&mt9v022->
subdev, 0);
690 static int mt9v022_g_skip_top_lines(
struct v4l2_subdev *sd,
u32 *lines)
692 struct i2c_client *client = v4l2_get_subdevdata(sd);
693 struct mt9v022 *mt9v022 = to_mt9v022(client);
701 .g_volatile_ctrl = mt9v022_g_volatile_ctrl,
702 .s_ctrl = mt9v022_s_ctrl,
706 .g_chip_ident = mt9v022_g_chip_ident,
707 #ifdef CONFIG_VIDEO_ADV_DEBUG
708 .g_register = mt9v022_g_register,
709 .s_register = mt9v022_s_register,
711 .s_power = mt9v022_s_power,
717 struct i2c_client *client = v4l2_get_subdevdata(sd);
718 struct mt9v022 *mt9v022 = to_mt9v022(client);
727 static int mt9v022_g_mbus_config(
struct v4l2_subdev *sd,
730 struct i2c_client *client = v4l2_get_subdevdata(sd);
744 static int mt9v022_s_mbus_config(
struct v4l2_subdev *sd,
747 struct i2c_client *client = v4l2_get_subdevdata(sd);
749 struct mt9v022 *mt9v022 = to_mt9v022(client);
759 }
else if (bps != 10) {
776 ret =
reg_write(client, mt9v022->
reg->pixclk_fv_lv, pixclk);
787 dev_dbg(&client->
dev,
"Calculated pixclk 0x%x, chip control 0x%x\n",
794 .s_stream = mt9v022_s_stream,
795 .s_mbus_fmt = mt9v022_s_fmt,
796 .g_mbus_fmt = mt9v022_g_fmt,
797 .try_mbus_fmt = mt9v022_try_fmt,
798 .s_crop = mt9v022_s_crop,
799 .g_crop = mt9v022_g_crop,
800 .cropcap = mt9v022_cropcap,
801 .enum_mbus_fmt = mt9v022_enum_fmt,
802 .g_mbus_config = mt9v022_g_mbus_config,
803 .s_mbus_config = mt9v022_s_mbus_config,
807 .g_skip_top_lines = mt9v022_g_skip_top_lines,
811 .core = &mt9v022_subdev_core_ops,
812 .video = &mt9v022_subdev_video_ops,
813 .sensor = &mt9v022_subdev_sensor_ops,
816 static int mt9v022_probe(
struct i2c_client *client,
819 struct mt9v022 *mt9v022;
825 dev_err(&client->
dev,
"MT9V022 driver needs platform data\n");
831 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
835 mt9v022 = kzalloc(
sizeof(
struct mt9v022),
GFP_KERNEL);
860 mt9v022->
subdev.ctrl_handler = &mt9v022->
hdl;
861 if (mt9v022->
hdl.error) {
862 int err = mt9v022->
hdl.error;
883 ret = mt9v022_video_probe(client);
892 static int mt9v022_remove(
struct i2c_client *client)
894 struct mt9v022 *mt9v022 = to_mt9v022(client);
911 static struct i2c_driver mt9v022_i2c_driver = {
915 .probe = mt9v022_probe,
916 .remove = mt9v022_remove,
917 .id_table = mt9v022_id,