From 1c7d6584a7811b7785ae5c1e378f14b5ba0971cf Mon Sep 17 00:00:00 2001 From: takeshi_hoshina Date: Mon, 2 Nov 2020 11:07:33 +0900 Subject: basesystem-jj recipes --- ...c-imagers-add-AR0231-for-new-LVDS-support.patch | 1843 ++++++++++++++++++++ 1 file changed, 1843 insertions(+) create mode 100644 bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0506-media-i2c-imagers-add-AR0231-for-new-LVDS-support.patch (limited to 'bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0506-media-i2c-imagers-add-AR0231-for-new-LVDS-support.patch') diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0506-media-i2c-imagers-add-AR0231-for-new-LVDS-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0506-media-i2c-imagers-add-AR0231-for-new-LVDS-support.patch new file mode 100644 index 00000000..c75293ae --- /dev/null +++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0506-media-i2c-imagers-add-AR0231-for-new-LVDS-support.patch @@ -0,0 +1,1843 @@ +From f113d62d104a24b6035d969bad8cb04af54d7534 Mon Sep 17 00:00:00 2001 +From: Vladimir Barinov +Date: Thu, 30 Apr 2020 10:54:49 +0300 +Subject: [PATCH] media: i2c: imagers: add AR0231 for new LVDS support + +This adds AR0231 into new LVDS drivers that support all enabled +serializers + +Signed-off-by: Vladimir Barinov +--- + drivers/media/i2c/soc_camera/imagers/Makefile | 1 + + drivers/media/i2c/soc_camera/imagers/ar0231.c | 604 +++++++++++++++++++++ + drivers/media/i2c/soc_camera/imagers/ar0231.h | 35 ++ + drivers/media/i2c/soc_camera/imagers/ar0231_rev4.h | 344 ++++++++++++ + drivers/media/i2c/soc_camera/imagers/ar0231_rev6.h | 343 ++++++++++++ + drivers/media/i2c/soc_camera/imagers/ar0231_rev7.h | 445 +++++++++++++++ + 5 files changed, 1771 insertions(+) + create mode 100644 drivers/media/i2c/soc_camera/imagers/ar0231.c + create mode 100644 drivers/media/i2c/soc_camera/imagers/ar0231.h + create mode 100644 drivers/media/i2c/soc_camera/imagers/ar0231_rev4.h + create mode 100644 drivers/media/i2c/soc_camera/imagers/ar0231_rev6.h + create mode 100644 drivers/media/i2c/soc_camera/imagers/ar0231_rev7.h + +diff --git a/drivers/media/i2c/soc_camera/imagers/Makefile b/drivers/media/i2c/soc_camera/imagers/Makefile +index 0d0ff32..eeb36fd 100644 +--- a/drivers/media/i2c/soc_camera/imagers/Makefile ++++ b/drivers/media/i2c/soc_camera/imagers/Makefile +@@ -1,7 +1,8 @@ + # SPDX-License-Identifier: GPL-2.0 ++obj-$(CONFIG_SOC_CAMERA_OV106XX) += ap0101_ar014x.o ++obj-$(CONFIG_SOC_CAMERA_OV106XX) += ap0201_ar023x.o ++obj-$(CONFIG_SOC_CAMERA_OV106XX) += ar0231.o + obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov10635.o + obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov2311.o + obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov490.o +-obj-$(CONFIG_SOC_CAMERA_OV106XX) += ap0101_ar014x.o +-obj-$(CONFIG_SOC_CAMERA_OV106XX) += ap0201_ar023x.o + obj-$(CONFIG_SOC_CAMERA_OV106XX) += dummy.o +diff --git a/drivers/media/i2c/soc_camera/imagers/ar0231.c b/drivers/media/i2c/soc_camera/imagers/ar0231.c +new file mode 100644 +index 0000000..fc08793 +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/imagers/ar0231.c +@@ -0,0 +1,604 @@ ++/* ++ * ON Semiconductor AR0231 sensor camera driver ++ * ++ * Copyright (C) 2018-220 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "../gmsl/common.h" ++#include "ar0231.h" ++ ++static const int ar0231_i2c_addr[] = {0x10, 0x20}; ++ ++#define AR0231_PID_REG 0x3000 ++#define AR0231_REV_REG 0x31FE ++#define AR0231_PID 0x0354 ++ ++#define AR0231_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12 ++ ++struct ar0231_priv { ++ struct v4l2_subdev sd; ++ struct v4l2_ctrl_handler hdl; ++ struct media_pad pad; ++ struct v4l2_rect rect; ++ int init_complete; ++ u8 id[6]; ++ /* serializers */ ++ int ser_addr; ++ int trigger; ++}; ++ ++static int trigger = 0; ++module_param(trigger, int, 0644); ++MODULE_PARM_DESC(trigger, " Trigger gpio number (default: 0 - GPIO0) "); ++ ++static inline struct ar0231_priv *to_ar0231(const struct i2c_client *client) ++{ ++ return container_of(i2c_get_clientdata(client), struct ar0231_priv, sd); ++} ++ ++static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) ++{ ++ return &container_of(ctrl->handler, struct ar0231_priv, hdl)->sd; ++} ++ ++static int ar0231_set_regs(struct i2c_client *client, ++ const struct ar0231_reg *regs, int nr_regs) ++{ ++ int i; ++ ++ for (i = 0; i < nr_regs; i++) { ++ if (regs[i].reg == AR0231_DELAY) { ++ mdelay(regs[i].val); ++ continue; ++ } ++ ++ reg16_write16(client, regs[i].reg, regs[i].val); ++ } ++ ++ return 0; ++} ++ ++static void ar0231_otp_id_read(struct i2c_client *client) ++{ ++ struct ar0231_priv *priv = to_ar0231(client); ++ int i; ++ u16 val = 0; ++ ++ /* read camera id from ar014x OTP memory */ ++ reg16_write16(client, 0x3054, 0x400); ++ reg16_write16(client, 0x304a, 0x110); ++ usleep_range(25000, 25500); /* wait 25 ms */ ++ ++ for (i = 0; i < 6; i += 2) { ++ /* first 4 bytes are equal on all ar014x */ ++ reg16_read16(client, 0x3800 + i + 4, &val); ++ priv->id[i] = val >> 8; ++ priv->id[i + 1] = val & 0xff; ++ } ++} ++ ++ ++static int ar0231_s_stream(struct v4l2_subdev *sd, int enable) ++{ ++ return 0; ++} ++ ++static int ar0231_set_window(struct v4l2_subdev *sd) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0231_priv *priv = to_ar0231(client); ++ ++ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height); ++ ++ /* horiz crop start */ ++ reg16_write16(client, 0x3004, priv->rect.left + AR0231_X_START); ++ /* horiz crop end */ ++ reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1 + AR0231_X_START); ++ /* vert crop start */ ++ reg16_write16(client, 0x3002, priv->rect.top + AR0231_Y_START); ++ /* vert crop end */ ++ reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height - 1 + AR0231_Y_START); ++ ++ return 0; ++}; ++ ++static int ar0231_get_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *format) ++{ ++ struct v4l2_mbus_framefmt *mf = &format->format; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0231_priv *priv = to_ar0231(client); ++ ++ if (format->pad) ++ return -EINVAL; ++ ++ mf->width = priv->rect.width; ++ mf->height = priv->rect.height; ++ mf->code = AR0231_MEDIA_BUS_FMT; ++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ++ mf->field = V4L2_FIELD_NONE; ++ ++ return 0; ++} ++ ++static int ar0231_set_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *format) ++{ ++ struct v4l2_mbus_framefmt *mf = &format->format; ++ ++ mf->code = AR0231_MEDIA_BUS_FMT; ++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ++ mf->field = V4L2_FIELD_NONE; ++ ++ if (format->which == V4L2_SUBDEV_FORMAT_TRY) ++ cfg->try_fmt = *mf; ++ ++ return 0; ++} ++ ++static int ar0231_enum_mbus_code(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_mbus_code_enum *code) ++{ ++ if (code->pad || code->index > 0) ++ return -EINVAL; ++ ++ code->code = AR0231_MEDIA_BUS_FMT; ++ ++ return 0; ++} ++ ++static int ar0231_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0231_priv *priv = to_ar0231(client); ++ ++ memcpy(edid->edid, priv->id, 6); ++ ++ edid->edid[6] = 0xff; ++ edid->edid[7] = client->addr; ++ edid->edid[8] = AR0231_PID >> 8; ++ edid->edid[9] = AR0231_PID & 0xff; ++ ++ return 0; ++} ++ ++static int ar0231_set_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) ++{ ++ struct v4l2_rect *rect = &sel->r; ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0231_priv *priv = to_ar0231(client); ++ ++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || ++ sel->target != V4L2_SEL_TGT_CROP) ++ return -EINVAL; ++ ++ rect->left = ALIGN(rect->left, 2); ++ rect->top = ALIGN(rect->top, 2); ++ rect->width = ALIGN(rect->width, 2); ++ rect->height = ALIGN(rect->height, 2); ++ ++ if ((rect->left + rect->width > AR0231_MAX_WIDTH) || ++ (rect->top + rect->height > AR0231_MAX_HEIGHT)) ++ *rect = priv->rect; ++ ++ priv->rect.left = rect->left; ++ priv->rect.top = rect->top; ++ priv->rect.width = rect->width; ++ priv->rect.height = rect->height; ++ ++ ar0231_set_window(sd); ++ ++ return 0; ++} ++ ++static int ar0231_get_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0231_priv *priv = to_ar0231(client); ++ ++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) ++ return -EINVAL; ++ ++ switch (sel->target) { ++ case V4L2_SEL_TGT_CROP_BOUNDS: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = AR0231_MAX_WIDTH; ++ sel->r.height = AR0231_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = AR0231_MAX_WIDTH; ++ sel->r.height = AR0231_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP: ++ sel->r = priv->rect; ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int ar0231_g_mbus_config(struct v4l2_subdev *sd, ++ struct v4l2_mbus_config *cfg) ++{ ++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 | ++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; ++ cfg->type = V4L2_MBUS_CSI2; ++ ++ return 0; ++} ++ ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++static int ar0231_g_register(struct v4l2_subdev *sd, ++ struct v4l2_dbg_register *reg) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ int ret; ++ __be64 be_val; ++ ++ if (!reg->size) ++ reg->size = sizeof(u16); ++ if (reg->size > sizeof(reg->val)) ++ reg->size = sizeof(reg->val); ++ ++ ret = reg16_read_n(client, (u16)reg->reg, (u8*)&be_val, reg->size); ++ be_val = be_val << ((sizeof(be_val) - reg->size) * 8); ++ reg->val = be64_to_cpu(be_val); ++ ++ return ret; ++} ++ ++static int ar0231_s_register(struct v4l2_subdev *sd, ++ const struct v4l2_dbg_register *reg) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ u32 size = reg->size; ++ int ret; ++ __be64 be_val; ++ ++ if (!size) ++ size = sizeof(u16); ++ if (size > sizeof(reg->val)) ++ size = sizeof(reg->val); ++ ++ be_val = cpu_to_be64(reg->val); ++ be_val = be_val >> ((sizeof(be_val) - size) * 8); ++ ret = reg16_write_n(client, (u16)reg->reg, (u8*)&be_val, size); ++ ++ return ret; ++} ++#endif ++ ++static struct v4l2_subdev_core_ops ar0231_core_ops = { ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++ .g_register = ar0231_g_register, ++ .s_register = ar0231_s_register, ++#endif ++}; ++ ++static int ar0231_s_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ struct v4l2_subdev *sd = to_sd(ctrl); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0231_priv *priv = to_ar0231(client); ++ int ret = -EINVAL; ++ u16 val = 0; ++ ++ if (!priv->init_complete) ++ return 0; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_BRIGHTNESS: ++ case V4L2_CID_CONTRAST: ++ case V4L2_CID_SATURATION: ++ case V4L2_CID_HUE: ++ case V4L2_CID_GAMMA: ++ case V4L2_CID_SHARPNESS: ++ case V4L2_CID_AUTOGAIN: ++ break; ++ case V4L2_CID_GAIN: ++ /* Digital gain */ ++ ret = reg16_write16(client, 0x3308, ctrl->val); ++ break; ++ case V4L2_CID_ANALOGUE_GAIN: ++ /* Analog gain */ ++ ret = reg16_write16(client, 0x3366, (ctrl->val << 8) | (ctrl->val << 4) | ctrl->val); ++ break; ++ case V4L2_CID_EXPOSURE: ++ /* T1 exposure */ ++ ret = reg16_write16(client, 0x3012, ctrl->val); ++ break; ++ case V4L2_CID_HFLIP: ++ ret = reg16_read16(client, 0x3040, &val); ++ if (ctrl->val) ++ val |= (1 << 14); ++ else ++ val &= ~(1 << 14); ++ ret |= reg16_write16(client, 0x3040, val); ++ break; ++ case V4L2_CID_VFLIP: ++ ret = reg16_read16(client, 0x3040, &val); ++ if (ctrl->val) ++ val |= (1 << 15); ++ else ++ val &= ~(1 << 15); ++ ret |= reg16_write16(client, 0x3040, val); ++ break; ++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: ++ ret = 0; ++ break; ++ } ++ ++ return ret; ++} ++ ++static const struct v4l2_ctrl_ops ar0231_ctrl_ops = { ++ .s_ctrl = ar0231_s_ctrl, ++}; ++ ++static struct v4l2_subdev_video_ops ar0231_video_ops = { ++ .s_stream = ar0231_s_stream, ++ .g_mbus_config = ar0231_g_mbus_config, ++}; ++ ++static const struct v4l2_subdev_pad_ops ar0231_subdev_pad_ops = { ++ .get_edid = ar0231_get_edid, ++ .enum_mbus_code = ar0231_enum_mbus_code, ++ .get_selection = ar0231_get_selection, ++ .set_selection = ar0231_set_selection, ++ .get_fmt = ar0231_get_fmt, ++ .set_fmt = ar0231_set_fmt, ++}; ++ ++static struct v4l2_subdev_ops ar0231_subdev_ops = { ++ .core = &ar0231_core_ops, ++ .video = &ar0231_video_ops, ++ .pad = &ar0231_subdev_pad_ops, ++}; ++ ++static ssize_t ar0231_otp_id_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev)); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0231_priv *priv = to_ar0231(client); ++ ++ ar0231_otp_id_read(client); ++ ++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n", ++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); ++} ++ ++static DEVICE_ATTR(otp_id_ar0231, S_IRUGO, ar0231_otp_id_show, NULL); ++ ++static int ar0231_initialize(struct i2c_client *client) ++{ ++ struct ar0231_priv *priv = to_ar0231(client); ++ u16 val = 0, pid = 0, rev = 0; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(ar0231_i2c_addr); i++) { ++ setup_i2c_translator(client, priv->ser_addr, ar0231_i2c_addr[i] << 1); ++ ++ /* check model ID */ ++ reg16_read16(client, AR0231_PID_REG, &pid); ++ if (pid == AR0231_PID) ++ break; ++ } ++ ++ if (pid != AR0231_PID) { ++ dev_dbg(&client->dev, "Product ID error %x\n", pid); ++ return -ENODEV; ++ } ++ ++ /* check revision */ ++ reg16_read16(client, AR0231_REV_REG, &rev); ++ /* Read OTP IDs */ ++ ar0231_otp_id_read(client); ++ /* Program wizard registers */ ++ switch (get_des_id(client)) { ++ case UB960_ID: ++ ar0231_set_regs(client, ar0231_regs_wizard_rev7, ARRAY_SIZE(ar0231_regs_wizard_rev7)); ++ break; ++ case MAX9286_ID: ++ case MAX9296A_ID: ++ case MAX96712_ID: ++ ar0231_set_regs(client, ar0231_regs_wizard_rev6_dvp, ARRAY_SIZE(ar0231_regs_wizard_rev6_dvp)); ++ break; ++ } ++ /* Enable trigger */ ++ if (priv->trigger >= 0 && priv->trigger < 4) { ++ reg16_write16(client, 0x340A, (~(BIT(priv->trigger) << 4)) & 0xf0);/* GPIO_CONTROL1: GPIOn input enable */ ++ reg16_write16(client, 0x340C, (0x2 << 2*priv->trigger)); /* GPIO_CONTROL2: GPIOn is trigger */ ++ reg16_write16(client, 0x30CE, 0x0120); /* TRIGGER_MODE */ ++ //reg16_write16(client, 0x30DC, 0x0120); /* TRIGGER_DELAY */ ++ } ++ /* Enable stream */ ++ reg16_read16(client, 0x301a, &val); ++ val |= (1 << 8); /* GPI pins enable */ ++ val |= (1 << 2); ++ reg16_write16(client, 0x301a, val); ++ ++ dev_info(&client->dev, "ar0231 PID %x (rev%x), res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n", ++ pid, rev & 0xf, AR0231_MAX_WIDTH, AR0231_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); ++ return 0; ++} ++ ++static const struct i2c_device_id ar0231_id[] = { ++ { "ar0231", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, ar0231_id); ++ ++static const struct of_device_id ar0231_of_ids[] = { ++ { .compatible = "onnn,ar0231", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, ar0231_of_ids); ++ ++static int ar0231_parse_dt(struct device_node *np, struct ar0231_priv *priv) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd); ++ u32 addrs[2], naddrs; ++ ++ naddrs = of_property_count_elems_of_size(np, "reg", sizeof(u32)); ++ if (naddrs != 2) { ++ dev_err(&client->dev, "Invalid DT reg property\n"); ++ return -EINVAL; ++ } ++ ++ if (of_property_read_u32_array(client->dev.of_node, "reg", addrs, naddrs) < 0) { ++ dev_err(&client->dev, "Invalid DT reg property\n"); ++ return -EINVAL; ++ } ++ ++ priv->ser_addr = addrs[1]; ++ ++ if (of_property_read_u32(np, "trigger", &priv->trigger)) ++ priv->trigger = 0; ++ ++ /* module params override dts */ ++ if (trigger) ++ priv->trigger = trigger; ++ ++ return 0; ++} ++ ++static int ar0231_probe(struct i2c_client *client, ++ const struct i2c_device_id *did) ++{ ++ struct ar0231_priv *priv; ++ int ret; ++ ++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0231_subdev_ops); ++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; ++ ++ v4l2_ctrl_handler_init(&priv->hdl, 4); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_CONTRAST, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_SATURATION, 0, 7, 1, 2); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_HUE, 0, 23, 1, 12); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_GAMMA, -128, 128, 1, 0); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_SHARPNESS, 0, 10, 1, 3); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_AUTOGAIN, 0, 1, 1, 0); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_GAIN, 1, 0x7ff, 1, 0x200); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_ANALOGUE_GAIN, 1, 0xe, 1, 0xa); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_EXPOSURE, 1, 0x600, 1, 0x144); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_HFLIP, 0, 1, 1, 0); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops, ++ V4L2_CID_VFLIP, 0, 1, 1, 0); ++ priv->sd.ctrl_handler = &priv->hdl; ++ ++ ret = priv->hdl.error; ++ if (ret) ++ goto cleanup; ++ ++ v4l2_ctrl_handler_setup(&priv->hdl); ++ ++ priv->pad.flags = MEDIA_PAD_FL_SOURCE; ++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR; ++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad); ++ if (ret < 0) ++ goto cleanup; ++ ++ ret = ar0231_parse_dt(client->dev.of_node, priv); ++ if (ret) ++ goto cleanup; ++ ++ ret = ar0231_initialize(client); ++ if (ret < 0) ++ goto cleanup; ++ ++ priv->rect.left = 0; ++ priv->rect.top = 0; ++ priv->rect.width = AR0231_MAX_WIDTH; ++ priv->rect.height = AR0231_MAX_HEIGHT; ++ ++ ret = v4l2_async_register_subdev(&priv->sd); ++ if (ret) ++ goto cleanup; ++ ++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0231) != 0) { ++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n"); ++ goto cleanup; ++ } ++ ++ priv->init_complete = 1; ++ ++ return 0; ++ ++cleanup: ++ media_entity_cleanup(&priv->sd.entity); ++ v4l2_ctrl_handler_free(&priv->hdl); ++ v4l2_device_unregister_subdev(&priv->sd); ++ return ret; ++} ++ ++static int ar0231_remove(struct i2c_client *client) ++{ ++ struct ar0231_priv *priv = i2c_get_clientdata(client); ++ ++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0231); ++ v4l2_async_unregister_subdev(&priv->sd); ++ media_entity_cleanup(&priv->sd.entity); ++ v4l2_ctrl_handler_free(&priv->hdl); ++ v4l2_device_unregister_subdev(&priv->sd); ++ ++ return 0; ++} ++ ++static struct i2c_driver ar0231_i2c_driver = { ++ .driver = { ++ .name = "ar0231", ++ .of_match_table = ar0231_of_ids, ++ }, ++ .probe = ar0231_probe, ++ .remove = ar0231_remove, ++ .id_table = ar0231_id, ++}; ++ ++module_i2c_driver(ar0231_i2c_driver); ++ ++MODULE_DESCRIPTION("SoC Camera driver for AR0231"); ++MODULE_AUTHOR("Vladimir Barinov"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/i2c/soc_camera/imagers/ar0231.h b/drivers/media/i2c/soc_camera/imagers/ar0231.h +new file mode 100644 +index 0000000..e455b38 +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/imagers/ar0231.h +@@ -0,0 +1,35 @@ ++/* ++ * ON Semiconductor AR0231 sensor camera wizard 1928x1208@30/BGGR/BT601 ++ * ++ * Copyright (C) 2018-2020 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++//#define AR0231_DISPLAY_PATTERN_FIXED ++//#define AR0231_DISPLAY_PATTERN_COLOR_BAR ++ ++#define AR0231_MAX_WIDTH 1920 ++#define AR0231_MAX_HEIGHT 1200 ++ ++#define AR0231_DELAY 0xffff ++ ++#define AR0231_SENSOR_WIDTH 1928 ++#define AR0231_SENSOR_HEIGHT 1208 ++ ++#define AR0231_X_START ((AR0231_SENSOR_WIDTH - AR0231_MAX_WIDTH) / 2) ++#define AR0231_Y_START ((AR0231_SENSOR_HEIGHT - AR0231_MAX_HEIGHT) / 2) ++#define AR0231_X_END (AR0231_X_START + AR0231_MAX_WIDTH - 1) ++#define AR0231_Y_END (AR0231_Y_START + AR0231_MAX_HEIGHT - 1) ++ ++struct ar0231_reg { ++ u16 reg; ++ u16 val; ++}; ++ ++#include "ar0231_rev4.h" ++#include "ar0231_rev6.h" ++#include "ar0231_rev7.h" +diff --git a/drivers/media/i2c/soc_camera/imagers/ar0231_rev4.h b/drivers/media/i2c/soc_camera/imagers/ar0231_rev4.h +new file mode 100644 +index 0000000..e18b96d +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/imagers/ar0231_rev4.h +@@ -0,0 +1,344 @@ ++/* ++ * ON Semiconductor AR0231 sensor camera wizard 1920x1080@30/BGGR/MIPI ++ * ++ * Copyright (C) 2018-2020 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++static const struct ar0231_reg ar0231_regs_wizard_rev4_dvp[] = { ++{0x301A, 0x0001}, // reset ++{0x301A, 0x10D8}, // Stream off and setup parallel ++{0x3070, 0x0000}, // 1: Solid color test pattern, ++ // 2: Full color bar test pattern, ++ // 3: Fade to grey color bar test pattern, ++ //256: Walking 1 test pattern (12 bit) ++{0x3072, 0x0123}, // R ++{0x3074, 0x0456}, // G(GR row) ++{0x3076, 0x0abc}, // B ++{0x3078, 0x0def}, // G(GB row) ++#ifdef AR0231_DISPLAY_PATTERN_FIXED ++{0x3070, 0x0001}, ++#endif ++#ifdef AR0231_DISPLAY_PATTERN_COLOR_BAR ++{0x3070, 0x0002}, ++#endif ++ ++//Recommended Settings ++{0x3366, 0x6666}, // ANALOG_GAIN ++{0x3056, 0x0080}, // GREEN1_GAIN ++{0x305C, 0x0080}, // GREEN2_GAIN ++{0x3058, 0x0080}, // BLUE_GAIN ++{0x305A, 0x0080}, // RED_GAIN ++{0x3044, 0x0400}, // DARK_CONTROL ++{0x30BA, 0x1021}, // DIGITAL_CTRL ++{0x318E, 0x0200}, // DLO_CONTROL0 ++{0x32EA, 0x3C0A}, // RESERVED_MFR_32EA ++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA ++{0x3362, 0x0000}, // DC_GAIN ++{0x3364, 0x0060}, // RESERVED_MFR_3364 ++{0x3370, 0x0231}, // DBLC_CONTROL ++{0x3372, 0x700F}, // RESERVED_MFR_3372 ++{0x3386, 0x0000}, // RESERVED_MFR_3386 ++{0x3C04, 0x0E80}, // RESERVED_MFR_3C04 ++{0x3F90, 0x06E1}, // TEMPVSENS0_TMG_CTRL ++{0x3F92, 0x06E1}, // TEMPVSENS1_TMG_CTRL ++{0x3502, 0x0808}, // RESERVED_MFR_3502 ++{0x3502, 0x0808}, // RESERVED_MFR_3502 ++{0x350E, 0xFF10}, // RESERVED_MFR_350E ++{0x3506, 0x4444}, // RESERVED_MFR_3506 ++{0x3508, 0x4444}, // RESERVED_MFR_3508 ++{0x350A, 0x4465}, // RESERVED_MFR_350A ++{0x350C, 0x055F}, // RESERVED_MFR_350C ++{0x3230, 0x0317}, // FINE_CORRECTION ++{0x3232, 0x0552}, // FINE_CORRECTION2 ++{0x3234, 0x078D}, // FINE_CORRECTION3 ++{0x3566, 0x9D38}, // RESERVED_MFR_3566 ++{0x3518, 0x1FFE}, // RESERVED_MFR_3518 ++{0x3520, 0xC688}, // RESERVED_MFR_3520 ++{0x3522, 0x88C0}, // RESERVED_MFR_3522 ++{0x3524, 0xC0C6}, // RESERVED_MFR_3524 ++{0x352C, 0xC6C6}, // RESERVED_MFR_352C ++{0x3528, 0x0900}, // RESERVED_MFR_3528 ++{0x3528, 0x9900}, // RESERVED_MFR_3528 ++{0x3528, 0x9909}, // RESERVED_MFR_3528 ++{0x3528, 0x9999}, // RESERVED_MFR_3528 ++{0x352A, 0x081F}, // RESERVED_MFR_352A ++{0x352E, 0x0001}, // RESERVED_MFR_352E ++{0x352E, 0x0011}, // RESERVED_MFR_352E ++{0x3530, 0x0400}, // RESERVED_MFR_3530 ++{0x3530, 0x4400}, // RESERVED_MFR_3530 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF02}, // RESERVED_MFR_3536 ++{0x3536, 0xFF06}, // RESERVED_MFR_3536 ++{0x3536, 0xFF06}, // RESERVED_MFR_3536 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x353A, 0x9000}, // RESERVED_MFR_353A ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC ++{0x3540, 0xC637}, // RESERVED_MFR_3540 ++{0x3540, 0xC637}, // RESERVED_MFR_3540 ++{0x3540, 0xC637}, // RESERVED_MFR_3540 ++{0x3542, 0x584B}, // RESERVED_MFR_3542 ++{0x3542, 0x464B}, // RESERVED_MFR_3542 ++{0x3544, 0x565A}, // RESERVED_MFR_3544 ++{0x3544, 0x4B5A}, // RESERVED_MFR_3544 ++{0x3546, 0x545A}, // RESERVED_MFR_3546 ++{0x3546, 0x5A5A}, // RESERVED_MFR_3546 ++{0x3548, 0x6430}, // RESERVED_MFR_3548 ++{0x3556, 0x101F}, // RESERVED_MFR_3556 ++{0x3566, 0x9D38}, // RESERVED_MFR_3566 ++{0x3566, 0x1D38}, // RESERVED_MFR_3566 ++{0x3566, 0x1D28}, // RESERVED_MFR_3566 ++{0x3566, 0x1128}, // RESERVED_MFR_3566 ++{0x3566, 0x1328}, // RESERVED_MFR_3566 ++{0x3566, 0x3328}, // RESERVED_MFR_3566 ++ ++//Sequencer Update ++{0x2512, 0x8000}, // SEQ_CTRL_PORT ++{0x2510, 0x0905}, // SEQ_DATA_PORT ++{0x2510, 0x3350}, // SEQ_DATA_PORT ++{0x2510, 0x2004}, // SEQ_DATA_PORT ++{0x2510, 0x1460}, // SEQ_DATA_PORT ++{0x2510, 0x1578}, // SEQ_DATA_PORT ++{0x2510, 0x1360}, // SEQ_DATA_PORT ++{0x2510, 0x7B24}, // SEQ_DATA_PORT ++{0x2510, 0xFF24}, // SEQ_DATA_PORT ++{0x2510, 0xFF24}, // SEQ_DATA_PORT ++{0x2510, 0xEA24}, // SEQ_DATA_PORT ++{0x2510, 0x1022}, // SEQ_DATA_PORT ++{0x2510, 0x2410}, // SEQ_DATA_PORT ++{0x2510, 0x155A}, // SEQ_DATA_PORT ++{0x2510, 0x1342}, // SEQ_DATA_PORT ++{0x2510, 0x1400}, // SEQ_DATA_PORT ++{0x2510, 0x24FF}, // SEQ_DATA_PORT ++{0x2510, 0x24FF}, // SEQ_DATA_PORT ++{0x2510, 0x24EA}, // SEQ_DATA_PORT ++{0x2510, 0x2324}, // SEQ_DATA_PORT ++{0x2510, 0x647A}, // SEQ_DATA_PORT ++{0x2510, 0x2404}, // SEQ_DATA_PORT ++{0x2510, 0x052C}, // SEQ_DATA_PORT ++{0x2510, 0x400A}, // SEQ_DATA_PORT ++{0x2510, 0xFF0A}, // SEQ_DATA_PORT ++{0x2510, 0xFF0A}, // SEQ_DATA_PORT ++{0x2510, 0x0408}, // SEQ_DATA_PORT ++{0x2510, 0x3851}, // SEQ_DATA_PORT ++{0x2510, 0x1440}, // SEQ_DATA_PORT ++{0x2510, 0x0004}, // SEQ_DATA_PORT ++{0x2510, 0x0801}, // SEQ_DATA_PORT ++{0x2510, 0x0408}, // SEQ_DATA_PORT ++{0x2510, 0x1180}, // SEQ_DATA_PORT ++{0x2510, 0x15DC}, // SEQ_DATA_PORT ++{0x2510, 0x134C}, // SEQ_DATA_PORT ++{0x2510, 0x1002}, // SEQ_DATA_PORT ++{0x2510, 0x1016}, // SEQ_DATA_PORT ++{0x2510, 0x1181}, // SEQ_DATA_PORT ++{0x2510, 0x1189}, // SEQ_DATA_PORT ++{0x2510, 0x1056}, // SEQ_DATA_PORT ++{0x2510, 0x1210}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x0D08}, // SEQ_DATA_PORT ++{0x2510, 0x0913}, // SEQ_DATA_PORT ++{0x2510, 0x13C8}, // SEQ_DATA_PORT ++{0x2510, 0x092B}, // SEQ_DATA_PORT ++{0x2510, 0x1588}, // SEQ_DATA_PORT ++{0x2510, 0x1388}, // SEQ_DATA_PORT ++{0x2510, 0x090B}, // SEQ_DATA_PORT ++{0x2510, 0x11D9}, // SEQ_DATA_PORT ++{0x2510, 0x091D}, // SEQ_DATA_PORT ++{0x2510, 0x1441}, // SEQ_DATA_PORT ++{0x2510, 0x0903}, // SEQ_DATA_PORT ++{0x2510, 0x1214}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x10D6}, // SEQ_DATA_PORT ++{0x2510, 0x1210}, // SEQ_DATA_PORT ++{0x2510, 0x1212}, // SEQ_DATA_PORT ++{0x2510, 0x1210}, // SEQ_DATA_PORT ++{0x2510, 0x11DD}, // SEQ_DATA_PORT ++{0x2510, 0x11D9}, // SEQ_DATA_PORT ++{0x2510, 0x1056}, // SEQ_DATA_PORT ++{0x2510, 0x090B}, // SEQ_DATA_PORT ++{0x2510, 0x11DB}, // SEQ_DATA_PORT ++{0x2510, 0x0915}, // SEQ_DATA_PORT ++{0x2510, 0x119B}, // SEQ_DATA_PORT ++{0x2510, 0x090F}, // SEQ_DATA_PORT ++{0x2510, 0x11BB}, // SEQ_DATA_PORT ++{0x2510, 0x121A}, // SEQ_DATA_PORT ++{0x2510, 0x1210}, // SEQ_DATA_PORT ++{0x2510, 0x1460}, // SEQ_DATA_PORT ++{0x2510, 0x1250}, // SEQ_DATA_PORT ++{0x2510, 0x1076}, // SEQ_DATA_PORT ++{0x2510, 0x10E6}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x15AB}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x13A8}, // SEQ_DATA_PORT ++{0x2510, 0x1240}, // SEQ_DATA_PORT ++{0x2510, 0x1260}, // SEQ_DATA_PORT ++{0x2510, 0x0923}, // SEQ_DATA_PORT ++{0x2510, 0x158D}, // SEQ_DATA_PORT ++{0x2510, 0x138D}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x0B09}, // SEQ_DATA_PORT ++{0x2510, 0x0108}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x1440}, // SEQ_DATA_PORT ++{0x2510, 0x091D}, // SEQ_DATA_PORT ++{0x2510, 0x1588}, // SEQ_DATA_PORT ++{0x2510, 0x1388}, // SEQ_DATA_PORT ++{0x2510, 0x092D}, // SEQ_DATA_PORT ++{0x2510, 0x1066}, // SEQ_DATA_PORT ++{0x2510, 0x0905}, // SEQ_DATA_PORT ++{0x2510, 0x0C08}, // SEQ_DATA_PORT ++{0x2510, 0x090B}, // SEQ_DATA_PORT ++{0x2510, 0x1441}, // SEQ_DATA_PORT ++{0x2510, 0x090D}, // SEQ_DATA_PORT ++{0x2510, 0x10E6}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x1262}, // SEQ_DATA_PORT ++{0x2510, 0x1260}, // SEQ_DATA_PORT ++{0x2510, 0x11BF}, // SEQ_DATA_PORT ++{0x2510, 0x11BB}, // SEQ_DATA_PORT ++{0x2510, 0x1066}, // SEQ_DATA_PORT ++{0x2510, 0x11FB}, // SEQ_DATA_PORT ++{0x2510, 0x0935}, // SEQ_DATA_PORT ++{0x2510, 0x11BB}, // SEQ_DATA_PORT ++{0x2510, 0x1263}, // SEQ_DATA_PORT ++{0x2510, 0x1260}, // SEQ_DATA_PORT ++{0x2510, 0x1400}, // SEQ_DATA_PORT ++{0x2510, 0x1510}, // SEQ_DATA_PORT ++{0x2510, 0x11B8}, // SEQ_DATA_PORT ++{0x2510, 0x12A0}, // SEQ_DATA_PORT ++{0x2510, 0x1200}, // SEQ_DATA_PORT ++{0x2510, 0x1026}, // SEQ_DATA_PORT ++{0x2510, 0x1000}, // SEQ_DATA_PORT ++{0x2510, 0x1342}, // SEQ_DATA_PORT ++{0x2510, 0x1100}, // SEQ_DATA_PORT ++{0x2510, 0x7A06}, // SEQ_DATA_PORT ++{0x2510, 0x0926}, // SEQ_DATA_PORT ++{0x2510, 0x0507}, // SEQ_DATA_PORT ++{0x2510, 0x0841}, // SEQ_DATA_PORT ++{0x2510, 0x3750}, // SEQ_DATA_PORT ++{0x2510, 0x2C2C}, // SEQ_DATA_PORT ++{0x2510, 0xFE02}, // SEQ_DATA_PORT ++{0x2510, 0xFE14}, // SEQ_DATA_PORT ++{0x3566, 0x3328}, // RESERVED_MFR_3566 ++{0x350C, 0x055F}, // RESERVED_MFR_350C ++{0x32D0, 0x3A02}, // RESERVED_MFR_32D0 ++{0x32D2, 0x3508}, // RESERVED_MFR_32D2 ++{0x32D4, 0x3702}, // RESERVED_MFR_32D4 ++{0x32D6, 0x3C04}, // RESERVED_MFR_32D6 ++{0x32DC, 0x370A}, // RESERVED_MFR_32DC ++ ++//Parallel Timing Setup ++{0x302A, 0x0009}, // VT_PIX_CLK_DIV ++{0x302C, 0x0001}, // VT_SYS_CLK_DIV ++{0x302E, 0x0003}, // PRE_PLL_CLK_DIV ++{0x3030, 0x0058}, // PLL_MULTIPLIER ++{0x3036, 0x0008}, // OP_WORD_CLK_DIV ++{0x3038, 0x0001}, // OP_SYS_CLK_DIV ++{0x30B0, 0x0A00}, // DIGITAL_TEST ++ ++//Readout Mode Configuration ++{0x30A2, 0x0001}, // X_ODD_INC_ ++{0x30A6, 0x0001}, // Y_ODD_INC_ ++{0x3040, 0x0000}, // READ_MODE ++{0x3044, 0x0400}, // DARK_CONTROL ++#ifdef AR0231_EMBEDDED_LINE ++{0x3064, 0x1982}, // SMIA_TEST ++#else ++{0x3064, 0x1802}, // SMIA_TEST ++#endif ++{0x33E0, 0x0880}, // RESERVED_MFR_33E0 ++{0x3180, 0x0080}, // RESERVED_MFR_3180 ++{0x33E4, 0x0080}, // RESERVED_MFR_33E4 ++ ++#if 1 ++{0x3004, AR0231_X_START}, // X_ADDR_START_ ++{0x3008, AR0231_X_END}, // X_ADDR_END_ ++{0x3002, AR0231_Y_START}, // Y_ADDR_START_ ++{0x3006, AR0231_Y_END}, // Y_ADDR_END_ ++{0x3402, 0x0000 | AR0231_MAX_WIDTH}, // X_OUTPUT_CONTROL ++{0x3404, 0x0000 | AR0231_MAX_HEIGHT}, // Y_OUTPUT_CONTROL ++#else ++{0x3004, 0}, // X_ADDR_START_ ++{0x3008, 0x0787}, // X_ADDR_END_ ++{0x3002, 0x0000}, // Y_ADDR_START_ ++{0x3006, 0x04B7}, // Y_ADDR_END_ ++{0x3402, 0x0788}, // RESERVED_MFR_3402 ++{0x3402, 0x0F10}, // RESERVED_MFR_3402 ++{0x3404, 0x0440}, // RESERVED_MFR_3404 ++{0x3404, 0x0970}, // RESERVED_MFR_3404 ++#endif ++{0x3032, 0x0000}, // SCALING_MODE ++{0x3400, 0x0010}, // RESERVED_MFR_3400 ++ ++//3exp Timing and Exposure ++{0x3082, 0x0008}, // OPERATION_MODE_CTRL ++{0x30BA, 0x11E2}, // DIGITAL_CTRL ++{0x300A, 0x05AF}, // FRAME_LENGTH_LINES_ ++{0x300C, 0x07BA}, // LINE_LENGTH_PCK_ ++{0x3042, 0x0000}, // EXTRA_DELAY ++{0x3238, 0x0222}, // EXPOSURE_RATIO ++{0x1008, 0x0374}, // FINE_INTEGRATION_TIME_MIN ++{0x100C, 0x05AF}, // FINE_INTEGRATION_TIME2_MIN ++{0x100E, 0x07EA}, // FINE_INTEGRATION_TIME3_MIN ++{0x1010, 0x0139}, // FINE_INTEGRATION_TIME4_MIN ++{0x3012, 0x0163}, // COARSE_INTEGRATION_TIME_ ++{0x3014, 0x06A6}, // FINE_INTEGRATION_TIME_ ++{0x321E, 0x06A6}, // FINE_INTEGRATION_TIME2 ++{0x3222, 0x06A6}, // FINE_INTEGRATION_TIME3 ++{0x30B0, 0x0B02}, // DIGITAL_TEST ++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA ++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC ++ ++//Parallel HDR 12 bit Output ++{0x31D0, 0x0001}, // COMPANDING ++{0x31AE, 0x0001}, // SERIAL_FORMAT ++{0x31AC, 0x140C}, // DATA_FORMAT_BITS ++ ++#if 0 // no need for front only camera ++/* Enable trigger input */ ++{0x340A, 0x00E0}, // GPIO_CONTROL1: GPIO1 is trigger ++{0x340C, 0x0002}, // GPIO_CONTROL2: GPIO1 is trigger ++{0x30CE, 0x0120}, // TRIGGER_MODE ++//{0x30DC, 0x0120}, // TRIGGER_DELAY ++{0x301A, 0x01D8}, // GPI pins enable ++#endif ++ ++{0x301A, 0x01DC}, // RESET_REGISTER - stream on ++ ++#if 1 ++{0x300A, AR0231_SENSOR_HEIGHT + 225}, // FRAME_LENGTH_LINES_ ++{0x300C, AR0231_SENSOR_WIDTH + 120}, // LINE_LENGTH_PCK_ ++/* the sequence must be updated to use following timings, now it is a hack */ ++{0x1008, 0x0fff}, // FINE_INTEGRATION_TIME_MIN ++{0x100C, 0x0fff}, // FINE_INTEGRATION_TIME2_MIN ++{0x100E, 0x0fff}, // FINE_INTEGRATION_TIME3_MIN ++{0x1010, 0x0fff}, // FINE_INTEGRATION_TIME4_MIN ++#endif ++}; +diff --git a/drivers/media/i2c/soc_camera/imagers/ar0231_rev6.h b/drivers/media/i2c/soc_camera/imagers/ar0231_rev6.h +new file mode 100644 +index 0000000..b5b8cb2 +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/imagers/ar0231_rev6.h +@@ -0,0 +1,343 @@ ++/* ++ * ON Semiconductor AR0231 sensor camera wizard 1920x1080@30/BGGR/MIPI ++ * ++ * Copyright (C) 2018-2020 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++/* Parallel Timing Setup 27MHz In 88 MHz Out */ ++static const struct ar0231_reg ar0231_regs_wizard_rev6_dvp[] = { ++{0x301A, 0x0001}, // reset ++{0x301A, 0x10D8}, // Stream off and setup parallel ++{0x3070, 0x0000}, // 1: Solid color test pattern, ++ // 2: Full color bar test pattern, ++ // 3: Fade to grey color bar test pattern, ++ //256: Walking 1 test pattern (12 bit) ++{0x3072, 0x0123}, // R ++{0x3074, 0x0456}, // G(GR row) ++{0x3076, 0x0abc}, // B ++{0x3078, 0x0def}, // G(GB row) ++#ifdef AR0231_DISPLAY_PATTERN_FIXED ++{0x3070, 0x0001}, ++#endif ++#ifdef AR0231_DISPLAY_PATTERN_COLOR_BAR ++{0x3070, 0x0002}, ++#endif ++ ++//Recommended Settings ++{0x3056, 0x0080}, // GREEN1_GAIN ++{0x305C, 0x0080}, // GREEN2_GAIN ++{0x3058, 0x0080}, // BLUE_GAIN ++{0x305A, 0x0080}, // RED_GAIN ++{0x3138, 0x000B}, // OTPM_TCFG_OPT ++{0x3372, 0xF54F}, // RESERVED_MFR_3372 ++{0x337A, 0x0D70}, // RESERVED_MFR_337A ++{0x337E, 0x1FFD}, // RESERVED_MFR_337E ++{0x3382, 0x00C0}, // RESERVED_MFR_3382 ++{0x3C04, 0x0E80}, // RESERVED_MFR_3C04 ++{0x3F90, 0x06E1}, // RESERVED_MFR_3F90 ++{0x3F92, 0x06E1}, // RESERVED_MFR_3F92 ++{0x350E, 0x1F14}, // RESERVED_MFR_350E ++{0x350E, 0xFF10}, // RESERVED_MFR_350E ++{0x3506, 0x4444}, // RESERVED_MFR_3506 ++{0x3508, 0x4444}, // RESERVED_MFR_3508 ++{0x350A, 0x4465}, // RESERVED_MFR_350A ++{0x350C, 0x055F}, // RESERVED_MFR_350C ++{0x3566, 0x9D38}, // RESERVED_MFR_3566 ++{0x3518, 0x1FFE}, // RESERVED_MFR_3518 ++{0x3520, 0xC688}, // RESERVED_MFR_3520 ++{0x3522, 0x88C0}, // RESERVED_MFR_3522 ++{0x3524, 0xC0C6}, // RESERVED_MFR_3524 ++{0x352C, 0xC6C6}, // RESERVED_MFR_352C ++{0x3528, 0x0900}, // RESERVED_MFR_3528 ++{0x3528, 0x9900}, // RESERVED_MFR_3528 ++{0x3528, 0x9909}, // RESERVED_MFR_3528 ++{0x3528, 0x9999}, // RESERVED_MFR_3528 ++{0x352A, 0x089F}, // RESERVED_MFR_352A ++{0x352E, 0x0001}, // RESERVED_MFR_352E ++{0x352E, 0x0011}, // RESERVED_MFR_352E ++{0x3530, 0x0400}, // RESERVED_MFR_3530 ++{0x3530, 0x4400}, // RESERVED_MFR_3530 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF00}, // RESERVED_MFR_3536 ++{0x3536, 0xFF02}, // RESERVED_MFR_3536 ++{0x3536, 0xFF06}, // RESERVED_MFR_3536 ++{0x3536, 0xFF06}, // RESERVED_MFR_3536 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x3538, 0xFFFF}, // RESERVED_MFR_3538 ++{0x353A, 0x9000}, // RESERVED_MFR_353A ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x353C, 0x3F00}, // RESERVED_MFR_353C ++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC ++{0x3540, 0xC637}, // RESERVED_MFR_3540 ++{0x3540, 0xC637}, // RESERVED_MFR_3540 ++{0x3540, 0xC637}, // RESERVED_MFR_3540 ++{0x3542, 0x584B}, // RESERVED_MFR_3542 ++{0x3542, 0x464B}, // RESERVED_MFR_3542 ++{0x3544, 0x565A}, // RESERVED_MFR_3544 ++{0x3544, 0x4B5A}, // RESERVED_MFR_3544 ++{0x3546, 0x545A}, // RESERVED_MFR_3546 ++{0x3546, 0x5A5A}, // RESERVED_MFR_3546 ++{0x3548, 0x6400}, // RESERVED_MFR_3548 ++{0x3556, 0x101F}, // RESERVED_MFR_3556 ++{0x3566, 0x9D38}, // RESERVED_MFR_3566 ++{0x3566, 0x1D38}, // RESERVED_MFR_3566 ++{0x3566, 0x1D28}, // RESERVED_MFR_3566 ++{0x3566, 0x1128}, // RESERVED_MFR_3566 ++{0x3566, 0x1328}, // RESERVED_MFR_3566 ++{0x3566, 0x3328}, // RESERVED_MFR_3566 ++{0x3528, 0xDDDD}, // RESERVED_MFR_3528 ++ ++//Sequencer Update ++{0x2512, 0x8000}, // SEQ_CTRL_PORT ++{0x2510, 0x0905}, // SEQ_DATA_PORT ++{0x2510, 0x3350}, // SEQ_DATA_PORT ++{0x2510, 0x2004}, // SEQ_DATA_PORT ++{0x2510, 0x1460}, // SEQ_DATA_PORT ++{0x2510, 0x1578}, // SEQ_DATA_PORT ++{0x2510, 0x1360}, // SEQ_DATA_PORT ++{0x2510, 0x7B24}, // SEQ_DATA_PORT ++{0x2510, 0xFF24}, // SEQ_DATA_PORT ++{0x2510, 0xFF24}, // SEQ_DATA_PORT ++{0x2510, 0xEA24}, // SEQ_DATA_PORT ++{0x2510, 0x1022}, // SEQ_DATA_PORT ++{0x2510, 0x2410}, // SEQ_DATA_PORT ++{0x2510, 0x155A}, // SEQ_DATA_PORT ++{0x2510, 0x1342}, // SEQ_DATA_PORT ++{0x2510, 0x1400}, // SEQ_DATA_PORT ++{0x2510, 0x24FF}, // SEQ_DATA_PORT ++{0x2510, 0x24FF}, // SEQ_DATA_PORT ++{0x2510, 0x24EA}, // SEQ_DATA_PORT ++{0x2510, 0x2324}, // SEQ_DATA_PORT ++{0x2510, 0x647A}, // SEQ_DATA_PORT ++{0x2510, 0x2404}, // SEQ_DATA_PORT ++{0x2510, 0x052C}, // SEQ_DATA_PORT ++{0x2510, 0x400A}, // SEQ_DATA_PORT ++{0x2510, 0xFF0A}, // SEQ_DATA_PORT ++{0x2510, 0xFF0A}, // SEQ_DATA_PORT ++{0x2510, 0x1808}, // SEQ_DATA_PORT ++{0x2510, 0x3851}, // SEQ_DATA_PORT ++{0x2510, 0x1440}, // SEQ_DATA_PORT ++{0x2510, 0x0004}, // SEQ_DATA_PORT ++{0x2510, 0x0801}, // SEQ_DATA_PORT ++{0x2510, 0x0408}, // SEQ_DATA_PORT ++{0x2510, 0x1180}, // SEQ_DATA_PORT ++{0x2510, 0x15DC}, // SEQ_DATA_PORT ++{0x2510, 0x134C}, // SEQ_DATA_PORT ++{0x2510, 0x1002}, // SEQ_DATA_PORT ++{0x2510, 0x1016}, // SEQ_DATA_PORT ++{0x2510, 0x1181}, // SEQ_DATA_PORT ++{0x2510, 0x1189}, // SEQ_DATA_PORT ++{0x2510, 0x1056}, // SEQ_DATA_PORT ++{0x2510, 0x1210}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x0D08}, // SEQ_DATA_PORT ++{0x2510, 0x0913}, // SEQ_DATA_PORT ++{0x2510, 0x13C8}, // SEQ_DATA_PORT ++{0x2510, 0x092B}, // SEQ_DATA_PORT ++{0x2510, 0x1588}, // SEQ_DATA_PORT ++{0x2510, 0x1388}, // SEQ_DATA_PORT ++{0x2510, 0x090B}, // SEQ_DATA_PORT ++{0x2510, 0x11D9}, // SEQ_DATA_PORT ++{0x2510, 0x091D}, // SEQ_DATA_PORT ++{0x2510, 0x1441}, // SEQ_DATA_PORT ++{0x2510, 0x0903}, // SEQ_DATA_PORT ++{0x2510, 0x1214}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x10D6}, // SEQ_DATA_PORT ++{0x2510, 0x1210}, // SEQ_DATA_PORT ++{0x2510, 0x1212}, // SEQ_DATA_PORT ++{0x2510, 0x1210}, // SEQ_DATA_PORT ++{0x2510, 0x11DD}, // SEQ_DATA_PORT ++{0x2510, 0x11D9}, // SEQ_DATA_PORT ++{0x2510, 0x1056}, // SEQ_DATA_PORT ++{0x2510, 0x090B}, // SEQ_DATA_PORT ++{0x2510, 0x11DB}, // SEQ_DATA_PORT ++{0x2510, 0x0915}, // SEQ_DATA_PORT ++{0x2510, 0x119B}, // SEQ_DATA_PORT ++{0x2510, 0x090F}, // SEQ_DATA_PORT ++{0x2510, 0x11BB}, // SEQ_DATA_PORT ++{0x2510, 0x121A}, // SEQ_DATA_PORT ++{0x2510, 0x1210}, // SEQ_DATA_PORT ++{0x2510, 0x1460}, // SEQ_DATA_PORT ++{0x2510, 0x1250}, // SEQ_DATA_PORT ++{0x2510, 0x1076}, // SEQ_DATA_PORT ++{0x2510, 0x10E6}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x15AB}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x13A8}, // SEQ_DATA_PORT ++{0x2510, 0x1240}, // SEQ_DATA_PORT ++{0x2510, 0x1260}, // SEQ_DATA_PORT ++{0x2510, 0x0923}, // SEQ_DATA_PORT ++{0x2510, 0x158D}, // SEQ_DATA_PORT ++{0x2510, 0x138D}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x0B09}, // SEQ_DATA_PORT ++{0x2510, 0x0108}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x1440}, // SEQ_DATA_PORT ++{0x2510, 0x091D}, // SEQ_DATA_PORT ++{0x2510, 0x1588}, // SEQ_DATA_PORT ++{0x2510, 0x1388}, // SEQ_DATA_PORT ++{0x2510, 0x092D}, // SEQ_DATA_PORT ++{0x2510, 0x1066}, // SEQ_DATA_PORT ++{0x2510, 0x0905}, // SEQ_DATA_PORT ++{0x2510, 0x0C08}, // SEQ_DATA_PORT ++{0x2510, 0x090B}, // SEQ_DATA_PORT ++{0x2510, 0x1441}, // SEQ_DATA_PORT ++{0x2510, 0x090D}, // SEQ_DATA_PORT ++{0x2510, 0x10E6}, // SEQ_DATA_PORT ++{0x2510, 0x0901}, // SEQ_DATA_PORT ++{0x2510, 0x1262}, // SEQ_DATA_PORT ++{0x2510, 0x1260}, // SEQ_DATA_PORT ++{0x2510, 0x11BF}, // SEQ_DATA_PORT ++{0x2510, 0x11BB}, // SEQ_DATA_PORT ++{0x2510, 0x1066}, // SEQ_DATA_PORT ++{0x2510, 0x11FB}, // SEQ_DATA_PORT ++{0x2510, 0x0935}, // SEQ_DATA_PORT ++{0x2510, 0x11BB}, // SEQ_DATA_PORT ++{0x2510, 0x1263}, // SEQ_DATA_PORT ++{0x2510, 0x1260}, // SEQ_DATA_PORT ++{0x2510, 0x1400}, // SEQ_DATA_PORT ++{0x2510, 0x1510}, // SEQ_DATA_PORT ++{0x2510, 0x11B8}, // SEQ_DATA_PORT ++{0x2510, 0x12A0}, // SEQ_DATA_PORT ++{0x2510, 0x1200}, // SEQ_DATA_PORT ++{0x2510, 0x1026}, // SEQ_DATA_PORT ++{0x2510, 0x1000}, // SEQ_DATA_PORT ++{0x2510, 0x1342}, // SEQ_DATA_PORT ++{0x2510, 0x1100}, // SEQ_DATA_PORT ++{0x2510, 0x7A06}, // SEQ_DATA_PORT ++{0x2510, 0x0915}, // SEQ_DATA_PORT ++{0x2510, 0x0507}, // SEQ_DATA_PORT ++{0x2510, 0x0841}, // SEQ_DATA_PORT ++{0x2510, 0x3750}, // SEQ_DATA_PORT ++{0x2510, 0x2C2C}, // SEQ_DATA_PORT ++{0x2510, 0xFE05}, // SEQ_DATA_PORT ++{0x2510, 0xFE13}, // SEQ_DATA_PORT ++{0x1008, 0x0361}, // FINE_INTEGRATION_TIME_MIN ++{0x100C, 0x0589}, // FINE_INTEGRATION_TIME2_MIN ++{0x100E, 0x07B1}, // FINE_INTEGRATION_TIME3_MIN ++{0x1010, 0x0139}, // FINE_INTEGRATION_TIME4_MIN ++{0x3230, 0x0304}, // FINE_CORRECTION ++{0x3232, 0x052C}, // FINE_CORRECTION2 ++{0x3234, 0x0754}, // FINE_CORRECTION3 ++{0x3236, 0x00DC}, // FINE_CORRECTION4 ++{0x3566, 0x3328}, // RESERVED_MFR_3566 ++{0x350C, 0x055F}, // RESERVED_MFR_350C ++{0x32D0, 0x3A02}, // RESERVED_MFR_32D0 ++{0x32D2, 0x3508}, // RESERVED_MFR_32D2 ++{0x32D4, 0x3702}, // RESERVED_MFR_32D4 ++{0x32D6, 0x3C04}, // RESERVED_MFR_32D6 ++{0x32DC, 0x370A}, // RESERVED_MFR_32DC ++ ++//Parallel Timing Setup 27MHz In 88 MHz Out ++{0x302A, 0x0009}, // VT_PIX_CLK_DIV ++{0x302C, 0x0001}, // VT_SYS_CLK_DIV ++{0x302E, 0x0003}, // PRE_PLL_CLK_DIV ++{0x3030, 0x0058}, // PLL_MULTIPLIER ++{0x3036, 0x0008}, // OP_WORD_CLK_DIV ++{0x3038, 0x0001}, // OP_SYS_CLK_DIV ++{0x30B0, 0x0B02}, // DIGITAL_TEST ++ ++//Readout Mode Configuration ++{0x30A2, 0x0001}, // X_ODD_INC_ ++{0x30A6, 0x0001}, // Y_ODD_INC_ ++{0x3040, 0x0000}, // READ_MODE ++{0x3082, 0x0008}, // OPERATION_MODE_CTRL ++{0x30BA, 0x11E2}, // DIGITAL_CTRL ++{0x3044, 0x0400}, // DARK_CONTROL ++#ifdef AR0231_EMBEDDED_LINE ++{0x3064, 0x1982}, // SMIA_TEST ++#else ++{0x3064, 0x1802}, // SMIA_TEST ++#endif ++{0x33E0, 0x0880}, // RESERVED_MFR_33E0 ++{0x3180, 0x0080}, // RESERVED_MFR_3180 ++{0x33E4, 0x0080}, // RESERVED_MFR_33E4 ++{0x33E0, 0x0C80}, // RESERVED_MFR_33E0 ++ ++#if 1 ++{0x3004, AR0231_X_START}, // X_ADDR_START_ ++{0x3008, AR0231_X_END}, // X_ADDR_END_ ++{0x3002, AR0231_Y_START}, // Y_ADDR_START_ ++{0x3006, AR0231_Y_END}, // Y_ADDR_END_ ++{0x3402, 0x0000 | AR0231_MAX_WIDTH}, // X_OUTPUT_CONTROL ++{0x3404, 0x0000 | AR0231_MAX_HEIGHT}, // Y_OUTPUT_CONTROL ++#else ++{0x3004, 0}, // X_ADDR_START_ ++{0x3008, 0x0787}, // X_ADDR_END_ ++{0x3002, 0x0000}, // Y_ADDR_START_ ++{0x3006, 0x04B7}, // Y_ADDR_END_ ++{0x3402, 0x0788}, // RESERVED_MFR_3402 ++{0x3402, 0x0F10}, // RESERVED_MFR_3402 ++{0x3404, 0x0440}, // RESERVED_MFR_3404 ++{0x3404, 0x0970}, // RESERVED_MFR_3404 ++#endif ++{0x3032, 0x0000}, // SCALING_MODE ++{0x3400, 0x0010}, // RESERVED_MFR_3400 ++ ++//3exp Timing and Exposure ++{0x3082, 0x0008}, // OPERATION_MODE_CTRL ++{0x30BA, 0x11E2}, // DIGITAL_CTRL ++{0x300A, 0x05CA}, // FRAME_LENGTH_LINES_ ++{0x300C, 0x07BA}, // LINE_LENGTH_PCK_ ++{0x3042, 0x0000}, // EXTRA_DELAY ++{0x3238, 0x0222}, // EXPOSURE_RATIO ++{0x3012, 0x0163}, // COARSE_INTEGRATION_TIME_ ++{0x3014, 0x08CC}, // FINE_INTEGRATION_TIME_ ++{0x321E, 0x08CC}, // FINE_INTEGRATION_TIME2 ++{0x3222, 0x0254}, // FINE_INTEGRATION_TIME3 ++{0x30B0, 0x0A00}, // DIGITAL_TEST ++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA ++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC ++ ++//Parallel HDR 12 bit Output ++{0x31D0, 0x0001}, // COMPANDING ++{0x31AE, 0x0001}, // SERIAL_FORMAT ++{0x31AC, 0x140C}, // DATA_FORMAT_BITS ++ ++#if 0 // no need for front only camera ++/* Enable trigger input */ ++{0x340A, 0x00E0}, // GPIO_CONTROL1: GPIO1 is trigger ++{0x340C, 0x0002}, // GPIO_CONTROL2: GPIO1 is trigger ++{0x30CE, 0x0120}, // TRIGGER_MODE ++//{0x30DC, 0x0120}, // TRIGGER_DELAY ++{0x301A, 0x01D8}, // GPI pins enable ++#endif ++ ++{0x301A, 0x01DC}, // RESET_REGISTER - stream on ++ ++#if 1 ++{0x300A, AR0231_SENSOR_HEIGHT + 225}, // FRAME_LENGTH_LINES_ ++{0x300C, AR0231_SENSOR_WIDTH + 120}, // LINE_LENGTH_PCK_ ++/* the sequence must be updated to use following timings, now it is a hack */ ++{0x1008, 0x0fff}, // FINE_INTEGRATION_TIME_MIN ++{0x100C, 0x0fff}, // FINE_INTEGRATION_TIME2_MIN ++{0x100E, 0x0fff}, // FINE_INTEGRATION_TIME3_MIN ++{0x1010, 0x0fff}, // FINE_INTEGRATION_TIME4_MIN ++#endif ++}; +diff --git a/drivers/media/i2c/soc_camera/imagers/ar0231_rev7.h b/drivers/media/i2c/soc_camera/imagers/ar0231_rev7.h +new file mode 100644 +index 0000000..f3485f5 +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/imagers/ar0231_rev7.h +@@ -0,0 +1,445 @@ ++/* ++ * ON Semiconductor AR0231 sensor camera wizard 1928x1208@30/BGGR/MIPI ++ * ++ * Copyright (C) 2018-2020 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++/* 3Exp HDR Full Resolution Mode MIPI 4lane 12bit 30FPS, XCLK=27MHz */ ++static const struct ar0231_reg ar0231_regs_wizard_rev7[] = { ++{0x301A, 0x18}, // MIPI, stream OFF ++{AR0231_DELAY, 200}, // Wait 200ms ++ ++{0x3070, 0x0000}, // 1: Solid color test pattern, ++ // 2: Full color bar test pattern, ++ // 3: Fade to grey color bar test pattern, ++ //256: Walking 1 test pattern (12 bit) ++{0x3072, 0x0123}, // R ++{0x3074, 0x0456}, // G(GR row) ++{0x3076, 0x0abc}, // B ++{0x3078, 0x0def}, // G(GB row) ++#ifdef AR0231_DISPLAY_PATTERN_FIXED ++{0x3070, 0x0001}, ++#endif ++#ifdef AR0231_DISPLAY_PATTERN_COLOR_BAR ++{0x3070, 0x0002}, ++#endif ++{AR0231_DELAY, 100}, // Wait 100ms ++ ++#if 1 /* Sensor Setup */ ++#if 1 /* Recommended Settings */ ++{0x3092, 0x0C24}, ++{0x337A, 0x0C80}, ++{0x3520, 0x1288}, ++{0x3522, 0x880C}, ++{0x3524, 0x0C12}, ++{0x352C, 0x1212}, ++{0x354A, 0x007F}, ++{0x350C, 0x055C}, ++{0x3506, 0x3333}, ++{0x3508, 0x3333}, ++{0x3100, 0x4000}, ++{0x3280, 0x0FA0}, ++{0x3282, 0x0FA0}, ++{0x3284, 0x0FA0}, ++{0x3286, 0x0FA0}, ++{0x3288, 0x0FA0}, ++{0x328A, 0x0FA0}, ++{0x328C, 0x0FA0}, ++{0x328E, 0x0FA0}, ++{0x3290, 0x0FA0}, ++{0x3292, 0x0FA0}, ++{0x3294, 0x0FA0}, ++{0x3296, 0x0FA0}, ++{0x3298, 0x0FA0}, ++{0x329A, 0x0FA0}, ++{0x329C, 0x0FA0}, ++{0x329E, 0x0FA0}, ++#endif /* Recommended Settings */ ++ ++#if 1 /* Sequencer Update */ ++{0x2512, 0x8000}, ++{0x2510, 0x0905}, ++{0x2510, 0x3350}, ++{0x2510, 0x2004}, ++{0x2510, 0x1460}, ++{0x2510, 0x1578}, ++{0x2510, 0x0901}, ++{0x2510, 0x7B24}, ++{0x2510, 0xFF24}, ++{0x2510, 0xFF24}, ++{0x2510, 0xEA24}, ++{0x2510, 0x1022}, ++{0x2510, 0x2410}, ++{0x2510, 0x155A}, ++{0x2510, 0x0901}, ++{0x2510, 0x1400}, ++{0x2510, 0x24FF}, ++{0x2510, 0x24FF}, ++{0x2510, 0x24EA}, ++{0x2510, 0x2324}, ++{0x2510, 0x647A}, ++{0x2510, 0x2404}, ++{0x2510, 0x052C}, ++{0x2510, 0x400A}, ++{0x2510, 0xFF0A}, ++{0x2510, 0xFF0A}, ++{0x2510, 0x1008}, ++{0x2510, 0x3851}, ++{0x2510, 0x1440}, ++{0x2510, 0x0004}, ++{0x2510, 0x0801}, ++{0x2510, 0x0408}, ++{0x2510, 0x1180}, ++{0x2510, 0x2652}, ++{0x2510, 0x1518}, ++{0x2510, 0x0906}, ++{0x2510, 0x1348}, ++{0x2510, 0x1002}, ++{0x2510, 0x1016}, ++{0x2510, 0x1181}, ++{0x2510, 0x1189}, ++{0x2510, 0x1056}, ++{0x2510, 0x1210}, ++{0x2510, 0x0901}, ++{0x2510, 0x0D09}, ++{0x2510, 0x1413}, ++{0x2510, 0x8809}, ++{0x2510, 0x2B15}, ++{0x2510, 0x8809}, ++{0x2510, 0x0311}, ++{0x2510, 0xD909}, ++{0x2510, 0x1214}, ++{0x2510, 0x4109}, ++{0x2510, 0x0312}, ++{0x2510, 0x1409}, ++{0x2510, 0x0110}, ++{0x2510, 0xD612}, ++{0x2510, 0x1012}, ++{0x2510, 0x1212}, ++{0x2510, 0x1011}, ++{0x2510, 0xDD11}, ++{0x2510, 0xD910}, ++{0x2510, 0x5609}, ++{0x2510, 0x1511}, ++{0x2510, 0xDB09}, ++{0x2510, 0x1511}, ++{0x2510, 0x9B09}, ++{0x2510, 0x0F11}, ++{0x2510, 0xBB12}, ++{0x2510, 0x1A12}, ++{0x2510, 0x1014}, ++{0x2510, 0x6012}, ++{0x2510, 0x5010}, ++{0x2510, 0x7610}, ++{0x2510, 0xE609}, ++{0x2510, 0x0812}, ++{0x2510, 0x4012}, ++{0x2510, 0x6009}, ++{0x2510, 0x290B}, ++{0x2510, 0x0904}, ++{0x2510, 0x1440}, ++{0x2510, 0x0923}, ++{0x2510, 0x15C8}, ++{0x2510, 0x13C8}, ++{0x2510, 0x092C}, ++{0x2510, 0x1588}, ++{0x2510, 0x1388}, ++{0x2510, 0x0C09}, ++{0x2510, 0x0C14}, ++{0x2510, 0x4109}, ++{0x2510, 0x1112}, ++{0x2510, 0x6212}, ++{0x2510, 0x6011}, ++{0x2510, 0xBF11}, ++{0x2510, 0xBB10}, ++{0x2510, 0x6611}, ++{0x2510, 0xFB09}, ++{0x2510, 0x3511}, ++{0x2510, 0xBB12}, ++{0x2510, 0x6312}, ++{0x2510, 0x6014}, ++{0x2510, 0x0015}, ++{0x2510, 0x0011}, ++{0x2510, 0xB812}, ++{0x2510, 0xA012}, ++{0x2510, 0x0010}, ++{0x2510, 0x2610}, ++{0x2510, 0x0013}, ++{0x2510, 0x0011}, ++{0x2510, 0x0008}, ++{0x2510, 0x3053}, ++{0x2510, 0x4215}, ++{0x2510, 0x4013}, ++{0x2510, 0x4010}, ++{0x2510, 0x0210}, ++{0x2510, 0x1611}, ++{0x2510, 0x8111}, ++{0x2510, 0x8910}, ++{0x2510, 0x5612}, ++{0x2510, 0x1009}, ++{0x2510, 0x010D}, ++{0x2510, 0x0815}, ++{0x2510, 0xC015}, ++{0x2510, 0xD013}, ++{0x2510, 0x5009}, ++{0x2510, 0x1313}, ++{0x2510, 0xD009}, ++{0x2510, 0x0215}, ++{0x2510, 0xC015}, ++{0x2510, 0xC813}, ++{0x2510, 0xC009}, ++{0x2510, 0x0515}, ++{0x2510, 0x8813}, ++{0x2510, 0x8009}, ++{0x2510, 0x0213}, ++{0x2510, 0x8809}, ++{0x2510, 0x0411}, ++{0x2510, 0xC909}, ++{0x2510, 0x0814}, ++{0x2510, 0x0109}, ++{0x2510, 0x0B11}, ++{0x2510, 0xD908}, ++{0x2510, 0x1400}, ++{0x2510, 0x091A}, ++{0x2510, 0x1440}, ++{0x2510, 0x0903}, ++{0x2510, 0x1214}, ++{0x2510, 0x0901}, ++{0x2510, 0x10D6}, ++{0x2510, 0x1210}, ++{0x2510, 0x1212}, ++{0x2510, 0x1210}, ++{0x2510, 0x11DD}, ++{0x2510, 0x11D9}, ++{0x2510, 0x1056}, ++{0x2510, 0x0917}, ++{0x2510, 0x11DB}, ++{0x2510, 0x0913}, ++{0x2510, 0x11FB}, ++{0x2510, 0x0905}, ++{0x2510, 0x11BB}, ++{0x2510, 0x121A}, ++{0x2510, 0x1210}, ++{0x2510, 0x1460}, ++{0x2510, 0x1250}, ++{0x2510, 0x1076}, ++{0x2510, 0x10E6}, ++{0x2510, 0x0901}, ++{0x2510, 0x15A8}, ++{0x2510, 0x0901}, ++{0x2510, 0x13A8}, ++{0x2510, 0x1240}, ++{0x2510, 0x1260}, ++{0x2510, 0x0925}, ++{0x2510, 0x13AD}, ++{0x2510, 0x0902}, ++{0x2510, 0x0907}, ++{0x2510, 0x1588}, ++{0x2510, 0x0901}, ++{0x2510, 0x138D}, ++{0x2510, 0x0B09}, ++{0x2510, 0x0914}, ++{0x2510, 0x4009}, ++{0x2510, 0x0B13}, ++{0x2510, 0x8809}, ++{0x2510, 0x1C0C}, ++{0x2510, 0x0920}, ++{0x2510, 0x1262}, ++{0x2510, 0x1260}, ++{0x2510, 0x11BF}, ++{0x2510, 0x11BB}, ++{0x2510, 0x1066}, ++{0x2510, 0x090A}, ++{0x2510, 0x11FB}, ++{0x2510, 0x093B}, ++{0x2510, 0x11BB}, ++{0x2510, 0x1263}, ++{0x2510, 0x1260}, ++{0x2510, 0x1400}, ++{0x2510, 0x1508}, ++{0x2510, 0x11B8}, ++{0x2510, 0x12A0}, ++{0x2510, 0x1200}, ++{0x2510, 0x1026}, ++{0x2510, 0x1000}, ++{0x2510, 0x1300}, ++{0x2510, 0x1100}, ++{0x2510, 0x437A}, ++{0x2510, 0x0609}, ++{0x2510, 0x0B05}, ++{0x2510, 0x0708}, ++{0x2510, 0x4137}, ++{0x2510, 0x502C}, ++{0x2510, 0x2CFE}, ++{0x2510, 0x15FE}, ++{0x2510, 0x0C2C}, ++ ++{0x32e6, 0xe0}, ++{0x1008, 0x36f}, ++{0x100c, 0x58f}, ++{0x100e, 0x7af}, ++{0x1010, 0x14f}, ++ ++{0x3230, 0x312}, ++{0x3232, 0x532}, ++{0x3234, 0x752}, ++{0x3236, 0xf2}, ++#endif /* Sequencer Update */ ++ ++//{0x3566, 0x3328}, // clear bit6 ++{0x32D0, 0x3A02}, ++{0x32D2, 0x3508}, ++{0x32D4, 0x3702}, ++{0x32D6, 0x3C04}, ++{0x32DC, 0x370A}, ++{0x30B0, 0x800}, // clear bit9 ++#endif /* Sensor Setup */ ++ ++#if 1 /* Serial 12-bit Timing Setup */ ++/* PCLK=24Mhz/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 *2 */ ++/* PCLK=24Mhz/2 *44/1/12 *2= 88Mhz - TI serializers */ ++{0x302E, 2}, // pre_pll_clk_div ++{0x3030, 44}, // pll_multiplier ++{0x302C, 1}, // vt_sys_clk_div (P1 divider) ++{0x302A, 6}, // vt_pix_clk_div (P2 divider) ++{0x3038, 1}, // op_sys_clk_div (P3 divider) ++{0x3036, 12}, // op_word_clk_div (P4 divider) ++{0x30B0, 0x800}, // digital_test: pll_complete_bypass=0 ++#endif /* Serial 12-bit Timing Setup */ ++ ++#if 1 /* Readout Mode Configuration */ ++{0x30A2, 1}, // x_odd_inc_ ++{0x30A6, 1}, // y_odd_inc_ ++{0x3040, 0}, // read_mode ++//{0x3082, 0x8}, // operation_mode_ctrl ++//{0x30BA, 0x11E2}, // digital_ctrl ++{0x3044, 0x400}, // dark_control ++#ifdef AR0231_EMBEDDED_LINE ++{0x3064, 0x1982}, // SMIA_TEST ++#else ++{0x3064, 0x1802}, // SMIA_TEST ++#endif ++//{0x33E0, 0xC80}, ++//{0x3180, 0x80}, ++//{0x33E4, 0x80}, ++#endif /* Readout Mode Configuration */ ++ ++#if 1 /* Full Res FOV */ ++{0x3004, AR0231_X_START}, // X_ADDR_START_ ++{0x3008, AR0231_X_END}, // X_ADDR_END_ ++{0x3002, AR0231_Y_START}, // Y_ADDR_START_ ++{0x3006, AR0231_Y_END}, // Y_ADDR_END_ ++{0x3032, 0x0}, // scaling_mode ++{0x3400, 0x10}, ++{0x3402, 0x0000 | AR0231_MAX_WIDTH}, // X_OUTPUT_CONTROL ++{0x3404, 0x0000 | AR0231_MAX_HEIGHT}, // Y_OUTPUT_CONTROL ++#endif /* Full Res FOV */ ++ ++#if 1 /* 3exp Timing and Exposure */ ++{0x3082, 0x8}, // operation_mode_ctrl ++{0x30BA, 0x11E2}, // digital_ctrl: num_exp_max=2 ++ ++/* Row and Pixel Timing */ ++{0x300C, 1674}, // line_length_pck_ ++{0x300A, 1314}, // frame_length_lines_ ++{0x3042, 0}, // extra_delay ++ ++/* Exposure Settings */ ++//{0x3238, 0x222}, // exposure_ratio ++{0x3012, 355}, // coarse_integration_time_ ++{0x3014, 1874}, // fine_integration_time_ ++{0x321E, 1874}, // fine_integration_time2 ++{0x3222, 1874}, // fine_integration_time3 ++{0x30B0, 0x800}, // digital_test: set bit11 ++{0x32EA, 0x3C0E}, ++{0x32EC, 0x72A1}, ++#endif /* 3exp Timing and Exposure - Serial */ ++ ++#if 1 /* HDR 12 bit Output */ ++{0x31D0, 1}, // companding ++{0x31AC, 0x140C}, // data_format_bits: RAW20, OUT12 ++#endif /* HDR 12 bit Output */ ++ ++#if 1 /* MIPI 12 bit Settings */ ++{0x31AE, 0x204}, // serial_format: MIPI 4 lanes ++{0x3342, 0x2c2c}, // default, DT=0x12, DT=0x2C ++{0x3346, 0x2c2c}, // default, DT=0x12, DT=0x2C ++{0x334A, 0x2c2c}, // default, DT=0x12, DT=0x2C ++{0x334E, 0x2c2c}, // default, DT=0x12, DT=0x2C ++//{0x3344, 0x0011}, // default, VC=0 ++//{0x3348, 0x0111}, // default, VC=1 ++//{0x334C, 0x0211}, // default, VC=2 ++//{0x3350, 0x0311}, // default, VC=3 ++//{0x31B0, 0x49}, // frame_preamble ++//{0x31B2, 0x33}, // line_preamble ++{0x31B4, 0x2185}, ++{0x31B6, 0x1146}, ++{0x31B8, 0x3047}, ++{0x31BA, 0x186}, ++{0x31BC, 0x805}, ++#endif /* MIPI 12 bit Settings */ ++ ++/* FPS = 105MHz / reg0x300A / reg0x300C * (DES_XTAL/27MHz), DES_XTAL=23.5MHz */ ++{0x300A, AR0231_SENSOR_HEIGHT + 100}, // Frame_length_Lines ++{0x300C, AR0231_SENSOR_WIDTH + 550}, // Line_length_pck ++{0x3012, 0x144}, //Integration_time ++ ++#if 0 /* Enable trigger input */ ++{0x340A, 0x00E0}, // GPIO_CONTROL1: GPIO0 is trigger ++{0x340C, 0x0002}, // GPIO_CONTROL2: GPIO0 is trigger ++{0x30CE, 0x0120}, // TRIGGER_MODE ++//{0x30DC, 0x0120}, // TRIGGER_DELAY ++{0x301A, 0x0118}, // GPI pins enable ++#endif ++}; ++ ++/* 3Exp HDR Full Resolution Mode Parallel 12bit 30FPS, XCLK=24MHz */ ++static const struct ar0231_reg ar0231_regs_wizard_rev7_dvp[] = { ++#if 1 /* Parallel Timing Setup */ ++/* PCLK=24Mhz/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 */ ++/* PCLK=24Mhz/3 *88/1/8 = 88Mhz - TI serializers */ ++{0x302A, 8}, // vt_pix_clk_div (P2 divider) ++{0x302C, 1}, // vt_sys_clk_div (P1 divider) ++{0x302E, 3}, // pre_pll_clk_div ++{0x3030, 88}, // pll_multiplier ++{0x3036, 8}, // op_word_clk_div (P4 divider) ++{0x3038, 1}, // op_sys_clk_div (P3 divider) ++{0x30B0, 0x800}, // digital_test: pll_complete_bypass=0 ++#endif ++ ++#if 1 /* 3exp Timing and Exposure - Parallel */ ++{0x3082, 0x8}, // operation_mode_ctrl ++{0x30BA, 0x11E2}, // digital_ctrl: num_exp_max=2 ++ ++/* Row and Pixel Timing */ ++#if 1 ++{0x300A, AR0231_SENSOR_HEIGHT + 225}, // frame_length_lines_ ++{0x300C, AR0231_SENSOR_WIDTH + 120}, // line_length_pck_ ++#else ++{0x300C, 1978}, // line_length_pck_ ++{0x300A, 1482}, // frame_length_lines_ ++#endif ++{0x3042, 0}, // extra_delay ++ ++/* Exposure Settings */ ++//{0x3238, 0x222}, // exposure_ratio ++//{0x3012, 355}, // coarse_integration_time_ ++{0x3014, 2178}, // fine_integration_time_ ++{0x321E, 2178}, // fine_integration_time2 ++{0x3222, 2178}, // fine_integration_time3 ++{0x30B0, 0x800}, // digital_test: set bit11 ++{0x32EA, 0x3C0E}, ++{0x32EC, 0x72A1}, ++#endif /* 3exp Timing and Exposure - Parallel */ ++ ++#if 1 /* Parallel HDR 12 bit Output */ ++{0x31AE, 0x001}, // serial_format: ++#endif ++ ++{0x301A, 0x01d8}, // RESET_REGISTER parallel pins enable ++}; +-- +2.7.4 + + -- cgit 1.2.3-korg