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/delay.h>
18 #include <linux/i2c.h>
19 #include <linux/slab.h>
20 #include <linux/videodev2.h>
21 #include <linux/module.h>
23 #include <media/soc_camera.h>
24 #include <media/soc_mediabus.h>
25 #include <media/v4l2-chip-ident.h>
26 #include <media/v4l2-subdev.h>
28 /* OV5642 registers */
29 #define REG_CHIP_ID_HIGH 0x300a
30 #define REG_CHIP_ID_LOW 0x300b
32 #define REG_WINDOW_START_X_HIGH 0x3800
33 #define REG_WINDOW_START_X_LOW 0x3801
34 #define REG_WINDOW_START_Y_HIGH 0x3802
35 #define REG_WINDOW_START_Y_LOW 0x3803
36 #define REG_WINDOW_WIDTH_HIGH 0x3804
37 #define REG_WINDOW_WIDTH_LOW 0x3805
38 #define REG_WINDOW_HEIGHT_HIGH 0x3806
39 #define REG_WINDOW_HEIGHT_LOW 0x3807
40 #define REG_OUT_WIDTH_HIGH 0x3808
41 #define REG_OUT_WIDTH_LOW 0x3809
42 #define REG_OUT_HEIGHT_HIGH 0x380a
43 #define REG_OUT_HEIGHT_LOW 0x380b
44 #define REG_OUT_TOTAL_WIDTH_HIGH 0x380c
45 #define REG_OUT_TOTAL_WIDTH_LOW 0x380d
46 #define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e
47 #define REG_OUT_TOTAL_HEIGHT_LOW 0x380f
50 * define standard resolution.
51 * Works currently only for up to 720 lines
52 * eg. 320x240, 640x480, 800x600, 1280x720, 2048x720
55 #define OV5642_WIDTH 1280
56 #define OV5642_HEIGHT 720
57 #define OV5642_TOTAL_WIDTH 3200
58 #define OV5642_TOTAL_HEIGHT 2000
59 #define OV5642_SENSOR_SIZE_X 2592
60 #define OV5642_SENSOR_SIZE_Y 1944
67 static struct regval_list ov5642_default_regs_init[] = {
528 static struct regval_list ov5642_default_regs_finalise[] = {
561 { 0x4300, 0x32 }, /* UYVY */
577 struct ov5642_datafmt {
578 enum v4l2_mbus_pixelcode code;
579 enum v4l2_colorspace colorspace;
583 struct v4l2_subdev subdev;
584 const struct ov5642_datafmt *fmt;
587 static const struct ov5642_datafmt ov5642_colour_fmts[] = {
588 {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
591 static struct ov5642 *to_ov5642(const struct i2c_client *client)
593 return container_of(i2c_get_clientdata(client), struct ov5642, subdev);
596 /* Find a data format by a pixel code in an array */
597 static const struct ov5642_datafmt
598 *ov5642_find_datafmt(enum v4l2_mbus_pixelcode code)
602 for (i = 0; i < ARRAY_SIZE(ov5642_colour_fmts); i++)
603 if (ov5642_colour_fmts[i].code == code)
604 return ov5642_colour_fmts + i;
609 static int reg_read(struct i2c_client *client, u16 reg, u8 *val)
612 /* We have 16-bit i2c addresses - care for endianess */
613 unsigned char data[2] = { reg >> 8, reg & 0xff };
615 ret = i2c_master_send(client, data, 2);
617 dev_err(&client->dev, "%s: i2c read error, reg: %x\n",
619 return ret < 0 ? ret : -EIO;
622 ret = i2c_master_recv(client, val, 1);
624 dev_err(&client->dev, "%s: i2c read error, reg: %x\n",
626 return ret < 0 ? ret : -EIO;
631 static int reg_write(struct i2c_client *client, u16 reg, u8 val)
634 unsigned char data[3] = { reg >> 8, reg & 0xff, val };
636 ret = i2c_master_send(client, data, 3);
638 dev_err(&client->dev, "%s: i2c write error, reg: %x\n",
640 return ret < 0 ? ret : -EIO;
645 #ifdef CONFIG_VIDEO_ADV_DEBUG
646 static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
648 struct i2c_client *client = v4l2_get_subdevdata(sd);
652 if (reg->reg & ~0xffff)
657 ret = reg_read(client, reg->reg, &val);
659 reg->val = (__u64)val;
664 static int ov5642_set_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
666 struct i2c_client *client = v4l2_get_subdevdata(sd);
668 if (reg->reg & ~0xffff || reg->val & ~0xff)
671 return reg_write(client, reg->reg, reg->val);
675 static int ov5642_write_array(struct i2c_client *client,
676 struct regval_list *vals)
678 while (vals->reg_num != 0xffff || vals->value != 0xff) {
679 int ret = reg_write(client, vals->reg_num, vals->value);
684 dev_dbg(&client->dev, "Register list loaded\n");
688 static int ov5642_set_resolution(struct i2c_client *client)
691 u8 start_x_high = ((OV5642_SENSOR_SIZE_X - OV5642_WIDTH) / 2) >> 8;
692 u8 start_x_low = ((OV5642_SENSOR_SIZE_X - OV5642_WIDTH) / 2) & 0xff;
693 u8 start_y_high = ((OV5642_SENSOR_SIZE_Y - OV5642_HEIGHT) / 2) >> 8;
694 u8 start_y_low = ((OV5642_SENSOR_SIZE_Y - OV5642_HEIGHT) / 2) & 0xff;
696 u8 width_high = OV5642_WIDTH >> 8;
697 u8 width_low = OV5642_WIDTH & 0xff;
698 u8 height_high = OV5642_HEIGHT >> 8;
699 u8 height_low = OV5642_HEIGHT & 0xff;
701 u8 total_width_high = OV5642_TOTAL_WIDTH >> 8;
702 u8 total_width_low = OV5642_TOTAL_WIDTH & 0xff;
703 u8 total_height_high = OV5642_TOTAL_HEIGHT >> 8;
704 u8 total_height_low = OV5642_TOTAL_HEIGHT & 0xff;
706 ret = reg_write(client, REG_WINDOW_START_X_HIGH, start_x_high);
708 ret = reg_write(client, REG_WINDOW_START_X_LOW, start_x_low);
710 ret = reg_write(client, REG_WINDOW_START_Y_HIGH, start_y_high);
712 ret = reg_write(client, REG_WINDOW_START_Y_LOW, start_y_low);
715 ret = reg_write(client, REG_WINDOW_WIDTH_HIGH, width_high);
717 ret = reg_write(client, REG_WINDOW_WIDTH_LOW , width_low);
719 ret = reg_write(client, REG_WINDOW_HEIGHT_HIGH, height_high);
721 ret = reg_write(client, REG_WINDOW_HEIGHT_LOW, height_low);
724 ret = reg_write(client, REG_OUT_WIDTH_HIGH, width_high);
726 ret = reg_write(client, REG_OUT_WIDTH_LOW , width_low);
728 ret = reg_write(client, REG_OUT_HEIGHT_HIGH, height_high);
730 ret = reg_write(client, REG_OUT_HEIGHT_LOW, height_low);
733 ret = reg_write(client, REG_OUT_TOTAL_WIDTH_HIGH, total_width_high);
735 ret = reg_write(client, REG_OUT_TOTAL_WIDTH_LOW, total_width_low);
737 ret = reg_write(client, REG_OUT_TOTAL_HEIGHT_HIGH, total_height_high);
739 ret = reg_write(client, REG_OUT_TOTAL_HEIGHT_LOW, total_height_low);
744 static int ov5642_try_fmt(struct v4l2_subdev *sd,
745 struct v4l2_mbus_framefmt *mf)
747 const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code);
749 dev_dbg(sd->v4l2_dev->dev, "%s(%u) width: %u heigth: %u\n",
750 __func__, mf->code, mf->width, mf->height);
753 mf->code = ov5642_colour_fmts[0].code;
754 mf->colorspace = ov5642_colour_fmts[0].colorspace;
757 mf->width = OV5642_WIDTH;
758 mf->height = OV5642_HEIGHT;
759 mf->field = V4L2_FIELD_NONE;
764 static int ov5642_s_fmt(struct v4l2_subdev *sd,
765 struct v4l2_mbus_framefmt *mf)
767 struct i2c_client *client = v4l2_get_subdevdata(sd);
768 struct ov5642 *priv = to_ov5642(client);
770 dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code);
772 /* MIPI CSI could have changed the format, double-check */
773 if (!ov5642_find_datafmt(mf->code))
776 ov5642_try_fmt(sd, mf);
778 priv->fmt = ov5642_find_datafmt(mf->code);
780 ov5642_write_array(client, ov5642_default_regs_init);
781 ov5642_set_resolution(client);
782 ov5642_write_array(client, ov5642_default_regs_finalise);
787 static int ov5642_g_fmt(struct v4l2_subdev *sd,
788 struct v4l2_mbus_framefmt *mf)
790 struct i2c_client *client = v4l2_get_subdevdata(sd);
791 struct ov5642 *priv = to_ov5642(client);
793 const struct ov5642_datafmt *fmt = priv->fmt;
795 mf->code = fmt->code;
796 mf->colorspace = fmt->colorspace;
797 mf->width = OV5642_WIDTH;
798 mf->height = OV5642_HEIGHT;
799 mf->field = V4L2_FIELD_NONE;
804 static int ov5642_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
805 enum v4l2_mbus_pixelcode *code)
807 if (index >= ARRAY_SIZE(ov5642_colour_fmts))
810 *code = ov5642_colour_fmts[index].code;
814 static int ov5642_g_chip_ident(struct v4l2_subdev *sd,
815 struct v4l2_dbg_chip_ident *id)
817 struct i2c_client *client = v4l2_get_subdevdata(sd);
819 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
822 if (id->match.addr != client->addr)
825 id->ident = V4L2_IDENT_OV5642;
831 static int ov5642_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
833 struct v4l2_rect *rect = &a->c;
835 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
838 rect->width = OV5642_WIDTH;
839 rect->height = OV5642_HEIGHT;
844 static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
848 a->bounds.width = OV5642_WIDTH;
849 a->bounds.height = OV5642_HEIGHT;
850 a->defrect = a->bounds;
851 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
852 a->pixelaspect.numerator = 1;
853 a->pixelaspect.denominator = 1;
858 static int ov5642_g_mbus_config(struct v4l2_subdev *sd,
859 struct v4l2_mbus_config *cfg)
861 cfg->type = V4L2_MBUS_CSI2;
862 cfg->flags = V4L2_MBUS_CSI2_2_LANE |
863 V4L2_MBUS_CSI2_CHANNEL_0 |
864 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
869 static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = {
870 .s_mbus_fmt = ov5642_s_fmt,
871 .g_mbus_fmt = ov5642_g_fmt,
872 .try_mbus_fmt = ov5642_try_fmt,
873 .enum_mbus_fmt = ov5642_enum_fmt,
874 .g_crop = ov5642_g_crop,
875 .cropcap = ov5642_cropcap,
876 .g_mbus_config = ov5642_g_mbus_config,
879 static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
880 .g_chip_ident = ov5642_g_chip_ident,
881 #ifdef CONFIG_VIDEO_ADV_DEBUG
882 .g_register = ov5642_get_register,
883 .s_register = ov5642_set_register,
887 static struct v4l2_subdev_ops ov5642_subdev_ops = {
888 .core = &ov5642_subdev_core_ops,
889 .video = &ov5642_subdev_video_ops,
892 static int ov5642_video_probe(struct soc_camera_device *icd,
893 struct i2c_client *client)
899 /* Read sensor Model ID */
900 ret = reg_read(client, REG_CHIP_ID_HIGH, &id_high);
906 ret = reg_read(client, REG_CHIP_ID_LOW, &id_low);
912 dev_info(&client->dev, "Chip ID 0x%04x detected\n", id);
920 static int ov5642_probe(struct i2c_client *client,
921 const struct i2c_device_id *did)
924 struct soc_camera_device *icd = client->dev.platform_data;
925 struct soc_camera_link *icl;
929 dev_err(&client->dev, "OV5642: missing soc-camera data!\n");
933 icl = to_soc_camera_link(icd);
935 dev_err(&client->dev, "OV5642: missing platform data!\n");
939 priv = kzalloc(sizeof(struct ov5642), GFP_KERNEL);
943 v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops);
945 priv->fmt = &ov5642_colour_fmts[0];
947 ret = ov5642_video_probe(icd, client);
958 static int ov5642_remove(struct i2c_client *client)
960 struct ov5642 *priv = to_ov5642(client);
961 struct soc_camera_device *icd = client->dev.platform_data;
962 struct soc_camera_link *icl = to_soc_camera_link(icd);
971 static const struct i2c_device_id ov5642_id[] = {
975 MODULE_DEVICE_TABLE(i2c, ov5642_id);
977 static struct i2c_driver ov5642_i2c_driver = {
981 .probe = ov5642_probe,
982 .remove = ov5642_remove,
983 .id_table = ov5642_id,
986 static int __init ov5642_mod_init(void)
988 return i2c_add_driver(&ov5642_i2c_driver);
991 static void __exit ov5642_mod_exit(void)
993 i2c_del_driver(&ov5642_i2c_driver);
996 module_init(ov5642_mod_init);
997 module_exit(ov5642_mod_exit);
999 MODULE_DESCRIPTION("Omnivision OV5642 Camera driver");
1000 MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
1001 MODULE_LICENSE("GPL v2");