From 0901b9accc0ee11072daebedbc385cf38364144a Mon Sep 17 00:00:00 2001 From: Vladimir Barinov Date: Sun, 21 Apr 2019 19:44:00 +0300 Subject: [PATCH 119/122] media: i2c: add AR0147 imager This adds AR0147 imager Signed-off-by: Vladimir Barinov --- drivers/media/i2c/soc_camera/Kconfig | 6 + drivers/media/i2c/soc_camera/Makefile | 1 + drivers/media/i2c/soc_camera/ar0147.c | 714 ++++++++++++++++++++++++++ drivers/media/i2c/soc_camera/ar0147.h | 36 ++ drivers/media/i2c/soc_camera/ar0147_rev1.h | 607 ++++++++++++++++++++++ drivers/media/i2c/soc_camera/ar0147_rev2.h | 796 +++++++++++++++++++++++++++++ 6 files changed, 2160 insertions(+) create mode 100644 drivers/media/i2c/soc_camera/ar0147.c create mode 100644 drivers/media/i2c/soc_camera/ar0147.h create mode 100644 drivers/media/i2c/soc_camera/ar0147_rev1.h create mode 100644 drivers/media/i2c/soc_camera/ar0147_rev2.h diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig index 627d8d9..edff0b0 100644 --- a/drivers/media/i2c/soc_camera/Kconfig +++ b/drivers/media/i2c/soc_camera/Kconfig @@ -106,3 +106,9 @@ config SOC_CAMERA_IMX219 depends on SOC_CAMERA && I2C help This is Sony IMX219 driver + +config SOC_CAMERA_AR0147 + tristate "AR0147 camera support" + depends on SOC_CAMERA && I2C + help + This is an AR0147 imager glue diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile index 4aa5046..367674b 100644 --- a/drivers/media/i2c/soc_camera/Makefile +++ b/drivers/media/i2c/soc_camera/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov106xx.o obj-$(CONFIG_SOC_CAMERA_IMX219) += imx219.o obj-y += dummy.o +obj-$(CONFIG_SOC_CAMERA_AR0147) += ar0147.o diff --git a/drivers/media/i2c/soc_camera/ar0147.c b/drivers/media/i2c/soc_camera/ar0147.c new file mode 100644 index 0000000..cc7face --- /dev/null +++ b/drivers/media/i2c/soc_camera/ar0147.c @@ -0,0 +1,714 @@ +/* + * ON Semiconductor AR0147 sensor camera driver + * + * Copyright (C) 2019 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 "max9286.h" +#include "ar0147.h" + +#define AR0147_I2C_ADDR 0x10 + +#define AR0147_PID 0x3000 +#define AR0147_REV 0x31FE +#define AR0147_VERSION_REG 0x1D54 + +#define AR0147_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12 + +struct ar0147_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 max9286_addr; + int max9271_addr; + int ti9x4_addr; + int ti9x3_addr; + int port; + int gpio_resetb; + int gpio_fsin; + int hts; + int vts; + int frame_preamble; +}; + +static char *mode = "hdr"; +module_param(mode, charp, 0644); +MODULE_PARM_DESC(mode, " Modes linear,hdr,se,seplus (default: hdr)"); + +static inline struct ar0147_priv *to_ar0147(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct ar0147_priv, sd); +} + +static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) +{ + return &container_of(ctrl->handler, struct ar0147_priv, hdl)->sd; +} + +static void ar0147_s_port(struct i2c_client *client, int fwd_en) +{ + struct ar0147_priv *priv = to_ar0147(client); + int tmp_addr; + + if (priv->max9286_addr) { + tmp_addr = client->addr; + client->addr = priv->max9286_addr; /* Deserializer I2C address */ + reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */ + usleep_range(5000, 5500); /* wait 5ms */ + client->addr = tmp_addr; + }; +} + +static int ar0147_set_regs(struct i2c_client *client, const struct ar0147_reg **pregs) +{ + struct ar0147_priv *priv = to_ar0147(client); + const struct ar0147_reg *regs; + int i, j; + + for (j = 0; ; j++) { + regs = pregs[j]; + + if (!pregs[j]) + break; + + for (i = 0; ; i++) { + if (!regs[i].reg && !regs[i].val) + break; + + if (regs[i].reg == AR0147_DELAY) { + mdelay(regs[i].val); + continue; + } + /* cache timings */ + if (regs[i].reg == 0x300a) + priv->vts = regs[i].val; + if (regs[i].reg == 0x300c) + priv->hts = regs[i].val; + if (regs[i].reg == 0x31b0) + priv->frame_preamble = regs[i].val - 1; + + if (priv->ti9x4_addr) { + /* Override default (MAXIM serializer) table */ + /* PCLK=16Mhz/2 *48/1/8= 48Mhz - TI serializers */ + switch (regs[i].reg) { + case 0x302A: + reg16_write16(client, regs[i].reg, 8); // VT_PIX_CLK_DIV + continue; + case 0x302C: + reg16_write16(client, regs[i].reg, 1); // VT_SYS_CLK_DIV + continue; + case 0x302E: + reg16_write16(client, regs[i].reg, 2); // PRE_PLL_CLK_DIV + continue; + case 0x3030: + reg16_write16(client, regs[i].reg, 48); // PLL_MULTIPLIER + continue; + case 0x3036: + reg16_write16(client, regs[i].reg, 8); // OP_WORD_CLK_DIV + continue; + case 0x3038: + reg16_write16(client, regs[i].reg, 1); // OP_SYS_CLK_DIV + continue; + case 0x300A: + reg16_write16(client, regs[i].reg, AR0147_SENSOR_HEIGHT + 142); // FRAME_LENGTH_LINES_ + continue; + } + } + + reg16_write16(client, regs[i].reg, regs[i].val); + } + } + + return 0; +} + +static int ar0147_s_stream(struct v4l2_subdev *sd, int enable) +{ + return 0; +} + +static int ar0147_set_window(struct v4l2_subdev *sd) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ar0147_priv *priv = to_ar0147(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); + /* horiz crop end */ + reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1); + /* vert crop start */ + reg16_write16(client, 0x3002, priv->rect.top); + /* vert crop end */ + reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height - 1); + + return 0; +}; + +static int ar0147_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 ar0147_priv *priv = to_ar0147(client); + + if (format->pad) + return -EINVAL; + + mf->width = priv->rect.width; + mf->height = priv->rect.height; + mf->code = AR0147_MEDIA_BUS_FMT; + mf->colorspace = V4L2_COLORSPACE_SMPTE170M; + mf->field = V4L2_FIELD_NONE; + + return 0; +} + +static int ar0147_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 = AR0147_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 ar0147_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 = AR0147_MEDIA_BUS_FMT; + + return 0; +} + +static int ar0147_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ar0147_priv *priv = to_ar0147(client); + + memcpy(edid->edid, priv->id, 6); + + edid->edid[6] = 0xff; + edid->edid[7] = client->addr; + edid->edid[8] = AR0147_VERSION_REG >> 8; + edid->edid[9] = AR0147_VERSION_REG & 0xff; + + return 0; +} + +static int ar0147_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 ar0147_priv *priv = to_ar0147(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 > AR0147_MAX_WIDTH) || + (rect->top + rect->height > AR0147_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; + + ar0147_set_window(sd); + + return 0; +} + +static int ar0147_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 ar0147_priv *priv = to_ar0147(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 = AR0147_MAX_WIDTH; + sel->r.height = AR0147_MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = AR0147_MAX_WIDTH; + sel->r.height = AR0147_MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = priv->rect; + return 0; + default: + return -EINVAL; + } +} + +static int ar0147_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 ar0147_g_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + u16 val = 0; + + ret = reg16_read16(client, (u16)reg->reg, &val); + if (ret < 0) + return ret; + + reg->val = val; + reg->size = sizeof(u16); + + return 0; +} + +static int ar0147_s_register(struct v4l2_subdev *sd, + const struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + return reg16_write16(client, (u16)reg->reg, (u16)reg->val); +} +#endif + +static struct v4l2_subdev_core_ops ar0147_core_ops = { +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = ar0147_g_register, + .s_register = ar0147_s_register, +#endif +}; + +static int ar0147_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct v4l2_subdev *sd = to_sd(ctrl); + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ar0147_priv *priv = to_ar0147(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); + 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 |= 0x4000; + else + val &= ~0x4000; + ret |= reg16_write16(client, 0x3040, val); + break; + case V4L2_CID_VFLIP: + ret = reg16_read16(client, 0x3040, &val); + if (ctrl->val) + val |= 0x8000; + else + val &= ~0x8000; + 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 ar0147_ctrl_ops = { + .s_ctrl = ar0147_s_ctrl, +}; + +static struct v4l2_subdev_video_ops ar0147_video_ops = { + .s_stream = ar0147_s_stream, + .g_mbus_config = ar0147_g_mbus_config, +}; + +static const struct v4l2_subdev_pad_ops ar0147_subdev_pad_ops = { + .get_edid = ar0147_get_edid, + .enum_mbus_code = ar0147_enum_mbus_code, + .get_selection = ar0147_get_selection, + .set_selection = ar0147_set_selection, + .get_fmt = ar0147_get_fmt, + .set_fmt = ar0147_set_fmt, +}; + +static struct v4l2_subdev_ops ar0147_subdev_ops = { + .core = &ar0147_core_ops, + .video = &ar0147_video_ops, + .pad = &ar0147_subdev_pad_ops, +}; + +static void ar0147_otp_id_read(struct i2c_client *client) +{ + struct ar0147_priv *priv = to_ar0147(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 ssize_t ar0147_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 ar0147_priv *priv = to_ar0147(client); + + ar0147_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_ar0147, S_IRUGO, ar0147_otp_id_show, NULL); + +static int ar0147_initialize(struct i2c_client *client) +{ + struct ar0147_priv *priv = to_ar0147(client); + u16 val = 0; + u16 pid = 0, rev = 0; + int ret = 0; + int tmp_addr; + + ar0147_s_port(client, 1); + + /* check and show model ID */ + reg16_read16(client, AR0147_PID, &pid); + + if (pid != AR0147_VERSION_REG) { + dev_dbg(&client->dev, "Product ID error %x\n\n\n", pid); + ret = -ENODEV; + goto err; + } + + /* check revision */ + reg16_read16(client, AR0147_REV, &rev); + /* Read OTP IDs */ + ar0147_otp_id_read(client); + /* Program wizard registers */ + switch (rev & 0xf) { + case 0x1: + ar0147_set_regs(client, ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev1); + break; + case 0x2: + if (strcmp(mode, "hdr") == 0) + ar0147_set_regs(client, ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev2); + else if (strcmp(mode, "seplus") == 0) + ar0147_set_regs(client, ar0147_regs_seplus_mipi450mbps_12bit_30fps_rev2); + else + dev_err(&client->dev, "Unsupported mode %s\n", mode); + break; + default: + dev_err(&client->dev, "Unsupported chip revision\n"); + } + + tmp_addr = client->addr; + if (priv->max9271_addr) { + /* setup serializer HS generator */ + client->addr = priv->max9271_addr; /* Serializer I2C address */ + reg8_write(client, 0x4e, priv->frame_preamble >> 16); /* HS delay */ + reg8_write(client, 0x4f, (priv->frame_preamble >> 8) & 0xff); + reg8_write(client, 0x50, priv->frame_preamble & 0xff); + reg8_write(client, 0x54, AR0147_MAX_WIDTH >> 8); /* HS high period */ + reg8_write(client, 0x55, AR0147_MAX_WIDTH & 0xff); + reg8_write(client, 0x56, (priv->hts - AR0147_MAX_WIDTH) >> 8); /* HS low period */ + reg8_write(client, 0x57, (priv->hts - AR0147_MAX_WIDTH) & 0xff); + reg8_write(client, 0x58, priv->vts >> 8); /* HS count */ + reg8_write(client, 0x59, priv->vts & 0xff); + } + client->addr = tmp_addr; + + /* Enable stream */ + reg16_read16(client, 0x301a, &val); + val |= (1 << 2); + reg16_write16(client, 0x301a, val); + + dev_info(&client->dev, "ar0147 PID %x (rev %x), res %dx%d, mode=%s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n", + pid, rev, AR0147_MAX_WIDTH, AR0147_MAX_HEIGHT, mode, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); +err: + ar0147_s_port(client, 0); + + return ret; +} + +static int ar0147_parse_dt(struct device_node *np, struct ar0147_priv *priv) +{ + struct i2c_client *client = v4l2_get_subdevdata(&priv->sd); + int i; + struct device_node *endpoint = NULL, *rendpoint = NULL; + int tmp_addr = 0; + + for (i = 0; ; i++) { + endpoint = of_graph_get_next_endpoint(np, endpoint); + if (!endpoint) + break; + + rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0); + if (!rendpoint) + continue; + + if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) && + !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) && + !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) + break; + + if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && + !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") && + !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) && + !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) + break; + } + + of_node_put(endpoint); + + if (!priv->max9286_addr && !priv->ti9x4_addr) { + dev_err(&client->dev, "deserializer does not present for AR0147\n"); +// return -EINVAL; + } + + ar0147_s_port(client, 1); + + /* setup I2C translator address */ + tmp_addr = client->addr; + if (priv->max9286_addr) { + client->addr = priv->max9271_addr; /* Serializer I2C address */ + + reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */ + reg8_write(client, 0x0A, AR0147_I2C_ADDR << 1); /* Sensor native I2C address */ + usleep_range(2000, 2500); /* wait 2ms */ + }; + if (priv->ti9x4_addr) { + client->addr = priv->ti9x4_addr; /* Deserializer I2C address */ + + reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */ + usleep_range(2000, 2500); /* wait 2ms */ + reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */ + reg8_write(client, 0x5d, AR0147_I2C_ADDR << 1); /* Sensor native I2C address */ + + reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */ + } + client->addr = tmp_addr; + + mdelay(10); + + return 0; +} + +static int ar0147_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct ar0147_priv *priv; + int ret; + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + v4l2_i2c_subdev_init(&priv->sd, client, &ar0147_subdev_ops); + priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + + v4l2_ctrl_handler_init(&priv->hdl, 4); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 16, 1, 7); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops, + V4L2_CID_CONTRAST, 0, 16, 1, 7); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops, + V4L2_CID_SATURATION, 0, 7, 1, 2); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops, + V4L2_CID_HUE, 0, 23, 1, 12); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops, + V4L2_CID_GAMMA, -128, 128, 1, 0); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops, + V4L2_CID_SHARPNESS, 0, 10, 1, 3); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops, + V4L2_CID_AUTOGAIN, 0, 1, 1, 0); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops, + V4L2_CID_GAIN, 1, 0x7ff, 1, 0x200); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops, + V4L2_CID_ANALOGUE_GAIN, 1, 0xe, 1, 0x7); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops, + V4L2_CID_EXPOSURE, 1, 0x400, 1, 0x300); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(&priv->hdl, &ar0147_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 = ar0147_parse_dt(client->dev.of_node, priv); + if (ret) + goto cleanup; + + ret = ar0147_initialize(client); + if (ret < 0) + goto cleanup; + + priv->rect.left = 0; + priv->rect.top = 0; + priv->rect.width = AR0147_MAX_WIDTH; + priv->rect.height = AR0147_MAX_HEIGHT; + + ret = v4l2_async_register_subdev(&priv->sd); + if (ret) + goto cleanup; + + if (device_create_file(&client->dev, &dev_attr_otp_id_ar0147) != 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); +#ifdef CONFIG_SOC_CAMERA_AR0147 + v4l_err(client, "failed to probe @ 0x%02x (%s)\n", + client->addr, client->adapter->name); +#endif + return ret; +} + +static int ar0147_remove(struct i2c_client *client) +{ + struct ar0147_priv *priv = i2c_get_clientdata(client); + + device_remove_file(&client->dev, &dev_attr_otp_id_ar0147); + 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; +} + +#ifdef CONFIG_SOC_CAMERA_AR0147 +static const struct i2c_device_id ar0147_id[] = { + { "ar0147", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ar0147_id); + +static const struct of_device_id ar0147_of_ids[] = { + { .compatible = "onnn,ar0147", }, + { } +}; +MODULE_DEVICE_TABLE(of, ar0147_of_ids); + +static struct i2c_driver ar0147_i2c_driver = { + .driver = { + .name = "ar0147", + .of_match_table = ar0147_of_ids, + }, + .probe = ar0147_probe, + .remove = ar0147_remove, + .id_table = ar0147_id, +}; + +module_i2c_driver(ar0147_i2c_driver); + +MODULE_DESCRIPTION("SoC Camera driver for AR0147"); +MODULE_AUTHOR("Vladimir Barinov"); +MODULE_LICENSE("GPL"); +#endif diff --git a/drivers/media/i2c/soc_camera/ar0147.h b/drivers/media/i2c/soc_camera/ar0147.h new file mode 100644 index 0000000..0f7ce31 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ar0147.h @@ -0,0 +1,36 @@ +/* + * ON Semiconductor AR0147 sensor camera wizard 1344x968@30/BGGR/BT601/RAW12 + * + * Copyright (C) 2019 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 AR0147_DISPLAY_PATTERN_FIXED +//#define AR0147_DISPLAY_PATTERN_COLOR_BAR + +//#define AR0147_EMBEDDED_LINE + +#define AR0147_MAX_WIDTH 1344 +#define AR0147_MAX_HEIGHT 968 + +#define AR0147_DELAY 0xffff + +#define AR0147_SENSOR_WIDTH 1344 +#define AR0147_SENSOR_HEIGHT 968 + +#define AR0147_X_START ((AR0147_SENSOR_WIDTH - AR0147_MAX_WIDTH) / 2) +#define AR0147_Y_START ((AR0147_SENSOR_HEIGHT - AR0147_MAX_HEIGHT) / 2) +#define AR0147_X_END (AR0147_X_START + AR0147_MAX_WIDTH - 1) +#define AR0147_Y_END (AR0147_Y_START + AR0147_MAX_HEIGHT - 1) + +struct ar0147_reg { + u16 reg; + u16 val; +}; + +#include "ar0147_rev1.h" +#include "ar0147_rev2.h" diff --git a/drivers/media/i2c/soc_camera/ar0147_rev1.h b/drivers/media/i2c/soc_camera/ar0147_rev1.h new file mode 100644 index 0000000..430e265 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ar0147_rev1.h @@ -0,0 +1,607 @@ +/* + * ON Semiconductor AR0147 sensor camera wizard 1344x968@30/BGGR/BT601/RAW12 + * + * Copyright (C) 2019 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 AR0147_REV1_2_Recommended_Settings + +static const struct ar0147_reg ar0147_rev1_Reset[] = { +{0x301A, 0x0001}, // reset +{AR0147_DELAY, 100}, +{0x301A, 0x10D8}, // Stream off and setup parallel +{0x3070, 0x0001}, +{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) +#ifdef AR0147_DISPLAY_PATTERN_FIXED +{0x3070, 0x0001}, +#endif +{0x3072, 0x0fff}, // R +{0x3074, 0x0fff}, // G(GR row) +{0x3076, 0x0fff}, // B +{0x3078, 0x0fff}, // G(GB row) +#ifdef AR0147_DISPLAY_PATTERN_COLOR_BAR +{0x3070, 0x0002}, +#endif +{AR0147_DELAY, 250}, +{ } +}; /* Reset */ + +static const struct ar0147_reg ar0147_rev1_Sensor_Setup[] = { +/* Recommended_Settings */ +{0x30B0, 0x980C}, // DIGITAL_TEST +{0x3C08, 0x0100}, +{0x3C0C, 0x0518}, +{0x3092, 0x1A24}, +{0x30B4, 0x01C7}, // TEMPSENS0_CTRL_REG +{0x30B8, 0x0007}, // TEMPSENS1_CTRL_REG +{0x3364, 0x0680}, +{0x3372, 0x700F}, +{0x350C, 0x035A}, +{0x350E, 0x0514}, +{0x3518, 0x14FE}, +{0x351A, 0x6000}, +{0x3520, 0x08CC}, +{0x3522, 0xCC08}, +{0x3524, 0x0C00}, +{0x3526, 0x0F00}, +{0x3528, 0xFFFF}, +{0x352A, 0x0897}, +{0x352C, 0x0012}, +{0x352E, 0x00FF}, +{0x3530, 0xFF00}, +{0x3536, 0xFF24}, +{0x3538, 0x3CFF}, +{0x353A, 0x90E0}, +{0x353C, 0x3F00}, +{0x3540, 0xC63C}, +{0x3542, 0x3C3C}, +{0x3544, 0x3C46}, +{0x3546, 0x5458}, +{0x3548, 0x5800}, +{0x354A, 0x007F}, +{0x3556, 0x1010}, +{0x3F90, 0x0800}, // TEMPVSENS0_TMG_CTRL +{0x3F9A, 0x0000}, // TEMPVSENS0_BOOST_SAMP_CTRL +{0x3116, 0x0001}, // HDR_CONTROL3 +{0x3102, 0x60A0}, +{0x3104, 0x60A0}, +{0x3106, 0x60A0}, + +//Set REV1 Minimum Analog Gain to LCG 3.5X +{0x3366, 0xCCCC}, +{0x3362, 0x0000}, +#ifdef AR0147_REV1_REV1_2_Recommended_Settings +//Set REV1.2 Default Analog Gain to LCG 8X (minimum recommended) +{0x3366, 0xEEEE}, +#endif /* REV1.2_Recommended_Settings */ +/* Recommended_Settings */ + +/* Sequencer_Update */ +{0x2512, 0x8000}, +{0x2510, 0x0901}, +{0x2510, 0x3350}, +{0x2510, 0x2004}, +{0x2510, 0x1420}, +{0x2510, 0x1578}, +{0x2510, 0x087B}, +{0x2510, 0x24FF}, +{0x2510, 0x24FF}, +{0x2510, 0x24EA}, +{0x2510, 0x2410}, +{0x2510, 0x2224}, +{0x2510, 0x1015}, +{0x2510, 0x5813}, +{0x2510, 0x0214}, +{0x2510, 0x0024}, +{0x2510, 0xFF24}, +{0x2510, 0xFF24}, +{0x2510, 0xEA23}, +{0x2510, 0x2464}, +{0x2510, 0x7A24}, +{0x2510, 0x0405}, +{0x2510, 0x2C40}, +{0x2510, 0x2A54}, +{0x2510, 0x0AFF}, +{0x2510, 0x0A78}, +{0x2510, 0x4538}, +{0x2510, 0x5114}, +{0x2510, 0x4000}, +{0x2510, 0x0408}, +{0x2510, 0x0104}, +{0x2510, 0x0826}, +{0x2510, 0x5208}, +{0x2510, 0x1518}, +{0x2510, 0x13C8}, +{0x2510, 0x1002}, +{0x2510, 0x1016}, +{0x2510, 0x1181}, +{0x2510, 0x1189}, +{0x2510, 0x1056}, +{0x2510, 0x1210}, +{0x2510, 0x0902}, +{0x2510, 0x0D09}, +{0x2510, 0x0515}, +{0x2510, 0x8813}, +{0x2510, 0x8809}, +{0x2510, 0x3811}, +{0x2510, 0x9911}, +{0x2510, 0xD909}, +{0x2510, 0x1E12}, +{0x2510, 0x1410}, +{0x2510, 0xD609}, +{0x2510, 0x0112}, +{0x2510, 0x1012}, +{0x2510, 0x1212}, +{0x2510, 0x1011}, +{0x2510, 0xDD11}, +{0x2510, 0xD909}, +{0x2510, 0x0114}, +{0x2510, 0x4109}, +{0x2510, 0x0410}, +{0x2510, 0x5608}, +{0x2510, 0x11DB}, +{0x2510, 0x0903}, +{0x2510, 0x11FB}, +{0x2510, 0x11BB}, +{0x2510, 0x121A}, +{0x2510, 0x1210}, +{0x2510, 0x0812}, +{0x2510, 0x5010}, +{0x2510, 0x7610}, +{0x2510, 0xE614}, +{0x2510, 0x6109}, +{0x2510, 0x0612}, +{0x2510, 0x4012}, +{0x2510, 0x6009}, +{0x2510, 0x1C14}, +{0x2510, 0x6009}, +{0x2510, 0x0C0B}, +{0x2510, 0x0905}, +{0x2510, 0x15C8}, +{0x2510, 0x13C8}, +{0x2510, 0x0810}, +{0x2510, 0x6609}, +{0x2510, 0x0B15}, +{0x2510, 0x8813}, +{0x2510, 0x8809}, +{0x2510, 0x130C}, +{0x2510, 0x1440}, +{0x2510, 0x0903}, +{0x2510, 0x10E6}, +{0x2510, 0x11FB}, +{0x2510, 0x1262}, +{0x2510, 0x1260}, +{0x2510, 0x11FF}, +{0x2510, 0x11FB}, +{0x2510, 0x1441}, +{0x2510, 0x0902}, +{0x2510, 0x1066}, +{0x2510, 0x0912}, +{0x2510, 0x11BB}, +{0x2510, 0x1263}, +{0x2510, 0x1260}, +{0x2510, 0x1400}, +{0x2510, 0x1518}, +{0x2510, 0x11B8}, +{0x2510, 0x12A0}, +{0x2510, 0x1200}, +{0x2510, 0x1026}, +{0x2510, 0x1000}, +{0x2510, 0x1300}, +{0x2510, 0x1100}, +{0x2510, 0x3053}, +{0x2510, 0x4211}, +{0x2510, 0x0010}, +{0x2510, 0x0210}, +{0x2510, 0x1611}, +{0x2510, 0x0111}, +{0x2510, 0x0910}, +{0x2510, 0x5612}, +{0x2510, 0x100D}, +{0x2510, 0x0905}, +{0x2510, 0x1441}, +{0x2510, 0x0907}, +{0x2510, 0x1440}, +{0x2510, 0x0901}, +{0x2510, 0x15C8}, +{0x2510, 0x13C8}, +{0x2510, 0x091A}, +{0x2510, 0x1149}, +{0x2510, 0x0908}, +{0x2510, 0x1588}, +{0x2510, 0x1388}, +{0x2510, 0x091B}, +{0x2510, 0x1159}, +{0x2510, 0x090B}, +{0x2510, 0x1214}, +{0x2510, 0x0901}, +{0x2510, 0x1210}, +{0x2510, 0x10D6}, +{0x2510, 0x1212}, +{0x2510, 0x1210}, +{0x2510, 0x115D}, +{0x2510, 0x1159}, +{0x2510, 0x1056}, +{0x2510, 0x0903}, +{0x2510, 0x115B}, +{0x2510, 0x0814}, +{0x2510, 0x4109}, +{0x2510, 0x0114}, +{0x2510, 0x4009}, +{0x2510, 0x0C11}, +{0x2510, 0x7B11}, +{0x2510, 0x3B12}, +{0x2510, 0x1A12}, +{0x2510, 0x1009}, +{0x2510, 0x0112}, +{0x2510, 0x5010}, +{0x2510, 0xF610}, +{0x2510, 0xE614}, +{0x2510, 0x6009}, +{0x2510, 0x0115}, +{0x2510, 0xA813}, +{0x2510, 0xA812}, +{0x2510, 0x4012}, +{0x2510, 0x6009}, +{0x2510, 0x2415}, +{0x2510, 0x8809}, +{0x2510, 0x0110}, +{0x2510, 0x660B}, +{0x2510, 0x0813}, +{0x2510, 0x8809}, +{0x2510, 0x250C}, +{0x2510, 0x0902}, +{0x2510, 0x1440}, +{0x2510, 0x0907}, +{0x2510, 0x10E6}, +{0x2510, 0x1262}, +{0x2510, 0x1260}, +{0x2510, 0x117F}, +{0x2510, 0x117B}, +{0x2510, 0x1066}, +{0x2510, 0x0906}, +{0x2510, 0x1441}, +{0x2510, 0x0901}, +{0x2510, 0x1440}, +{0x2510, 0x090D}, +{0x2510, 0x113B}, +{0x2510, 0x1263}, +{0x2510, 0x1260}, +{0x2510, 0x1400}, +{0x2510, 0x1518}, +{0x2510, 0x1138}, +{0x2510, 0x12A0}, +{0x2510, 0x1200}, +{0x2510, 0x1026}, +{0x2510, 0x1000}, +{0x2510, 0x1300}, +{0x2510, 0x1100}, +{0x2510, 0x437A}, +{0x2510, 0x0605}, +{0x2510, 0x0741}, +{0x2510, 0x0E02}, +{0x2510, 0x3750}, +{0x2510, 0x2C44}, +{0x2510, 0x3714}, +{0x2510, 0x4000}, +{0x2510, 0x0408}, +{0x2510, 0x0104}, +{0x2510, 0x0811}, +{0x2510, 0x0010}, +{0x2510, 0x0210}, +{0x2510, 0x1611}, +{0x2510, 0x0111}, +{0x2510, 0x0910}, +{0x2510, 0x5612}, +{0x2510, 0x100D}, +{0x2510, 0x0906}, +{0x2510, 0x1441}, +{0x2510, 0x0907}, +{0x2510, 0x1440}, +{0x2510, 0x0901}, +{0x2510, 0x1588}, +{0x2510, 0x1388}, +{0x2510, 0x0921}, +{0x2510, 0x1149}, +{0x2510, 0x0908}, +{0x2510, 0x1588}, +{0x2510, 0x1388}, +{0x2510, 0x091B}, +{0x2510, 0x1159}, +{0x2510, 0x090B}, +{0x2510, 0x1214}, +{0x2510, 0x0901}, +{0x2510, 0x1210}, +{0x2510, 0x10D6}, +{0x2510, 0x1212}, +{0x2510, 0x1210}, +{0x2510, 0x115D}, +{0x2510, 0x1159}, +{0x2510, 0x1056}, +{0x2510, 0x0903}, +{0x2510, 0x115B}, +{0x2510, 0x0814}, +{0x2510, 0x4109}, +{0x2510, 0x0114}, +{0x2510, 0x4009}, +{0x2510, 0x0C11}, +{0x2510, 0x7B11}, +{0x2510, 0x3B12}, +{0x2510, 0x1A12}, +{0x2510, 0x1009}, +{0x2510, 0x0112}, +{0x2510, 0x5010}, +{0x2510, 0xF610}, +{0x2510, 0xE614}, +{0x2510, 0x6009}, +{0x2510, 0x0115}, +{0x2510, 0xA813}, +{0x2510, 0xA812}, +{0x2510, 0x4012}, +{0x2510, 0x6009}, +{0x2510, 0x2415}, +{0x2510, 0x8809}, +{0x2510, 0x0110}, +{0x2510, 0x660B}, +{0x2510, 0x0813}, +{0x2510, 0x8809}, +{0x2510, 0x250C}, +{0x2510, 0x0902}, +{0x2510, 0x1440}, +{0x2510, 0x0907}, +{0x2510, 0x10E6}, +{0x2510, 0x1262}, +{0x2510, 0x1260}, +{0x2510, 0x117F}, +{0x2510, 0x117B}, +{0x2510, 0x1066}, +{0x2510, 0x0906}, +{0x2510, 0x1441}, +{0x2510, 0x0901}, +{0x2510, 0x1440}, +{0x2510, 0x090D}, +{0x2510, 0x113B}, +{0x2510, 0x1263}, +{0x2510, 0x1260}, +{0x2510, 0x1440}, +{0x2510, 0x1598}, +{0x2510, 0x1139}, +{0x2510, 0x12A0}, +{0x2510, 0x1200}, +{0x2510, 0x1066}, +{0x2510, 0x1066}, +{0x2510, 0x1380}, +{0x2510, 0x1109}, +{0x2510, 0x0E02}, +{0x2510, 0x0920}, +{0x2510, 0x3708}, +{0x2510, 0x0015}, +{0x2510, 0x9813}, +{0x2510, 0x9810}, +{0x2510, 0x6610}, +{0x2510, 0x6611}, +{0x2510, 0x8911}, +{0x2510, 0x8910}, +{0x2510, 0x5612}, +{0x2510, 0x1009}, +{0x2510, 0x020D}, +{0x2510, 0x0905}, +{0x2510, 0x15A8}, +{0x2510, 0x13A8}, +{0x2510, 0x0934}, +{0x2510, 0x1588}, +{0x2510, 0x1388}, +{0x2510, 0x1199}, +{0x2510, 0x11D9}, +{0x2510, 0x091E}, +{0x2510, 0x1214}, +{0x2510, 0x10D6}, +{0x2510, 0x0901}, +{0x2510, 0x1210}, +{0x2510, 0x1212}, +{0x2510, 0x1210}, +{0x2510, 0x11DD}, +{0x2510, 0x11D9}, +{0x2510, 0x0901}, +{0x2510, 0x1441}, +{0x2510, 0x0904}, +{0x2510, 0x1056}, +{0x2510, 0x0811}, +{0x2510, 0xDB09}, +{0x2510, 0x0311}, +{0x2510, 0xFB11}, +{0x2510, 0xBB12}, +{0x2510, 0x1A12}, +{0x2510, 0x1008}, +{0x2510, 0x1250}, +{0x2510, 0x1076}, +{0x2510, 0x10E6}, +{0x2510, 0x1461}, +{0x2510, 0x0906}, +{0x2510, 0x1240}, +{0x2510, 0x1260}, +{0x2510, 0x091C}, +{0x2510, 0x1460}, +{0x2510, 0x090C}, +{0x2510, 0x0B09}, +{0x2510, 0x0515}, +{0x2510, 0xC813}, +{0x2510, 0xC808}, +{0x2510, 0x1066}, +{0x2510, 0x090B}, +{0x2510, 0x1588}, +{0x2510, 0x1388}, +{0x2510, 0x0913}, +{0x2510, 0x0C14}, +{0x2510, 0x4009}, +{0x2510, 0x0310}, +{0x2510, 0xE611}, +{0x2510, 0xFB12}, +{0x2510, 0x6212}, +{0x2510, 0x6011}, +{0x2510, 0xFF11}, +{0x2510, 0xFB14}, +{0x2510, 0x4109}, +{0x2510, 0x0210}, +{0x2510, 0x6609}, +{0x2510, 0x1211}, +{0x2510, 0xBB12}, +{0x2510, 0x6312}, +{0x2510, 0x6014}, +{0x2510, 0x0015}, +{0x2510, 0x1811}, +{0x2510, 0xB812}, +{0x2510, 0xA012}, +{0x2510, 0x0010}, +{0x2510, 0x2610}, +{0x2510, 0x0013}, +{0x2510, 0x0011}, +{0x2510, 0x007A}, +{0x2510, 0x0605}, +{0x2510, 0x0807}, +{0x2510, 0x0E02}, +{0x2510, 0x3709}, +{0x2510, 0x0655}, +{0x2510, 0x2CFE}, +{0x2510, 0x12FE}, +{0x2510, 0x062C}, + +{0x1010, 0x0115}, +{0x3236, 0x00b3}, +{0x32e6, 0x009a}, +{0x322e, 0x258c}, +/* Sequencer_Update */ + +{0x32D0, 0x3A02}, +{0x32D2, 0x3508}, +{0x32D4, 0x3702}, +{0x32D6, 0x3C04}, +{0x32DC, 0x370A}, +{ } +}; /* Sensor_Setup */ + +static const struct ar0147_reg ar0147_rev1_Serial_12_bit_Timing_Setup[] = { +#if 0 +/* PCLK=24Mhz/3 *50 /1/8 = 50MHz */ +{0x302A, 8}, // VT_PIX_CLK_DIV +{0x302C, 1}, // VT_SYS_CLK_DIV +{0x302E, 3}, // PRE_PLL_CLK_DIV +{0x3030, 50}, // PLL_MULTIPLIER +{0x3036, 8}, // OP_WORD_CLK_DIV +{0x3038, 1}, // OP_SYS_CLK_DIV +#else +/* PCLK=24Mhz/4 *75 /1/9 = 50MHz */ +{0x302A, 9}, // VT_PIX_CLK_DIV +{0x302C, 1}, // VT_SYS_CLK_DIV +{0x302E, 4}, // PRE_PLL_CLK_DIV +{0x3030, 75}, // PLL_MULTIPLIER +{0x3036, 12}, // OP_WORD_CLK_DIV +{0x3038, 1}, // OP_SYS_CLK_DIV +#endif +{0x30B0, 0x980C}, // DIGITAL_TEST +{0x31DC, 0x1FB0}, +{ } +}; /* Serial_12_bit_Timing_Setup */ + +static const struct ar0147_reg ar0147_rev1_Readout_Mode_Configuration[] = { +{0x30A2, 0x0001}, // X_ODD_INC_ +{0x30A6, 0x0001}, // Y_ODD_INC_ +{0x3040, 0x0000}, // READ_MODE +{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp +{0x3044, 0x0400}, // DARK_CONTROL +{0x3064, 0x0000}, // SMIA_TEST: disable emb data and stats +{0x33E0, 0x0C80}, // TEST_ASIL_ROWS +{0x3180, 0x0080}, // RESERVED_MFR_3180 +{0x33E4, 0x0080}, // RESERVED_MFR_33E4 +#ifdef AR0147_EMBEDDED_LINE +{0x3064, 0x0180}, // SMIA_TEST: enable emb data and stats +#endif /* HDR_Readout_Mode_Configuration */ +{ } +}; /* Readout_Mode_Configuration */ + +static const struct ar0147_reg ar0147_rev1_Full_Res_FOV[] = { +{0x31B0, 0x0056}, // FRAME_PREAMBLE +{0x31B2, 0x0045}, // LINE_PREAMBLE +{0x3004, AR0147_X_START}, // X_ADDR_START_ +{0x3008, AR0147_X_END}, // X_ADDR_END_ +{0x3002, AR0147_Y_START}, // Y_ADDR_START_ +{0x3006, AR0147_Y_END}, // Y_ADDR_END_ +{0x3400, 0x10}, +{0x3402, (0x8000 & 0) | AR0147_MAX_WIDTH}, // X_OUTPUT_CONTROL +{0x3404, (0x8000 & 0) | AR0147_MAX_HEIGHT}, // Y_OUTPUT_CONTROL +{ } +}; /* Full_Res_FOV */ + +static const struct ar0147_reg ar0147_rev1_3exp_30FPS_Timing_and_Exposure[] = { +{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp +{0x30BA, 0x1002}, // DIGITAL_CTRL: 3exp max +/* Row and Pixel Timing */ +{0x300C, AR0147_SENSOR_WIDTH + 52}, // LINE_LENGTH_PCK_ (1396) +{0x300A, AR0147_SENSOR_HEIGHT + 226}, // FRAME_LENGTH_LINES_ +{0x3042, 0x0000}, // EXTRA_DELAY +/* Exposure Settings */ +{0x3238, 0x0222}, // EXPOSURE_RATIO +{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_ + +{0x3014, 1550}, // FINE_INTEGRATION_TIME_ +{0x321E, 1550}, // FINE_INTEGRATION_TIME2 +{0x3222, 1550}, // FINE_INTEGRATION_TIME3 + +{0x30B0, 0x980C}, // DIGITAL_TEST (MIPI ...) +{0x32EA, 0x3C0E}, +{0x32EC, 0x72A1}, +{0x3C06, 0x083C}, +{0x3C08, 0x0100}, +{ } +}; /* 3exp_30FPS_Timing_and_Exposure */ + +static const struct ar0147_reg ar0147_rev1_Serial_HDR_12_bit_Output[] = { +{0x31D0, 0x0001}, // COMPANDING +{0x31AE, 0x0304}, // SERIAL_FORMAT: HISPI 4-lanes +{0x31AC, 0x140C}, // DATA_FORMAT_BITS: ADC20, RAW12 +//{0x301A, 0x0118}, // RESET_REGISTER +{0x301A, 0x0018}, // RESET_REGISTER +{ } +}; /* Serial_HDR_12_bit_Output */ + +static const struct ar0147_reg ar0147_rev1_MIPI_12_bit_450MBps_Settings[] = { +{0x31AE, 0x0204}, // SERIAL_FORMAT: MIPI 4-lanes +{0x3342, 0x122C}, // exposure1 DT=0x2c emb=0x12 +{0x3346, 0x122C}, // exposure2 DT=0x2c emb=0x12 +{0x334A, 0x122C}, // exposure3 DT=0x2c emb=0x12 +{0x334E, 0x122C}, // exposure4 DT=0x2c emb=0x12 +{0x3344, 0x0011}, // exposure1 VC=0 +{0x3348, 0x0111}, // exposure1 VC=1 +{0x334C, 0x0211}, // exposure1 VC=2 +{0x3350, 0x0311}, // exposure1 VC=3 +{0x31B0, 0x41}, // frame_preamble +{0x31B2, 0x2e}, // line_preamble + +{0x31B4, 0x2185}, +{0x31B6, 0x1105}, +{0x31B8, 0x2047}, +{0x31BA, 0x105}, +{0x31BC, 0x704}, +{ } +}; /* MIPI_12_bit_450MBps_Settings */ + +/* 3 Exp HDR, Full Resolution, MIPI 450MBps 4 lane 12-bit, 30FPS, XMCLK=24MHz */ +static const struct ar0147_reg *ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev1[] = { + ar0147_rev1_Reset, + ar0147_rev1_Sensor_Setup, + ar0147_rev1_Serial_12_bit_Timing_Setup, + ar0147_rev1_Readout_Mode_Configuration, + ar0147_rev1_Full_Res_FOV, + ar0147_rev1_3exp_30FPS_Timing_and_Exposure, + ar0147_rev1_Serial_HDR_12_bit_Output, + ar0147_rev1_MIPI_12_bit_450MBps_Settings, + NULL +}; diff --git a/drivers/media/i2c/soc_camera/ar0147_rev2.h b/drivers/media/i2c/soc_camera/ar0147_rev2.h new file mode 100644 index 0000000..e5ccb8f --- /dev/null +++ b/drivers/media/i2c/soc_camera/ar0147_rev2.h @@ -0,0 +1,796 @@ +/* + * ON Semiconductor AR0147 sensor camera wizard 1344x968@30/BGGR/BT601/RAW12 + * + * Copyright (C) 2019 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 ar0147_reg ar0147_rev2_Reset[] = { +{0x301A, 0x0001}, // reset +{AR0147_DELAY, 100}, +{0x301A, 0x10D8}, // Stream off and setup parallel +{0x3070, 0x0001}, +{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) +#ifdef AR0147_DISPLAY_PATTERN_FIXED +{0x3070, 0x0001}, +#endif +{0x3072, 0x0fff}, // R +{0x3074, 0x0fff}, // G(GR row) +{0x3076, 0x0fff}, // B +{0x3078, 0x0fff}, // G(GB row) +#ifdef AR0147_DISPLAY_PATTERN_COLOR_BAR +{0x3070, 0x0002}, +#endif +{AR0147_DELAY, 250}, +{ } +}; /* Reset */ + +static const struct ar0147_reg ar0147_rev2_Sensor_Setup[] = { +/* Recommended_Settings */ +{0x30B0, 0x980E}, // DIGITAL_TEST +{0x3C08, 0x0000}, +{0x3C0C, 0x0518}, // DELAY_BUFFER_LLPCK_RD_WR_OVERLAP +{0x3092, 0x1A24}, +{0x30B4, 0x01C7}, // TEMPSENS0_CTRL_REG +{0x3372, 0x700F}, // DBLC_FS0_CONTROL +{0x33EE, 0x0344}, +{0x350C, 0x035A}, +{0x350E, 0x0514}, +{0x3518, 0x14FE}, +{0x351A, 0x6000}, +{0x3520, 0x08CC}, +{0x3522, 0xCC08}, +{0x3524, 0x0C00}, +{0x3526, 0x0F00}, +{0x3528, 0xEEEE}, +{0x352A, 0x089F}, +{0x352C, 0x0012}, +{0x352E, 0x00EE}, +{0x3530, 0xEE00}, +{0x3536, 0xFF20}, +{0x3538, 0x3CFF}, +{0x353A, 0x9000}, +{0x353C, 0x7F00}, +{0x3540, 0xC62C}, +{0x3542, 0x4B4B}, +{0x3544, 0x3C46}, +{0x3546, 0x5A5A}, +{0x3548, 0x6400}, +{0x354A, 0x007F}, +{0x3556, 0x1010}, +{0x3566, 0x7328}, +{0x3F90, 0x0800}, // TEMPVSENS0_TMG_CTRL +{0x3510, 0x011F}, +{0x353E, 0x801F}, +{0x3F9A, 0x0001}, // TEMPVSENS0_BOOST_SAMP_CTRL +{0x3116, 0x0001}, // HDR_CONTROL3 +{0x3102, 0x60A0}, +{0x3104, 0x60A0}, +{0x3106, 0x60A0}, +{0x3362, 0x0000}, // DC_GAIN +{0x3366, 0xCCCC}, // ANALOG_GAIN + +// Writes to bitfield R0x3552[5:4]. +// Be sure not to overwrite the other bitfields in this register. +{0x3552, 0x0FB0}, +/* Recommended_Settings */ + +/* Sequencer_Update */ +{0x2512, 0x8000}, +{0x2510, 0x0901}, +{0x2510, 0x3350}, +{0x2510, 0x2004}, +{0x2510, 0x1420}, +{0x2510, 0x1578}, +{0x2510, 0x087B}, +{0x2510, 0x24FF}, +{0x2510, 0x24FF}, +{0x2510, 0x24EA}, +{0x2510, 0x2410}, +{0x2510, 0x2224}, +{0x2510, 0x1015}, +{0x2510, 0xD813}, +{0x2510, 0x0214}, +{0x2510, 0x0024}, +{0x2510, 0xFF24}, +{0x2510, 0xFF24}, +{0x2510, 0xEA23}, +{0x2510, 0x2464}, +{0x2510, 0x7A24}, +{0x2510, 0x0405}, +{0x2510, 0x2C40}, +{0x2510, 0x0AFF}, +{0x2510, 0x0A78}, +{0x2510, 0x3851}, +{0x2510, 0x2A54}, +{0x2510, 0x1440}, +{0x2510, 0x0015}, +{0x2510, 0x0804}, +{0x2510, 0x0801}, +{0x2510, 0x0408}, +{0x2510, 0x2652}, +{0x2510, 0x0813}, +{0x2510, 0xC810}, +{0x2510, 0x0210}, +{0x2510, 0x1611}, +{0x2510, 0x8111}, +{0x2510, 0x8910}, +{0x2510, 0x5612}, +{0x2510, 0x1009}, +{0x2510, 0x020D}, +{0x2510, 0x0903}, +{0x2510, 0x1402}, +{0x2510, 0x15A8}, +{0x2510, 0x1388}, +{0x2510, 0x0938}, +{0x2510, 0x1199}, +{0x2510, 0x11D9}, +{0x2510, 0x091E}, +{0x2510, 0x1214}, +{0x2510, 0x10D6}, +{0x2510, 0x0901}, +{0x2510, 0x1210}, +{0x2510, 0x1212}, +{0x2510, 0x1210}, +{0x2510, 0x11DD}, +{0x2510, 0x11D9}, +{0x2510, 0x0901}, +{0x2510, 0x1441}, +{0x2510, 0x0904}, +{0x2510, 0x1056}, +{0x2510, 0x0811}, +{0x2510, 0xDB09}, +{0x2510, 0x0311}, +{0x2510, 0xFB11}, +{0x2510, 0xBB12}, +{0x2510, 0x1A12}, +{0x2510, 0x1008}, +{0x2510, 0x1250}, +{0x2510, 0x0B10}, +{0x2510, 0x7610}, +{0x2510, 0xE614}, +{0x2510, 0x6109}, +{0x2510, 0x0612}, +{0x2510, 0x4012}, +{0x2510, 0x6009}, +{0x2510, 0x1C14}, +{0x2510, 0x6009}, +{0x2510, 0x1215}, +{0x2510, 0xC813}, +{0x2510, 0xC808}, +{0x2510, 0x1066}, +{0x2510, 0x090B}, +{0x2510, 0x1588}, +{0x2510, 0x1388}, +{0x2510, 0x0913}, +{0x2510, 0x0C14}, +{0x2510, 0x4009}, +{0x2510, 0x0310}, +{0x2510, 0xE611}, +{0x2510, 0xFB12}, +{0x2510, 0x6212}, +{0x2510, 0x6011}, +{0x2510, 0xFF11}, +{0x2510, 0xFB14}, +{0x2510, 0x4109}, +{0x2510, 0x0210}, +{0x2510, 0x6609}, +{0x2510, 0x1211}, +{0x2510, 0xBB12}, +{0x2510, 0x6312}, +{0x2510, 0x6014}, +{0x2510, 0x0015}, +{0x2510, 0x1811}, +{0x2510, 0xB812}, +{0x2510, 0xA012}, +{0x2510, 0x0010}, +{0x2510, 0x2610}, +{0x2510, 0x0013}, +{0x2510, 0x0011}, +{0x2510, 0x0030}, +{0x2510, 0x5342}, +{0x2510, 0x1100}, +{0x2510, 0x1002}, +{0x2510, 0x1016}, +{0x2510, 0x1101}, +{0x2510, 0x1109}, +{0x2510, 0x1056}, +{0x2510, 0x1210}, +{0x2510, 0x0D09}, +{0x2510, 0x0314}, +{0x2510, 0x0214}, +{0x2510, 0x4309}, +{0x2510, 0x0514}, +{0x2510, 0x4009}, +{0x2510, 0x0115}, +{0x2510, 0xC813}, +{0x2510, 0xC809}, +{0x2510, 0x1A11}, +{0x2510, 0x4909}, +{0x2510, 0x0815}, +{0x2510, 0x8813}, +{0x2510, 0x8809}, +{0x2510, 0x1B11}, +{0x2510, 0x5909}, +{0x2510, 0x0B12}, +{0x2510, 0x1409}, +{0x2510, 0x0112}, +{0x2510, 0x1010}, +{0x2510, 0xD612}, +{0x2510, 0x1212}, +{0x2510, 0x1011}, +{0x2510, 0x5D11}, +{0x2510, 0x5910}, +{0x2510, 0x5609}, +{0x2510, 0x0311}, +{0x2510, 0x5B08}, +{0x2510, 0x1441}, +{0x2510, 0x0901}, +{0x2510, 0x1440}, +{0x2510, 0x090C}, +{0x2510, 0x117B}, +{0x2510, 0x113B}, +{0x2510, 0x121A}, +{0x2510, 0x1210}, +{0x2510, 0x0901}, +{0x2510, 0x1250}, +{0x2510, 0x10F6}, +{0x2510, 0x10E6}, +{0x2510, 0x1460}, +{0x2510, 0x0901}, +{0x2510, 0x15A8}, +{0x2510, 0x13A8}, +{0x2510, 0x1240}, +{0x2510, 0x1260}, +{0x2510, 0x0924}, +{0x2510, 0x1588}, +{0x2510, 0x0901}, +{0x2510, 0x1066}, +{0x2510, 0x0B08}, +{0x2510, 0x1388}, +{0x2510, 0x0925}, +{0x2510, 0x0C09}, +{0x2510, 0x0214}, +{0x2510, 0x4009}, +{0x2510, 0x0710}, +{0x2510, 0xE612}, +{0x2510, 0x6212}, +{0x2510, 0x6011}, +{0x2510, 0x7F11}, +{0x2510, 0x7B10}, +{0x2510, 0x6609}, +{0x2510, 0x0614}, +{0x2510, 0x4109}, +{0x2510, 0x0114}, +{0x2510, 0x4009}, +{0x2510, 0x0D11}, +{0x2510, 0x3B12}, +{0x2510, 0x6312}, +{0x2510, 0x6014}, +{0x2510, 0x0015}, +{0x2510, 0x1811}, +{0x2510, 0x3812}, +{0x2510, 0xA012}, +{0x2510, 0x0010}, +{0x2510, 0x2610}, +{0x2510, 0x0013}, +{0x2510, 0x0011}, +{0x2510, 0x0043}, +{0x2510, 0x7A06}, +{0x2510, 0x0507}, +{0x2510, 0x410E}, +{0x2510, 0x0237}, +{0x2510, 0x502C}, +{0x2510, 0x4414}, +{0x2510, 0x4000}, +{0x2510, 0x1508}, +{0x2510, 0x0408}, +{0x2510, 0x0104}, +{0x2510, 0x0826}, +{0x2510, 0x5508}, +{0x2510, 0x13C8}, +{0x2510, 0x1002}, +{0x2510, 0x1016}, +{0x2510, 0x1181}, +{0x2510, 0x1189}, +{0x2510, 0x1056}, +{0x2510, 0x1210}, +{0x2510, 0x0902}, +{0x2510, 0x0D09}, +{0x2510, 0x0314}, +{0x2510, 0x0215}, +{0x2510, 0xA813}, +{0x2510, 0xA814}, +{0x2510, 0x0309}, +{0x2510, 0x0614}, +{0x2510, 0x0209}, +{0x2510, 0x1F15}, +{0x2510, 0x8813}, +{0x2510, 0x8809}, +{0x2510, 0x0B11}, +{0x2510, 0x9911}, +{0x2510, 0xD909}, +{0x2510, 0x1E12}, +{0x2510, 0x1409}, +{0x2510, 0x0312}, +{0x2510, 0x1012}, +{0x2510, 0x1212}, +{0x2510, 0x1011}, +{0x2510, 0xDD11}, +{0x2510, 0xD909}, +{0x2510, 0x0114}, +{0x2510, 0x4009}, +{0x2510, 0x0711}, +{0x2510, 0xDB09}, +{0x2510, 0x0311}, +{0x2510, 0xFB11}, +{0x2510, 0xBB12}, +{0x2510, 0x1A12}, +{0x2510, 0x1009}, +{0x2510, 0x0112}, +{0x2510, 0x500B}, +{0x2510, 0x1076}, +{0x2510, 0x1066}, +{0x2510, 0x1460}, +{0x2510, 0x0901}, +{0x2510, 0x15C8}, +{0x2510, 0x0901}, +{0x2510, 0x1240}, +{0x2510, 0x1260}, +{0x2510, 0x0901}, +{0x2510, 0x13C8}, +{0x2510, 0x0956}, +{0x2510, 0x1588}, +{0x2510, 0x0901}, +{0x2510, 0x0C14}, +{0x2510, 0x4009}, +{0x2510, 0x0511}, +{0x2510, 0xFB12}, +{0x2510, 0x6212}, +{0x2510, 0x6011}, +{0x2510, 0xFF11}, +{0x2510, 0xFB09}, +{0x2510, 0x1911}, +{0x2510, 0xBB12}, +{0x2510, 0x6312}, +{0x2510, 0x6014}, +{0x2510, 0x0015}, +{0x2510, 0x1811}, +{0x2510, 0xB812}, +{0x2510, 0xA012}, +{0x2510, 0x0010}, +{0x2510, 0x2610}, +{0x2510, 0x0013}, +{0x2510, 0x0011}, +{0x2510, 0x0030}, +{0x2510, 0x5345}, +{0x2510, 0x1444}, +{0x2510, 0x1002}, +{0x2510, 0x1016}, +{0x2510, 0x1101}, +{0x2510, 0x1109}, +{0x2510, 0x1056}, +{0x2510, 0x1210}, +{0x2510, 0x0D09}, +{0x2510, 0x0314}, +{0x2510, 0x0614}, +{0x2510, 0x4709}, +{0x2510, 0x0514}, +{0x2510, 0x4409}, +{0x2510, 0x0115}, +{0x2510, 0x9813}, +{0x2510, 0x9809}, +{0x2510, 0x1A11}, +{0x2510, 0x4909}, +{0x2510, 0x0815}, +{0x2510, 0x8813}, +{0x2510, 0x8809}, +{0x2510, 0x1B11}, +{0x2510, 0x5909}, +{0x2510, 0x0B12}, +{0x2510, 0x1409}, +{0x2510, 0x0112}, +{0x2510, 0x1009}, +{0x2510, 0x0112}, +{0x2510, 0x1212}, +{0x2510, 0x1011}, +{0x2510, 0x5D11}, +{0x2510, 0x5909}, +{0x2510, 0x0511}, +{0x2510, 0x5B09}, +{0x2510, 0x1311}, +{0x2510, 0x7B11}, +{0x2510, 0x3B12}, +{0x2510, 0x1A12}, +{0x2510, 0x1009}, +{0x2510, 0x0112}, +{0x2510, 0x5010}, +{0x2510, 0x7610}, +{0x2510, 0x6614}, +{0x2510, 0x6409}, +{0x2510, 0x0115}, +{0x2510, 0xA813}, +{0x2510, 0xA812}, +{0x2510, 0x4012}, +{0x2510, 0x6009}, +{0x2510, 0x2015}, +{0x2510, 0x8809}, +{0x2510, 0x020B}, +{0x2510, 0x0901}, +{0x2510, 0x1388}, +{0x2510, 0x0925}, +{0x2510, 0x0C09}, +{0x2510, 0x0214}, +{0x2510, 0x4409}, +{0x2510, 0x0912}, +{0x2510, 0x6212}, +{0x2510, 0x6011}, +{0x2510, 0x7F11}, +{0x2510, 0x7B09}, +{0x2510, 0x1C11}, +{0x2510, 0x3B12}, +{0x2510, 0x6312}, +{0x2510, 0x6014}, +{0x2510, 0x0015}, +{0x2510, 0x1811}, +{0x2510, 0x3812}, +{0x2510, 0xA012}, +{0x2510, 0x0010}, +{0x2510, 0x2610}, +{0x2510, 0x0013}, +{0x2510, 0x0011}, +{0x2510, 0x0008}, +{0x2510, 0x7A06}, +{0x2510, 0x0508}, +{0x2510, 0x070E}, +{0x2510, 0x0237}, +{0x2510, 0x502C}, +{0x2510, 0xFE32}, +{0x2510, 0xFE06}, +{0x2510, 0x2C2C}, + +{AR0147_DELAY, 200}, + +{0x32e6, 0x009a}, //min_subrow +{0x322e, 0x258c}, //clks_per_sample 396 +/* Sequencer_Update */ + +{0x32D0, 0x3A02}, +{0x32D2, 0x3508}, +{0x32D4, 0x3702}, +{0x32D6, 0x3C04}, +{0x32DC, 0x370A}, +{0x32EA, 0x3CA8}, +{0x351E, 0x0000}, +{0x3510, 0x811F}, + +//settings to rev1 default for non-Super Exposure mode settings +//Super Exposure mode settings have additional settings +{0x1010, 0x0155}, // FINE_INTEGRATION_TIME4_MIN +{0x3236, 0x00B2}, // FINE_CORRECTION4 +{0x32EA, 0x3C0E}, +{0x32EC, 0x7151}, +{0x3116, 0x0001}, // HDR_CONTROL3 +{0x33E2, 0x0000}, // SAMPLE_CTRL +{0x3088, 0x0400}, // LFM_CTRL +{0x322A, 0x0039}, // FINE_INTEGRATION_CTRL +{0x3238, 0x0333}, // EXPOSURE_RATIO +{ } +}; /* Sensor_Setup */ + +static const struct ar0147_reg ar0147_rev2_Super_Exposure_Default_Plus_T2_Setup[] = { +{0x3082, 0x0008}, // OPERATION_MODE_CTRL +{0x30BA, 0x1003}, // DIGITAL_CTRL +{0x3C06, 0x2024}, // CONFIGURE_BUFFERS1 +{0x3C08, 0x2100}, // CONFIGURE_BUFFERS2 +{0x3088, 0x0400}, +{0x32EA, 0x3CA9}, +{0x3510, 0x814F}, +{0x351E, 0x0100}, +{0x32EA, 0x3CA9}, +{0x32EC, 0x7281}, +{0x3212, 0x0000}, // COARSE_INTEGRATION_TIME2 +{0x3216, 0x0004}, // COARSE_INTEGRATION_TIME3 +{0x3238, 0x8222}, // EXPOSURE_RATIO +{0x33E2, 0x0A10}, // SAMPLE_CTRL +{0x3362, 0x0001}, // DC_GAIN +{0x322A, 0x0539}, // FINE_INTEGRATION_CTRL +{0x3014, 0x0123}, // FINE_INTEGRATION_TIME_ +{0x3222, 0x0490}, // FINE_INTEGRATION_TIME3 +{0x1008, 0x0123}, // FINE_INTEGRATION_TIME_MIN +{0x100E, 0x043B}, // FINE_INTEGRATION_TIME3_MIN +{0x3230, 0x00C7}, // FINE_CORRECTION +{0x3234, 0x03DF}, // FINE_CORRECTION3 +{0x32D0, 0x3A02}, +{0x32D2, 0x3508}, +{0x32D4, 0x3702}, +{0x32D6, 0x3C04}, +{0x32DC, 0x370A}, +{0x3528, 0x99EE}, +{0x30FE, 0x0040}, // NOISE_PEDESTAL +{0x3096, 0x0000}, // ROW_NOISE_ADJUST_1X_LCG_T2 + +/* Digital_Lateral_Overflow_for_SE */ +{0x3116, 0x0001}, +{0x3100, 0xC001}, // FIELD_WR= DLO_CONTROL0, 0xE001 +{0x3102, 0x6100}, +{0x3104, 0x6100}, +{0x3106, 0x6100}, +{0x3108, 0x0CB1}, +{0x312A, 0x83E8}, +{0x3C82, 0x0FFF}, +/* Digital_Lateral_Overflow_for_SE */ + +/* Other_Super_Exposure_Setup */ +{0x3536, 0xFF20}, +{0x3520, 0x0800}, +{0x3522, 0x0008}, +{0x3536, 0xFF20}, +{0x350C, 0x034A}, +{0x350E, 0x051C}, +{0x3540, 0xC62C}, +{0x3542, 0x4B4B}, +{0x3544, 0x4B46}, +{0x3546, 0x5A5A}, +{0x3548, 0x6400}, +{0x354A, 0x007F}, +{0x3524, 0x0600}, +{0x3372, 0xF40F}, // DBLC_FS0_CONTROL +{0x3180, 0x0188}, +{0x3280, 0x0CB2}, // T1_BARRIER_C0 +{0x3282, 0x0CB2}, // T1_BARRIER_C1 +{0x3284, 0x0CB2}, // T1_BARRIER_C2 +{0x3286, 0x0CB2}, // T1_BARRIER_C3 +{0x3288, 0x0CB2}, // T2_BARRIER_C0 +{0x328A, 0x0CB2}, // T2_BARRIER_C1 +{0x328C, 0x0CB2}, // T2_BARRIER_C2 +{0x328E, 0x0CB2}, // T2_BARRIER_C3 +{0x3290, 0x0CB2}, // T3_BARRIER_C0 +{0x3292, 0x0CB2}, // T3_BARRIER_C1 +{0x3294, 0x0CB2}, // T3_BARRIER_C2 +{0x3296, 0x0CB2}, // T3_BARRIER_C3 +{0x3298, 0x0CB2}, // T4_BARRIER_C0 +{0x329A, 0x0CB2}, // T4_BARRIER_C1 +{0x329C, 0x0CB2}, // T4_BARRIER_C2 +{0x329E, 0x0CB2}, // T4_BARRIER_C3 +{0x3108, 0x0CB1}, +{0x312A, 0x83E8}, +{0x3C82, 0x0FFF}, +{0x3102, 0x6100}, +{0x3104, 0x6100}, +{0x3106, 0x6100}, +{0x3120, 0x0AF0}, +{0x3122, 0x0CB2}, +/* Other_Super_Exposure_Setup */ +{ } +}; /* Super_Exposure_Default_Plus_T2_Setup */ + +static const struct ar0147_reg ar0147_rev2_Serial_12_bit_Timing_Setup[] = { +#if 0 +/* PCLK=24Mhz/3 *50 /1/8 = 50MHz */ +{0x302A, 8}, // VT_PIX_CLK_DIV +{0x302C, 1}, // VT_SYS_CLK_DIV +{0x302E, 3}, // PRE_PLL_CLK_DIV +{0x3030, 50}, // PLL_MULTIPLIER +{0x3036, 8}, // OP_WORD_CLK_DIV +{0x3038, 1}, // OP_SYS_CLK_DIV +#else +/* PCLK=24Mhz/4 *75 /1/9 = 50MHz */ +{0x302A, 9}, // VT_PIX_CLK_DIV +{0x302C, 1}, // VT_SYS_CLK_DIV +{0x302E, 4}, // PRE_PLL_CLK_DIV +{0x3030, 75}, // PLL_MULTIPLIER +{0x3036, 12}, // OP_WORD_CLK_DIV +{0x3038, 1}, // OP_SYS_CLK_DIV +#endif +{0x30B0, 0x980C}, // DIGITAL_TEST +{0x31DC, 0x1FB0}, +{ } +}; /* Serial_12_bit_Timing_Setup */ + +static const struct ar0147_reg ar0147_rev2_Readout_Mode_Configuration[] = { +{0x30A2, 0x0001}, // X_ODD_INC_ +{0x30A6, 0x0001}, // Y_ODD_INC_ +{0x3040, 0x0000}, // READ_MODE +{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp +{0x3044, 0x0400}, // DARK_CONTROL +{0x3064, 0x0000}, // SMIA_TEST: disable emb data and stats +{0x33E0, 0x0C80}, // TEST_ASIL_ROWS +{0x3180, 0x0080}, // RESERVED_MFR_3180 +{0x33E4, 0x0080}, // RESERVED_MFR_33E4 +#ifdef AR0147_EMBEDDED_LINE +{0x3064, 0x0180}, // SMIA_TEST: enable emb data and stats +#endif +{ } +}; /* Readout_Mode_Configuration */ + +static const struct ar0147_reg ar0147_rev2_Full_Res_FOV[] = { +{0x31B0, 0x0056}, // FRAME_PREAMBLE +{0x31B2, 0x0045}, // LINE_PREAMBLE +{0x3004, AR0147_X_START}, // X_ADDR_START_ +{0x3008, AR0147_X_END}, // X_ADDR_END_ +{0x3002, AR0147_Y_START}, // Y_ADDR_START_ +{0x3006, AR0147_Y_END}, // Y_ADDR_END_ +{0x3400, 0x10}, +{0x3402, (0x8000 & 0) | AR0147_MAX_WIDTH}, // X_OUTPUT_CONTROL +{0x3404, (0x8000 & 0) | AR0147_MAX_HEIGHT}, // Y_OUTPUT_CONTROL +{ } +}; /* Full_Res_FOV */ + +static const struct ar0147_reg ar0147_rev2_3exp_30FPS_Timing_and_Exposure[] = { +{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp +{0x30BA, 0x1002}, // DIGITAL_CTRL: 3exp max + +/* Row and Pixel Timing */ +{0x300C, AR0147_SENSOR_WIDTH + 52}, // LINE_LENGTH_PCK_ (1396) +{0x300A, AR0147_SENSOR_HEIGHT + 226}, // FRAME_LENGTH_LINES_ +{0x3042, 0x0000}, // EXTRA_DELAY + +/* Exposure Settings */ +{0x3238, 0x0222}, // EXPOSURE_RATIO +{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_ + +{0x3014, 1550}, // FINE_INTEGRATION_TIME_ +{0x321E, 1550}, // FINE_INTEGRATION_TIME2 +{0x3222, 1550}, // FINE_INTEGRATION_TIME3 +{0x30B0, 0x980C}, // DIGITAL_TEST (MIPI ...) +{0x32EA, 0x3C0E}, +{0x32EC, 0x72A1}, +{0x3362, 0x0000}, // DC_GAIN +{0x3366, 0xCCCC}, // ANALOG_GAIN +{0x3364, 0x01CF}, // DCG_TRIM +{0x3C06, 0x083C}, +{0x3C08, 0x0100}, +{ } +}; /* 3exp_30FPS_Timing_and_Exposure */ + +static const struct ar0147_reg ar0147_rev2_SE_Plus_T2_Default_Mode_30FPS_Timing_and_Exposure[] = { +{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp +{0x30BA, 0x1003}, // DIGITAL_CTRL: 4exp max + +/* Row and Pixel Timing */ +{0x300C, AR0147_SENSOR_WIDTH + 52}, // LINE_LENGTH_PCK_ (1396) +{0x300A, AR0147_SENSOR_HEIGHT + 226}, // FRAME_LENGTH_LINES_ +{0x3042, 0x0000}, // EXTRA_DELAY + +/* Exposure Settings */ +{0x3238, 0x8222}, // EXPOSURE_RATIO: separate integartion time!? +{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_ + +{0x322A, 0x0539}, // FINE_INTEGRATION_CTRL +{0x3014, 0x0123}, // FINE_INTEGRATION_TIME_ +{0x3222, 0x0490}, // FINE_INTEGRATION_TIME3 +{0x3362, 0x0001}, // DC_GAIN +{0x3366, 0xFDF7}, // ANALOG_GAIN +{0x3364, 0x01CF}, // DCG_TRIM + +{0x30B0, 0x980C}, // DIGITAL_TEST (MIPI ...) +{0x32EC, 0x7281}, +{ } +}; /* SE_Plus_T2_Default_Mode_30FPS_Timing_and_Exposure */ + +static const struct ar0147_reg ar0147_rev2_Serial_4_Lane_20_to_12_bit_Output[] = { +{0x31D0, 0x0001}, // COMPANDING +{0x31AE, 0x0304}, // SERIAL_FORMAT: HISPI 4-lanes +{0x31AC, 0x140C}, // DATA_FORMAT_BITS: ADC20, RAW12 +//{0x301A, 0x0118}, // RESET_REGISTER +{0x301A, 0x0018}, // RESET_REGISTER +{ } +}; /* Serial_4_Lane_20_to_12_bit_Output */ + +static const struct ar0147_reg ar0147_rev2_MIPI_12_bit_450MBps_Settings[] = { +{0x31AE, 0x0204}, // SERIAL_FORMAT: MIPI 4-lanes +{0x3342, 0x122C}, // exposure1 DT=0x2c emb=0x12 +{0x3346, 0x122C}, // exposure2 DT=0x2c emb=0x12 +{0x334A, 0x122C}, // exposure3 DT=0x2c emb=0x12 +{0x334E, 0x122C}, // exposure4 DT=0x2c emb=0x12 +{0x3344, 0x0011}, // exposure1 VC=0 +{0x3348, 0x0111}, // exposure1 VC=1 +{0x334C, 0x0211}, // exposure1 VC=2 +{0x3350, 0x0311}, // exposure1 VC=3 +{0x31B0, 0x41}, // frame_preamble +{0x31B2, 0x2e}, // line_preamble + +{0x31B4, 0x2185}, +{0x31B6, 0x1105}, +{0x31B8, 0x2047}, +{0x31BA, 0x105}, +{0x31BC, 0x704}, +{ } +}; /* MIPI_12_bit_450MBps_Settings */ + +static const struct ar0147_reg ar0147_rev2_shutter_and_booster_settings[] = { +{0x32EA, 0x3CA8}, +{0x32F6, 0x3A01}, +{0x32D2, 0x200A}, +{0x32D0, 0x3005}, +{0x32D4, 0x3505}, +{0x32F8, 0x3C03}, +{0x32DC, 0x220C}, +{0x32D6, 0x3207}, +{0x32E2, 0x3707}, +{0x3260, 0x00FF}, +{0x3262, 0x00FF}, +{0x3528, 0xEEEE}, +{0x353E, 0x801F}, +{0x3532, 0x8F4C}, +{0x3250, 0x0005}, +{0x3252, 0x0107}, +{0x3256, 0x03E8}, +{0x3258, 0x0300}, +{0x325A, 0x0A13}, +{0x325E, 0x0186}, +{0x3524, 0x0C00}, +{0x3536, 0xFF38}, +{0x3532, 0x8F48}, +{0x3526, 0x8F00}, +{0x3536, 0xDF18}, +{0x3520, 0x0C00}, +{0x352E, 0x00FF}, +{0x3530, 0xFF00}, +{0x3532, 0x8F68}, +{0x3536, 0xDF18}, +{0x3252, 0x0107}, +{0x325E, 0x0186}, +{0x3096, 0x0000}, +{0x3504, 0x9100}, +{0x354E, 0x1480}, +{0x355A, 0x0B0E}, +{0x3372, 0xF50F}, +{0x337A, 0x100E}, +{0x3554, 0x1599}, +{0x32EA, 0x3CA9}, +{0x3510, 0x9753}, +{0x3520, 0x0800}, +{0x3522, 0x0008}, +{0x3524, 0x0C00}, +{0x3526, 0x0F00}, +{0x3528, 0xDDDD}, +{0x352A, 0x089F}, +{0x352C, 0x0012}, +{0x352E, 0x00FF}, +{0x3530, 0xFF00}, +{0x3532, 0x8F48}, +{0x3536, 0xFF38}, +{0x3538, 0x24FF}, +{0x353A, 0x9000}, +{0x353C, 0x7F00}, +{0x312A, 0x83E8}, +{0x3C82, 0x0FFF}, +{ } +}; /* shutter_and_booster_settings */ + +/* 3 Exp HDR, Full Resolution, MIPI 450MBPS 4 lane 12-bit, 30FPS, XMCLK=24MHz */ +static const struct ar0147_reg *ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev2[] = { + ar0147_rev2_Reset, + ar0147_rev2_Sensor_Setup, + ar0147_rev2_Serial_12_bit_Timing_Setup, + ar0147_rev2_Readout_Mode_Configuration, + ar0147_rev2_Full_Res_FOV, + ar0147_rev2_3exp_30FPS_Timing_and_Exposure, + ar0147_rev2_Serial_4_Lane_20_to_12_bit_Output, + ar0147_rev2_MIPI_12_bit_450MBps_Settings, + NULL +}; + +/* Super-Exposure Plus T2, Full Resolution, MIPI 450MBPS 4 lane 12-bit, 30FPS, XMCLK=24MHz */ +static const struct ar0147_reg *ar0147_regs_seplus_mipi450mbps_12bit_30fps_rev2[] = { + ar0147_rev2_Reset, + ar0147_rev2_Sensor_Setup, + ar0147_rev2_Super_Exposure_Default_Plus_T2_Setup, + ar0147_rev2_Serial_12_bit_Timing_Setup, + ar0147_rev2_Readout_Mode_Configuration, + ar0147_rev2_Full_Res_FOV, + ar0147_rev2_SE_Plus_T2_Default_Mode_30FPS_Timing_and_Exposure, + ar0147_rev2_Serial_4_Lane_20_to_12_bit_Output, + ar0147_rev2_MIPI_12_bit_450MBps_Settings, + ar0147_rev2_shutter_and_booster_settings, + NULL +}; -- 2.7.4