2 * Driver for OV5642 CMOS Image Sensor from Omnivision
4 * Copyright (C) 2011, Bastian Hecht <hechtb@gmail.com>
6 * Based on Sony IMX074 Camera Driver
7 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
9 * Based on Omnivision OV7670 Camera Driver
10 * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
17 #include <linux/bitops.h>
18 #include <linux/delay.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>
24 #include <linux/v4l2-mediabus.h>
26 #include <media/soc_camera.h>
27 #include <media/v4l2-clk.h>
28 #include <media/v4l2-subdev.h>
30 /* OV5642 registers */
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
57 /* active pixel array size */
58 #define OV5642_SENSOR_SIZE_X 2592
59 #define OV5642_SENSOR_SIZE_Y 1944
62 * About OV5642 resolution, cropping and binning:
63 * This sensor supports it all, at least in the feature description.
64 * Unfortunately, no combination of appropriate registers settings could make
65 * the chip work the intended way. As it works with predefined register lists,
66 * some undocumented registers are presumably changed there to achieve their
68 * This driver currently only works for resolutions up to 720 lines with a
69 * 1:1 scale. Hopefully these restrictions will be removed in the future.
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
78 /* minimum extra blanking */
79 #define BLANKING_EXTRA_WIDTH 500
80 #define BLANKING_EXTRA_HEIGHT 20
83 * the sensor's autoexposure is buggy when setting total_height low.
84 * It tries to expose longer than 1 frame period without taking care of it
85 * and this leads to weird output. So we set 1000 lines as minimum.
87 #define BLANKING_MIN_HEIGHT 1000
94 static struct regval_list ov5642_default_regs_init
[] = {
555 static struct regval_list ov5642_default_regs_finalise
[] = {
588 { 0x4300, 0x32 }, /* UYVY */
604 struct ov5642_datafmt
{
605 enum v4l2_mbus_pixelcode code
;
606 enum v4l2_colorspace colorspace
;
610 struct v4l2_subdev subdev
;
611 const struct ov5642_datafmt
*fmt
;
612 struct v4l2_rect crop_rect
;
613 struct v4l2_clk
*clk
;
615 /* blanking information */
620 static const struct ov5642_datafmt ov5642_colour_fmts
[] = {
621 {V4L2_MBUS_FMT_UYVY8_2X8
, V4L2_COLORSPACE_JPEG
},
624 static struct ov5642
*to_ov5642(const struct i2c_client
*client
)
626 return container_of(i2c_get_clientdata(client
), struct ov5642
, subdev
);
629 /* Find a data format by a pixel code in an array */
630 static const struct ov5642_datafmt
631 *ov5642_find_datafmt(enum v4l2_mbus_pixelcode code
)
635 for (i
= 0; i
< ARRAY_SIZE(ov5642_colour_fmts
); i
++)
636 if (ov5642_colour_fmts
[i
].code
== code
)
637 return ov5642_colour_fmts
+ i
;
642 static int reg_read(struct i2c_client
*client
, u16 reg
, u8
*val
)
645 /* We have 16-bit i2c addresses - care for endianness */
646 unsigned char data
[2] = { reg
>> 8, reg
& 0xff };
648 ret
= i2c_master_send(client
, data
, 2);
650 dev_err(&client
->dev
, "%s: i2c read error, reg: %x\n",
652 return ret
< 0 ? ret
: -EIO
;
655 ret
= i2c_master_recv(client
, val
, 1);
657 dev_err(&client
->dev
, "%s: i2c read error, reg: %x\n",
659 return ret
< 0 ? ret
: -EIO
;
664 static int reg_write(struct i2c_client
*client
, u16 reg
, u8 val
)
667 unsigned char data
[3] = { reg
>> 8, reg
& 0xff, val
};
669 ret
= i2c_master_send(client
, data
, 3);
671 dev_err(&client
->dev
, "%s: i2c write error, reg: %x\n",
673 return ret
< 0 ? ret
: -EIO
;
680 * convenience function to write 16 bit register values that are split up
681 * into two consecutive high and low parts
683 static int reg_write16(struct i2c_client
*client
, u16 reg
, u16 val16
)
687 ret
= reg_write(client
, reg
, val16
>> 8);
690 return reg_write(client
, reg
+ 1, val16
& 0x00ff);
693 #ifdef CONFIG_VIDEO_ADV_DEBUG
694 static int ov5642_get_register(struct v4l2_subdev
*sd
, struct v4l2_dbg_register
*reg
)
696 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
700 if (reg
->reg
& ~0xffff)
705 ret
= reg_read(client
, reg
->reg
, &val
);
707 reg
->val
= (__u64
)val
;
712 static int ov5642_set_register(struct v4l2_subdev
*sd
, const struct v4l2_dbg_register
*reg
)
714 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
716 if (reg
->reg
& ~0xffff || reg
->val
& ~0xff)
719 return reg_write(client
, reg
->reg
, reg
->val
);
723 static int ov5642_write_array(struct i2c_client
*client
,
724 struct regval_list
*vals
)
726 while (vals
->reg_num
!= 0xffff || vals
->value
!= 0xff) {
727 int ret
= reg_write(client
, vals
->reg_num
, vals
->value
);
732 dev_dbg(&client
->dev
, "Register list loaded\n");
736 static int ov5642_set_resolution(struct v4l2_subdev
*sd
)
738 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
739 struct ov5642
*priv
= to_ov5642(client
);
740 int width
= priv
->crop_rect
.width
;
741 int height
= priv
->crop_rect
.height
;
742 int total_width
= priv
->total_width
;
743 int total_height
= priv
->total_height
;
744 int start_x
= (OV5642_SENSOR_SIZE_X
- width
) / 2;
745 int start_y
= (OV5642_SENSOR_SIZE_Y
- height
) / 2;
749 * This should set the starting point for cropping.
750 * Doesn't work so far.
752 ret
= reg_write16(client
, REG_WINDOW_START_X_HIGH
, start_x
);
754 ret
= reg_write16(client
, REG_WINDOW_START_Y_HIGH
, start_y
);
756 priv
->crop_rect
.left
= start_x
;
757 priv
->crop_rect
.top
= start_y
;
761 ret
= reg_write16(client
, REG_WINDOW_WIDTH_HIGH
, width
);
763 ret
= reg_write16(client
, REG_WINDOW_HEIGHT_HIGH
, height
);
766 priv
->crop_rect
.width
= width
;
767 priv
->crop_rect
.height
= height
;
769 /* Set the output window size. Only 1:1 scale is supported so far. */
770 ret
= reg_write16(client
, REG_OUT_WIDTH_HIGH
, width
);
772 ret
= reg_write16(client
, REG_OUT_HEIGHT_HIGH
, height
);
774 /* Total width = output size + blanking */
776 ret
= reg_write16(client
, REG_OUT_TOTAL_WIDTH_HIGH
, total_width
);
778 ret
= reg_write16(client
, REG_OUT_TOTAL_HEIGHT_HIGH
, total_height
);
780 /* Sets the window for AWB calculations */
782 ret
= reg_write16(client
, REG_AVG_WINDOW_END_X_HIGH
, width
);
784 ret
= reg_write16(client
, REG_AVG_WINDOW_END_Y_HIGH
, height
);
789 static int ov5642_try_fmt(struct v4l2_subdev
*sd
,
790 struct v4l2_mbus_framefmt
*mf
)
792 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
793 struct ov5642
*priv
= to_ov5642(client
);
794 const struct ov5642_datafmt
*fmt
= ov5642_find_datafmt(mf
->code
);
796 mf
->width
= priv
->crop_rect
.width
;
797 mf
->height
= priv
->crop_rect
.height
;
800 mf
->code
= ov5642_colour_fmts
[0].code
;
801 mf
->colorspace
= ov5642_colour_fmts
[0].colorspace
;
804 mf
->field
= V4L2_FIELD_NONE
;
809 static int ov5642_s_fmt(struct v4l2_subdev
*sd
,
810 struct v4l2_mbus_framefmt
*mf
)
812 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
813 struct ov5642
*priv
= to_ov5642(client
);
815 /* MIPI CSI could have changed the format, double-check */
816 if (!ov5642_find_datafmt(mf
->code
))
819 ov5642_try_fmt(sd
, mf
);
820 priv
->fmt
= ov5642_find_datafmt(mf
->code
);
825 static int ov5642_g_fmt(struct v4l2_subdev
*sd
,
826 struct v4l2_mbus_framefmt
*mf
)
828 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
829 struct ov5642
*priv
= to_ov5642(client
);
831 const struct ov5642_datafmt
*fmt
= priv
->fmt
;
833 mf
->code
= fmt
->code
;
834 mf
->colorspace
= fmt
->colorspace
;
835 mf
->width
= priv
->crop_rect
.width
;
836 mf
->height
= priv
->crop_rect
.height
;
837 mf
->field
= V4L2_FIELD_NONE
;
842 static int ov5642_enum_fmt(struct v4l2_subdev
*sd
, unsigned int index
,
843 enum v4l2_mbus_pixelcode
*code
)
845 if (index
>= ARRAY_SIZE(ov5642_colour_fmts
))
848 *code
= ov5642_colour_fmts
[index
].code
;
852 static int ov5642_s_crop(struct v4l2_subdev
*sd
, const struct v4l2_crop
*a
)
854 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
855 struct ov5642
*priv
= to_ov5642(client
);
856 struct v4l2_rect rect
= a
->c
;
859 v4l_bound_align_image(&rect
.width
, 48, OV5642_MAX_WIDTH
, 1,
860 &rect
.height
, 32, OV5642_MAX_HEIGHT
, 1, 0);
862 priv
->crop_rect
.width
= rect
.width
;
863 priv
->crop_rect
.height
= rect
.height
;
864 priv
->total_width
= rect
.width
+ BLANKING_EXTRA_WIDTH
;
865 priv
->total_height
= max_t(int, rect
.height
+
866 BLANKING_EXTRA_HEIGHT
,
867 BLANKING_MIN_HEIGHT
);
868 priv
->crop_rect
.width
= rect
.width
;
869 priv
->crop_rect
.height
= rect
.height
;
871 ret
= ov5642_write_array(client
, ov5642_default_regs_init
);
873 ret
= ov5642_set_resolution(sd
);
875 ret
= ov5642_write_array(client
, ov5642_default_regs_finalise
);
880 static int ov5642_g_crop(struct v4l2_subdev
*sd
, struct v4l2_crop
*a
)
882 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
883 struct ov5642
*priv
= to_ov5642(client
);
884 struct v4l2_rect
*rect
= &a
->c
;
886 if (a
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
889 *rect
= priv
->crop_rect
;
894 static int ov5642_cropcap(struct v4l2_subdev
*sd
, struct v4l2_cropcap
*a
)
898 a
->bounds
.width
= OV5642_MAX_WIDTH
;
899 a
->bounds
.height
= OV5642_MAX_HEIGHT
;
900 a
->defrect
= a
->bounds
;
901 a
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
902 a
->pixelaspect
.numerator
= 1;
903 a
->pixelaspect
.denominator
= 1;
908 static int ov5642_g_mbus_config(struct v4l2_subdev
*sd
,
909 struct v4l2_mbus_config
*cfg
)
911 cfg
->type
= V4L2_MBUS_CSI2
;
912 cfg
->flags
= V4L2_MBUS_CSI2_2_LANE
| V4L2_MBUS_CSI2_CHANNEL_0
|
913 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK
;
918 static int ov5642_s_power(struct v4l2_subdev
*sd
, int on
)
920 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
921 struct soc_camera_subdev_desc
*ssdd
= soc_camera_i2c_to_desc(client
);
922 struct ov5642
*priv
= to_ov5642(client
);
926 return soc_camera_power_off(&client
->dev
, ssdd
, priv
->clk
);
928 ret
= soc_camera_power_on(&client
->dev
, ssdd
, priv
->clk
);
932 ret
= ov5642_write_array(client
, ov5642_default_regs_init
);
934 ret
= ov5642_set_resolution(sd
);
936 ret
= ov5642_write_array(client
, ov5642_default_regs_finalise
);
941 static struct v4l2_subdev_video_ops ov5642_subdev_video_ops
= {
942 .s_mbus_fmt
= ov5642_s_fmt
,
943 .g_mbus_fmt
= ov5642_g_fmt
,
944 .try_mbus_fmt
= ov5642_try_fmt
,
945 .enum_mbus_fmt
= ov5642_enum_fmt
,
946 .s_crop
= ov5642_s_crop
,
947 .g_crop
= ov5642_g_crop
,
948 .cropcap
= ov5642_cropcap
,
949 .g_mbus_config
= ov5642_g_mbus_config
,
952 static struct v4l2_subdev_core_ops ov5642_subdev_core_ops
= {
953 .s_power
= ov5642_s_power
,
954 #ifdef CONFIG_VIDEO_ADV_DEBUG
955 .g_register
= ov5642_get_register
,
956 .s_register
= ov5642_set_register
,
960 static struct v4l2_subdev_ops ov5642_subdev_ops
= {
961 .core
= &ov5642_subdev_core_ops
,
962 .video
= &ov5642_subdev_video_ops
,
965 static int ov5642_video_probe(struct i2c_client
*client
)
967 struct v4l2_subdev
*subdev
= i2c_get_clientdata(client
);
972 ret
= ov5642_s_power(subdev
, 1);
976 /* Read sensor Model ID */
977 ret
= reg_read(client
, REG_CHIP_ID_HIGH
, &id_high
);
983 ret
= reg_read(client
, REG_CHIP_ID_LOW
, &id_low
);
989 dev_info(&client
->dev
, "Chip ID 0x%04x detected\n", id
);
999 ov5642_s_power(subdev
, 0);
1003 static int ov5642_probe(struct i2c_client
*client
,
1004 const struct i2c_device_id
*did
)
1006 struct ov5642
*priv
;
1007 struct soc_camera_subdev_desc
*ssdd
= soc_camera_i2c_to_desc(client
);
1011 dev_err(&client
->dev
, "OV5642: missing platform data!\n");
1015 priv
= devm_kzalloc(&client
->dev
, sizeof(struct ov5642
), GFP_KERNEL
);
1019 v4l2_i2c_subdev_init(&priv
->subdev
, client
, &ov5642_subdev_ops
);
1021 priv
->fmt
= &ov5642_colour_fmts
[0];
1023 priv
->crop_rect
.width
= OV5642_DEFAULT_WIDTH
;
1024 priv
->crop_rect
.height
= OV5642_DEFAULT_HEIGHT
;
1025 priv
->crop_rect
.left
= (OV5642_MAX_WIDTH
- OV5642_DEFAULT_WIDTH
) / 2;
1026 priv
->crop_rect
.top
= (OV5642_MAX_HEIGHT
- OV5642_DEFAULT_HEIGHT
) / 2;
1027 priv
->total_width
= OV5642_DEFAULT_WIDTH
+ BLANKING_EXTRA_WIDTH
;
1028 priv
->total_height
= BLANKING_MIN_HEIGHT
;
1030 priv
->clk
= v4l2_clk_get(&client
->dev
, "mclk");
1031 if (IS_ERR(priv
->clk
))
1032 return PTR_ERR(priv
->clk
);
1034 ret
= ov5642_video_probe(client
);
1036 v4l2_clk_put(priv
->clk
);
1041 static int ov5642_remove(struct i2c_client
*client
)
1043 struct soc_camera_subdev_desc
*ssdd
= soc_camera_i2c_to_desc(client
);
1044 struct ov5642
*priv
= to_ov5642(client
);
1046 v4l2_clk_put(priv
->clk
);
1048 ssdd
->free_bus(ssdd
);
1053 static const struct i2c_device_id ov5642_id
[] = {
1057 MODULE_DEVICE_TABLE(i2c
, ov5642_id
);
1059 static struct i2c_driver ov5642_i2c_driver
= {
1063 .probe
= ov5642_probe
,
1064 .remove
= ov5642_remove
,
1065 .id_table
= ov5642_id
,
1068 module_i2c_driver(ov5642_i2c_driver
);
1070 MODULE_DESCRIPTION("Omnivision OV5642 Camera driver");
1071 MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
1072 MODULE_LICENSE("GPL v2");