17 #include <linux/bitops.h>
19 #include <linux/i2c.h>
20 #include <linux/kernel.h>
21 #include <linux/slab.h>
22 #include <linux/videodev2.h>
23 #include <linux/module.h>
31 #define REG_CHIP_ID_HIGH 0x300a
32 #define REG_CHIP_ID_LOW 0x300b
34 #define REG_WINDOW_START_X_HIGH 0x3800
35 #define REG_WINDOW_START_X_LOW 0x3801
36 #define REG_WINDOW_START_Y_HIGH 0x3802
37 #define REG_WINDOW_START_Y_LOW 0x3803
38 #define REG_WINDOW_WIDTH_HIGH 0x3804
39 #define REG_WINDOW_WIDTH_LOW 0x3805
40 #define REG_WINDOW_HEIGHT_HIGH 0x3806
41 #define REG_WINDOW_HEIGHT_LOW 0x3807
42 #define REG_OUT_WIDTH_HIGH 0x3808
43 #define REG_OUT_WIDTH_LOW 0x3809
44 #define REG_OUT_HEIGHT_HIGH 0x380a
45 #define REG_OUT_HEIGHT_LOW 0x380b
46 #define REG_OUT_TOTAL_WIDTH_HIGH 0x380c
47 #define REG_OUT_TOTAL_WIDTH_LOW 0x380d
48 #define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e
49 #define REG_OUT_TOTAL_HEIGHT_LOW 0x380f
50 #define REG_OUTPUT_FORMAT 0x4300
51 #define REG_ISP_CTRL_01 0x5001
52 #define REG_AVG_WINDOW_END_X_HIGH 0x5682
53 #define REG_AVG_WINDOW_END_X_LOW 0x5683
54 #define REG_AVG_WINDOW_END_Y_HIGH 0x5686
55 #define REG_AVG_WINDOW_END_Y_LOW 0x5687
58 #define OV5642_SENSOR_SIZE_X 2592
59 #define OV5642_SENSOR_SIZE_Y 1944
71 #define OV5642_MAX_WIDTH OV5642_SENSOR_SIZE_X
72 #define OV5642_MAX_HEIGHT 720
75 #define OV5642_DEFAULT_WIDTH 1280
76 #define OV5642_DEFAULT_HEIGHT OV5642_MAX_HEIGHT
79 #define BLANKING_EXTRA_WIDTH 500
80 #define BLANKING_EXTRA_HEIGHT 20
87 #define BLANKING_MIN_HEIGHT 1000
94 static struct regval_list ov5642_default_regs_init[] = {
555 static struct regval_list ov5642_default_regs_finalise[] = {
634 for (i = 0; i <
ARRAY_SIZE(ov5642_colour_fmts); i++)
635 if (ov5642_colour_fmts[i].code == code)
636 return ov5642_colour_fmts +
i;
645 unsigned char data[2] = { reg >> 8, reg & 0xff };
649 dev_err(&client->
dev,
"%s: i2c read error, reg: %x\n",
651 return ret < 0 ? ret : -
EIO;
656 dev_err(&client->
dev,
"%s: i2c read error, reg: %x\n",
658 return ret < 0 ? ret : -
EIO;
666 unsigned char data[3] = { reg >> 8, reg & 0xff, val };
670 dev_err(&client->
dev,
"%s: i2c write error, reg: %x\n",
672 return ret < 0 ? ret : -
EIO;
686 ret =
reg_write(client, reg, val16 >> 8);
689 return reg_write(client, reg + 1, val16 & 0x00ff);
692 #ifdef CONFIG_VIDEO_ADV_DEBUG
695 struct i2c_client *client = v4l2_get_subdevdata(sd);
699 if (reg->
reg & ~0xffff)
713 struct i2c_client *client = v4l2_get_subdevdata(sd);
715 if (reg->
reg & ~0xffff || reg->
val & ~0xff)
722 static int ov5642_write_array(
struct i2c_client *client,
725 while (vals->
reg_num != 0xffff || vals->
value != 0xff) {
731 dev_dbg(&client->
dev,
"Register list loaded\n");
735 static int ov5642_set_resolution(
struct v4l2_subdev *sd)
737 struct i2c_client *client = v4l2_get_subdevdata(sd);
789 struct v4l2_mbus_framefmt *mf)
791 struct i2c_client *client = v4l2_get_subdevdata(sd);
792 struct ov5642 *priv = to_ov5642(client);
799 mf->code = ov5642_colour_fmts[0].
code;
800 mf->colorspace = ov5642_colour_fmts[0].
colorspace;
809 struct v4l2_mbus_framefmt *mf)
811 struct i2c_client *client = v4l2_get_subdevdata(sd);
812 struct ov5642 *priv = to_ov5642(client);
815 if (!ov5642_find_datafmt(mf->code))
818 ov5642_try_fmt(sd, mf);
819 priv->
fmt = ov5642_find_datafmt(mf->code);
825 struct v4l2_mbus_framefmt *mf)
827 struct i2c_client *client = v4l2_get_subdevdata(sd);
828 struct ov5642 *priv = to_ov5642(client);
832 mf->code = fmt->
code;
851 static int ov5642_g_chip_ident(
struct v4l2_subdev *sd,
854 struct i2c_client *client = v4l2_get_subdevdata(sd);
870 struct i2c_client *client = v4l2_get_subdevdata(sd);
871 struct ov5642 *priv = to_ov5642(client);
887 ret = ov5642_write_array(client, ov5642_default_regs_init);
889 ret = ov5642_set_resolution(sd);
891 ret = ov5642_write_array(client, ov5642_default_regs_finalise);
898 struct i2c_client *client = v4l2_get_subdevdata(sd);
899 struct ov5642 *priv = to_ov5642(client);
924 static int ov5642_g_mbus_config(
struct v4l2_subdev *sd,
934 static int ov5642_s_power(
struct v4l2_subdev *sd,
int on)
936 struct i2c_client *client = v4l2_get_subdevdata(sd);
947 ret = ov5642_write_array(client, ov5642_default_regs_init);
949 ret = ov5642_set_resolution(sd);
951 ret = ov5642_write_array(client, ov5642_default_regs_finalise);
957 .s_mbus_fmt = ov5642_s_fmt,
958 .g_mbus_fmt = ov5642_g_fmt,
959 .try_mbus_fmt = ov5642_try_fmt,
960 .enum_mbus_fmt = ov5642_enum_fmt,
961 .s_crop = ov5642_s_crop,
962 .g_crop = ov5642_g_crop,
963 .cropcap = ov5642_cropcap,
964 .g_mbus_config = ov5642_g_mbus_config,
968 .s_power = ov5642_s_power,
969 .g_chip_ident = ov5642_g_chip_ident,
970 #ifdef CONFIG_VIDEO_ADV_DEBUG
971 .g_register = ov5642_get_register,
972 .s_register = ov5642_set_register,
977 .core = &ov5642_subdev_core_ops,
978 .video = &ov5642_subdev_video_ops,
981 static int ov5642_video_probe(
struct i2c_client *client)
988 ret = ov5642_s_power(subdev, 1);
1005 dev_info(&client->
dev,
"Chip ID 0x%04x detected\n",
id);
1015 ov5642_s_power(subdev, 0);
1019 static int ov5642_probe(
struct i2c_client *client,
1027 dev_err(&client->
dev,
"OV5642: missing platform data!\n");
1037 priv->
fmt = &ov5642_colour_fmts[0];
1046 ret = ov5642_video_probe(client);
1057 static int ov5642_remove(
struct i2c_client *client)
1059 struct ov5642 *priv = to_ov5642(client);
1075 static struct i2c_driver ov5642_i2c_driver = {
1079 .probe = ov5642_probe,
1080 .remove = ov5642_remove,
1081 .id_table = ov5642_id,