diff options
Diffstat (limited to 'meta-rcar-gen3-adas/recipes-kernel')
7 files changed, 1196 insertions, 113 deletions
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngr.bbappend b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngr.bbappend new file mode 100644 index 0000000..cf50bc8 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngr.bbappend @@ -0,0 +1,2 @@ +MMNGR_CFG_eagle = "MMNGR_SALVATORX_X" +MMNGR_CFG_v3msk = "MMNGR_SALVATORX_X" diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch index 6209ed0..0cb8cc6 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch @@ -1609,11 +1609,11 @@ index ecae864..42eb45c 100644 - pllcr = LVDPLLCR_PLLDIVCNT_148M; + if (soc_device_match(r8a7797)) { + if (freq < 39000) -+ pllcr = LVDPLLCR_PLLDLYCNT_38M; ++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M; + else if (freq < 61000) -+ pllcr = LVDPLLCR_PLLDLYCNT_60M; ++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M; + else if (freq < 121000) -+ pllcr = LVDPLLCR_PLLDLYCNT_121M; ++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M; + else + pllcr = LVDPLLCR_PLLDLYCNT_150M; + } else { diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch index 2782272..96c1601 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch @@ -4,33 +4,37 @@ Date: Sun, 14 May 2017 15:20:01 +0300 Subject: [PATCH] Gen3: LVDS cameras This add Gen3 LVDS cameras support: -- deserializers: MAX9286, TI964, TI953, TI960 -- cameras: 10635, ov490+ov10640, ov495+OV2775 +- deserializers: MAX9286, TI964, TI954, TI960 +- cameras: ov10635, ov490+ov10640, ov495+OV2775, ar0132 Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> --- drivers/media/i2c/soc_camera/Kconfig | 47 + drivers/media/i2c/soc_camera/Makefile | 7 + - drivers/media/i2c/soc_camera/max9286_max9271.c | 562 +++++++++++ - drivers/media/i2c/soc_camera/max9286_max9271.h | 196 ++++ - drivers/media/i2c/soc_camera/ov10635.c | 751 ++++++++++++++ + drivers/media/i2c/soc_camera/ar0132.c | 548 +++++++++++ + drivers/media/i2c/soc_camera/ar0132.h | 213 ++++ + drivers/media/i2c/soc_camera/max9286_max9271.c | 567 +++++++++++ + drivers/media/i2c/soc_camera/max9286_max9271.h | 243 +++++ + drivers/media/i2c/soc_camera/ov10635.c | 759 ++++++++++++++ drivers/media/i2c/soc_camera/ov10635.h | 1139 ++++++++++++++++++++++ drivers/media/i2c/soc_camera/ov10635_debug.h | 54 + - drivers/media/i2c/soc_camera/ov106xx.c | 95 ++ - drivers/media/i2c/soc_camera/ov490_ov10640.c | 961 ++++++++++++++++++ - drivers/media/i2c/soc_camera/ov490_ov10640.h | 82 ++ - drivers/media/i2c/soc_camera/ov495_ov2775.c | 650 ++++++++++++ + drivers/media/i2c/soc_camera/ov106xx.c | 106 ++ + drivers/media/i2c/soc_camera/ov490_ov10640.c | 1046 ++++++++++++++++++++ + drivers/media/i2c/soc_camera/ov490_ov10640.h | 88 ++ + drivers/media/i2c/soc_camera/ov495_ov2775.c | 658 +++++++++++++ drivers/media/i2c/soc_camera/ov495_ov2775.h | 23 + drivers/media/i2c/soc_camera/ti954_ti9x3.c | 417 ++++++++ drivers/media/i2c/soc_camera/ti964_ti9x3.c | 385 ++++++++ - drivers/media/i2c/soc_camera/ti9x4_ti9x3.h | 108 ++ + drivers/media/i2c/soc_camera/ti9x4_ti9x3.h | 153 +++ drivers/media/platform/soc_camera/rcar_csi2.c | 297 ++++-- - drivers/media/platform/soc_camera/rcar_vin.c | 159 ++- + drivers/media/platform/soc_camera/rcar_vin.c | 174 +++- drivers/media/platform/soc_camera/soc_camera.c | 17 +- drivers/media/platform/soc_camera/soc_mediabus.c | 16 + include/media/drv-intf/soc_mediabus.h | 3 + include/media/soc_camera.h | 1 + - 21 files changed, 5861 insertions(+), 109 deletions(-) + 23 files changed, 6852 insertions(+), 109 deletions(-) + create mode 100644 drivers/media/i2c/soc_camera/ar0132.c + create mode 100644 drivers/media/i2c/soc_camera/ar0132.h create mode 100644 drivers/media/i2c/soc_camera/max9286_max9271.c create mode 100644 drivers/media/i2c/soc_camera/max9286_max9271.h create mode 100644 drivers/media/i2c/soc_camera/ov10635.c @@ -123,12 +127,785 @@ index 6f994f9..7d4c1ab 100644 obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o +diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c +new file mode 100644 +index 0000000..284c522 +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/ar0132.c +@@ -0,0 +1,548 @@ ++/* ++ * Aptina AR0132 sensor camera driver ++ * ++ * Copyright (C) 2017 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 <linux/delay.h> ++#include <linux/init.h> ++#include <linux/i2c.h> ++#include <linux/module.h> ++#include <linux/videodev2.h> ++ ++#include <media/soc_camera.h> ++#include <media/v4l2-common.h> ++#include <media/v4l2-ctrls.h> ++#include <media/v4l2-of.h> ++ ++#include "ar0132.h" ++ ++#define AR0132_I2C_ADDR 0x18 ++//#define AR0132_I2C_ADDR 0x50 // eeprom ++ ++#define AR0132_PID 0x3000 ++#define AR0132_VERSION_REG 0x2400 ++ ++#define AR0132_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR12_1X12 ++ ++struct ar0132_priv { ++ struct v4l2_subdev sd; ++ struct v4l2_ctrl_handler hdl; ++ struct media_pad pad; ++ struct v4l2_rect rect; ++ int init_complete; ++ u8 id[6]; ++ int exposure; ++ int gain; ++ int autogain; ++ int dvp_order; ++ /* serializers */ ++ int ti964_addr; ++ int ti954_addr; ++ int ti9x3_addr; ++ int port; ++ int gpio_resetb; ++ int gpio_fsin; ++ ++}; ++ ++static inline struct ar0132_priv *to_ar0132(const struct i2c_client *client) ++{ ++ return container_of(i2c_get_clientdata(client), struct ar0132_priv, sd); ++} ++ ++static int ar0132_set_regs(struct i2c_client *client, ++ const struct ar0132_reg *regs, int nr_regs) ++{ ++ int i; ++ ++ for (i = 0; i < nr_regs; i++) { ++ if (regs[i].reg == AR0132_DELAY) { ++ mdelay(regs[i].val); ++ continue; ++ } ++ ++ reg16_write16(client, regs[i].reg, regs[i].val); ++ } ++ ++ return 0; ++} ++ ++static int ar0132_s_stream(struct v4l2_subdev *sd, int enable) ++{ ++ return 0; ++} ++ ++static int ar0132_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 ar0132_priv *priv = to_ar0132(client); ++ ++ if (format->pad) ++ return -EINVAL; ++ ++ mf->width = priv->rect.width; ++ mf->height = priv->rect.height; ++ mf->code = AR0132_MEDIA_BUS_FMT; ++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ++ mf->field = V4L2_FIELD_NONE; ++ ++ return 0; ++} ++ ++static int ar0132_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 = AR0132_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 ar0132_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 = AR0132_MEDIA_BUS_FMT; ++ ++ return 0; ++} ++ ++static int ar0132_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0132_priv *priv = to_ar0132(client); ++ ++ memcpy(edid->edid, priv->id, 6); ++ ++ edid->edid[6] = 0xff; ++ edid->edid[7] = client->addr; ++ edid->edid[8] = AR0132_VERSION_REG >> 8; ++ edid->edid[9] = AR0132_VERSION_REG & 0xff; ++ ++ return 0; ++} ++ ++static int ar0132_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 ar0132_priv *priv = to_ar0132(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 > AR0132_MAX_WIDTH) || ++ (rect->top + rect->height > AR0132_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; ++ ++ return 0; ++} ++ ++static int ar0132_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 ar0132_priv *priv = to_ar0132(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 = AR0132_MAX_WIDTH; ++ sel->r.height = AR0132_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = AR0132_MAX_WIDTH; ++ sel->r.height = AR0132_MAX_HEIGHT; ++ return 0; ++ case V4L2_SEL_TGT_CROP: ++ sel->r = priv->rect; ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int ar0132_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 ar0132_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 ar0132_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 ar0132_core_ops = { ++#ifdef CONFIG_VIDEO_ADV_DEBUG ++ .g_register = ar0132_g_register, ++ .s_register = ar0132_s_register, ++#endif ++}; ++ ++static int ar0132_s_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ struct v4l2_subdev *sd = to_sd(ctrl); ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct ar0132_priv *priv = to_ar0132(client); ++ int ret = -EINVAL; ++ ++ 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: ++ case V4L2_CID_GAIN: ++ case V4L2_CID_EXPOSURE: ++ case V4L2_CID_HFLIP: ++ case V4L2_CID_VFLIP: ++ break; ++ } ++ ++ return ret; ++} ++ ++static const struct v4l2_ctrl_ops ar0132_ctrl_ops = { ++ .s_ctrl = ar0132_s_ctrl, ++}; ++ ++static struct v4l2_subdev_video_ops ar0132_video_ops = { ++ .s_stream = ar0132_s_stream, ++ .g_mbus_config = ar0132_g_mbus_config, ++}; ++ ++static const struct v4l2_subdev_pad_ops ar0132_subdev_pad_ops = { ++ .get_edid = ar0132_get_edid, ++ .enum_mbus_code = ar0132_enum_mbus_code, ++ .get_selection = ar0132_get_selection, ++ .set_selection = ar0132_set_selection, ++ .get_fmt = ar0132_get_fmt, ++ .set_fmt = ar0132_set_fmt, ++}; ++ ++static struct v4l2_subdev_ops ar0132_subdev_ops = { ++ .core = &ar0132_core_ops, ++ .video = &ar0132_video_ops, ++ .pad = &ar0132_subdev_pad_ops, ++}; ++ ++static void ar0132_otp_id_read(struct i2c_client *client) ++{ ++} ++ ++static ssize_t ar0132_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 ar0132_priv *priv = to_ar0132(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_ar0132, S_IRUGO, ar0132_otp_id_show, NULL); ++ ++static int ar0132_initialize(struct i2c_client *client) ++{ ++ struct ar0132_priv *priv = to_ar0132(client); ++ u16 val = 0; ++ u16 pid = 0; ++ int ret = 0; ++ ++ /* check and show model ID */ ++ reg16_read16(client, AR0132_PID, &pid); ++ ++ if (pid != AR0132_VERSION_REG) { ++ dev_dbg(&client->dev, "Product ID error %x\n", pid); ++ ret = -ENODEV; ++ goto err; ++ } ++ ++ /* Program wizard registers */ ++ ar0132_set_regs(client, ar0132_regs_wizard, ARRAY_SIZE(ar0132_regs_wizard)); ++ ++ /* Enable stream */ ++ reg16_read16(client, 0x301a, &val); // read inital reset_register value ++ val |= (1 << 2); // Set streamOn bit ++ reg16_write16(client, 0x301a, val); // Start Streaming ++ ++ /* Read OTP IDs */ ++ ar0132_otp_id_read(client); ++ ++ dev_info(&client->dev, "ar0132 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n", ++ pid, AR0132_MAX_WIDTH, AR0132_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); ++err: ++ return ret; ++} ++ ++static int ar0132_parse_dt(struct device_node *np, struct ar0132_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; ++ ++ of_node_put(endpoint); ++ ++ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order); ++ ++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0); ++ if (!rendpoint) ++ continue; ++ ++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && ++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti964-ti9x3") && ++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti964_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,ti954-ti9x3") && ++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti954_addr) && ++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) ++ break; ++ } ++ ++ if (!priv->ti964_addr && !priv->ti954_addr) { ++ dev_err(&client->dev, "deserializer does not present\n"); ++ return -EINVAL; ++ } ++ ++ /* setup I2C translator address */ ++ tmp_addr = client->addr; ++ if (priv->ti964_addr) { ++ client->addr = priv->ti964_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, AR0132_I2C_ADDR << 1); /* Sensor native I2C address */ ++ ++ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */ ++ } ++ if (priv->ti954_addr) { ++ client->addr = priv->ti954_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, AR0132_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 ar0132_probe(struct i2c_client *client, ++ const struct i2c_device_id *did) ++{ ++ struct ar0132_priv *priv; ++ int ret; ++ ++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0132_subdev_ops); ++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; ++ ++ priv->exposure = 0x100; ++ priv->gain = 0x100; ++ priv->autogain = 1; ++ v4l2_ctrl_handler_init(&priv->hdl, 4); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops, ++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops, ++ V4L2_CID_CONTRAST, 0, 16, 1, 7); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops, ++ V4L2_CID_SATURATION, 0, 7, 1, 2); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops, ++ V4L2_CID_HUE, 0, 23, 1, 12); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops, ++ V4L2_CID_GAMMA, -128, 128, 1, 0); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops, ++ V4L2_CID_SHARPNESS, 0, 10, 1, 3); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops, ++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops, ++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops, ++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops, ++ V4L2_CID_HFLIP, 0, 1, 1, 1); ++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_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 = ar0132_parse_dt(client->dev.of_node, priv); ++ if (ret) ++ goto cleanup; ++ ++ ret = ar0132_initialize(client); ++ if (ret < 0) ++ goto cleanup; ++ ++ priv->rect.left = 0; ++ priv->rect.top = 0; ++ priv->rect.width = AR0132_MAX_WIDTH; ++ priv->rect.height = AR0132_MAX_HEIGHT; ++ ++ ret = v4l2_async_register_subdev(&priv->sd); ++ if (ret) ++ goto cleanup; ++ ++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0132) != 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_AR0132 ++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n", ++ client->addr, client->adapter->name); ++#endif ++ return ret; ++} ++ ++static int ar0132_remove(struct i2c_client *client) ++{ ++ struct ar0132_priv *priv = i2c_get_clientdata(client); ++ ++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0132); ++ 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_AR0132 ++static const struct i2c_device_id ar0132_id[] = { ++ { "ar0132", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, ar0132_id); ++ ++static const struct of_device_id ar0132_of_ids[] = { ++ { .compatible = "aptina,ar0132", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, ar0132_of_ids); ++ ++static struct i2c_driver ar0132_i2c_driver = { ++ .driver = { ++ .name = "ar0132", ++ .of_match_table = ar0132_of_ids, ++ }, ++ .probe = ar0132_probe, ++ .remove = ar0132_remove, ++ .id_table = ar0132_id, ++}; ++ ++module_i2c_driver(ar0132_i2c_driver); ++ ++MODULE_DESCRIPTION("SoC Camera driver for AR0132"); ++MODULE_AUTHOR("Vladimir Barinov"); ++MODULE_LICENSE("GPL"); ++#endif +diff --git a/drivers/media/i2c/soc_camera/ar0132.h b/drivers/media/i2c/soc_camera/ar0132.h +new file mode 100644 +index 0000000..055841d +--- /dev/null ++++ b/drivers/media/i2c/soc_camera/ar0132.h +@@ -0,0 +1,213 @@ ++/* ++ * OmniVision ar0132 sensor camera wizard 1110x620@30/BGGR/BT601/12bit ++ * ++ * Copyright (C) 2017 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 AR0132_DISPLAY_PATTERN_FIXED ++//#define AR0132_DISPLAY_PATTERN_COLOR_BAR ++ ++#define AR0132_EMBEDDED_LINE ++ ++#define AR0132_MAX_WIDTH 1665 // (1110*3/2) ++#define AR0132_MAX_HEIGHT 624 ++ ++#define AR0132_DELAY 0xffff ++ ++#define AR0132_MAX_ROI_DIM_X 1288 ++#define AR0132_MAX_ROI_DIM_Y 968 ++#define AR0132_InfoLines 4 ++ ++#define AR0132_ROI_DIM_X 1110 // 1104 ++#define AR0132_ROI_DIM_Y 620 // AR0132_MAX_HEIGHT ++ ++#define AR0132_ROI_Y_START 0x00AE ++#define AR0132_ROI_X_START 0x005C ++#define AR0132_ROI_Y_END AR0132_ROI_Y_START+AR0132_ROI_DIM_Y-1 ++#define AR0132_ROI_X_END AR0132_ROI_X_START+AR0132_ROI_DIM_X-1 ++ ++#define AR0132_FrameLength_Lines 0x029E ++#define AR0132_LineLength_Ticks 0x06B6 ++ ++#define AR0132_PLL_VT_Pix_Clk_Div 0x0008 ++#define AR0132_PLL_VT_Sys_Clk_Div 0x0001 ++#define AR0132_PLL_Pre_Clk_Div 0x0004 ++#define AR0132_PLL_Multiplier 0x003C ++ ++#define AR0132_DigitalTest 0x2002 ++ ++struct ar0132_reg { ++ u16 reg; ++ u16 val; ++}; ++ ++static const struct ar0132_reg ar0132_regs_wizard[] = { ++{0x301A, 0x0001}, // reset ++{AR0132_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 AR0132_DISPLAY_PATTERN_FIXED ++{0x3070, 0x0001}, ++{0x3072, 0x0123}, // R ++{0x3074, 0x0456}, // G(GR row) ++{0x3076, 0x0abc}, // B ++{0x3078, 0x0def}, // G(GB row) ++#endif ++#ifdef AR0132_DISPLAY_PATTERN_COLOR_BAR ++{0x3070, 0x0002}, ++#endif ++{AR0132_DELAY, 250}, ++// patch begin ++{0x3088, 0x8000}, ++{0x3086, 0x0025}, {0x3086, 0x5050}, {0x3086, 0x2D26}, {0x3086, 0x0828}, {0x3086, 0x0D17}, {0x3086, 0x0926}, {0x3086, 0x0028}, {0x3086, 0x0526}, ++{0x3086, 0xA728}, {0x3086, 0x0725}, {0x3086, 0x8080}, {0x3086, 0x2925}, {0x3086, 0x0040}, {0x3086, 0x2702}, {0x3086, 0x1616}, {0x3086, 0x2706}, ++{0x3086, 0x1736}, {0x3086, 0x26A6}, {0x3086, 0x1703}, {0x3086, 0x26A4}, {0x3086, 0x171F}, {0x3086, 0x2805}, {0x3086, 0x2620}, {0x3086, 0x2804}, ++{0x3086, 0x2520}, {0x3086, 0x2027}, {0x3086, 0x0017}, {0x3086, 0x1D25}, {0x3086, 0x0020}, {0x3086, 0x1F17}, {0x3086, 0x1028}, {0x3086, 0x0519}, ++{0x3086, 0x1703}, {0x3086, 0x2706}, {0x3086, 0x1703}, {0x3086, 0x1741}, {0x3086, 0x2660}, {0x3086, 0x17AE}, {0x3086, 0x2500}, {0x3086, 0x9027}, ++{0x3086, 0x0026}, {0x3086, 0x1828}, {0x3086, 0x002E}, {0x3086, 0x2A28}, {0x3086, 0x081C}, {0x3086, 0x1470}, {0x3086, 0x7003}, {0x3086, 0x1470}, ++{0x3086, 0x7004}, {0x3086, 0x1470}, {0x3086, 0x7005}, {0x3086, 0x1470}, {0x3086, 0x7009}, {0x3086, 0x170C}, {0x3086, 0x0014}, {0x3086, 0x0020}, ++{0x3086, 0x2300}, {0x3086, 0x1400}, {0x3086, 0x5003}, {0x3086, 0x1400}, {0x3086, 0x2003}, {0x3086, 0x1400}, {0x3086, 0x5022}, {0x3086, 0x0414}, ++{0x3086, 0x0020}, {0x3086, 0x0414}, {0x3086, 0x0050}, {0x3086, 0x0514}, {0x3086, 0x0020}, {0x3086, 0x2405}, {0x3086, 0x1400}, {0x3086, 0x5001}, ++{0x3086, 0x2550}, {0x3086, 0x502D}, {0x3086, 0x2608}, {0x3086, 0x280D}, {0x3086, 0x1709}, {0x3086, 0x2600}, {0x3086, 0x2805}, {0x3086, 0x26A7}, ++{0x3086, 0x2807}, {0x3086, 0x2580}, {0x3086, 0x8029}, {0x3086, 0x2500}, {0x3086, 0x4027}, {0x3086, 0x0216}, {0x3086, 0x1627}, {0x3086, 0x0617}, ++{0x3086, 0x3626}, {0x3086, 0xA617}, {0x3086, 0x0326}, {0x3086, 0xA417}, {0x3086, 0x1F28}, {0x3086, 0x0526}, {0x3086, 0x2028}, {0x3086, 0x0425}, ++{0x3086, 0x2020}, {0x3086, 0x2700}, {0x3086, 0x171D}, {0x3086, 0x2500}, {0x3086, 0x2020}, {0x3086, 0x1710}, {0x3086, 0x2805}, {0x3086, 0x1A17}, ++{0x3086, 0x0327}, {0x3086, 0x0617}, {0x3086, 0x0317}, {0x3086, 0x4126}, {0x3086, 0x6017}, {0x3086, 0xAE25}, {0x3086, 0x0090}, {0x3086, 0x2700}, ++{0x3086, 0x2618}, {0x3086, 0x2800}, {0x3086, 0x2E2A}, {0x3086, 0x2808}, {0x3086, 0x1D05}, {0x3086, 0x1470}, {0x3086, 0x7009}, {0x3086, 0x1720}, ++{0x3086, 0x1400}, {0x3086, 0x2024}, {0x3086, 0x1400}, {0x3086, 0x5002}, {0x3086, 0x2550}, {0x3086, 0x502D}, {0x3086, 0x2608}, {0x3086, 0x280D}, ++{0x3086, 0x1709}, {0x3086, 0x2600}, {0x3086, 0x2805}, {0x3086, 0x26A7}, {0x3086, 0x2807}, {0x3086, 0x2580}, {0x3086, 0x8029}, {0x3086, 0x2500}, ++{0x3086, 0x4027}, {0x3086, 0x0216}, {0x3086, 0x1627}, {0x3086, 0x0617}, {0x3086, 0x3626}, {0x3086, 0xA617}, {0x3086, 0x0326}, {0x3086, 0xA417}, ++{0x3086, 0x1F28}, {0x3086, 0x0526}, {0x3086, 0x2028}, {0x3086, 0x0425}, {0x3086, 0x2020}, {0x3086, 0x2700}, {0x3086, 0x171D}, {0x3086, 0x2500}, ++{0x3086, 0x2021}, {0x3086, 0x1710}, {0x3086, 0x2805}, {0x3086, 0x1B17}, {0x3086, 0x0327}, {0x3086, 0x0617}, {0x3086, 0x0317}, {0x3086, 0x4126}, ++{0x3086, 0x6017}, {0x3086, 0xAE25}, {0x3086, 0x0090}, {0x3086, 0x2700}, {0x3086, 0x2618}, {0x3086, 0x2800}, {0x3086, 0x2E2A}, {0x3086, 0x2808}, ++{0x3086, 0x1E17}, {0x3086, 0x0A05}, {0x3086, 0x1470}, {0x3086, 0x7009}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, ++{0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, ++{0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1400}, {0x3086, 0x2024}, {0x3086, 0x1400}, {0x3086, 0x502B}, ++{0x3086, 0x302C}, {0x3086, 0x2C2C}, {0x3086, 0x2C00}, {0x3086, 0x0225}, {0x3086, 0x5050}, {0x3086, 0x2D26}, {0x3086, 0x0828}, {0x3086, 0x0D17}, ++{0x3086, 0x0926}, {0x3086, 0x0028}, {0x3086, 0x0526}, {0x3086, 0xA728}, {0x3086, 0x0725}, {0x3086, 0x8080}, {0x3086, 0x2917}, {0x3086, 0x0525}, ++{0x3086, 0x0040}, {0x3086, 0x2702}, {0x3086, 0x1616}, {0x3086, 0x2706}, {0x3086, 0x1736}, {0x3086, 0x26A6}, {0x3086, 0x1703}, {0x3086, 0x26A4}, ++{0x3086, 0x171F}, {0x3086, 0x2805}, {0x3086, 0x2620}, {0x3086, 0x2804}, {0x3086, 0x2520}, {0x3086, 0x2027}, {0x3086, 0x0017}, {0x3086, 0x1E25}, ++{0x3086, 0x0020}, {0x3086, 0x2117}, {0x3086, 0x1028}, {0x3086, 0x051B}, {0x3086, 0x1703}, {0x3086, 0x2706}, {0x3086, 0x1703}, {0x3086, 0x1747}, ++{0x3086, 0x2660}, {0x3086, 0x17AE}, {0x3086, 0x2500}, {0x3086, 0x9027}, {0x3086, 0x0026}, {0x3086, 0x1828}, {0x3086, 0x002E}, {0x3086, 0x2A28}, ++{0x3086, 0x081E}, {0x3086, 0x0831}, {0x3086, 0x1440}, {0x3086, 0x4014}, {0x3086, 0x2020}, {0x3086, 0x1410}, {0x3086, 0x1034}, {0x3086, 0x1400}, ++{0x3086, 0x1014}, {0x3086, 0x0020}, {0x3086, 0x1400}, {0x3086, 0x4013}, {0x3086, 0x1802}, {0x3086, 0x1470}, {0x3086, 0x7004}, {0x3086, 0x1470}, ++{0x3086, 0x7003}, {0x3086, 0x1470}, {0x3086, 0x7017}, {0x3086, 0x2002}, {0x3086, 0x1400}, {0x3086, 0x2002}, {0x3086, 0x1400}, {0x3086, 0x5004}, ++{0x3086, 0x1400}, {0x3086, 0x2004}, {0x3086, 0x1400}, {0x3086, 0x5022}, {0x3086, 0x0314}, {0x3086, 0x0020}, {0x3086, 0x0314}, {0x3086, 0x0050}, ++{0x3086, 0x2C2C}, {0x3086, 0x2C2C}, ++{0x309E, 0x0186}, ++{0x309E, 0x0186}, ++// patch end ++{AR0132_DELAY, 250}, ++{0x301A, 0x10D8}, // WR= RESET_REGISTER, 0x10D8 - stop streaming ++{0x3082, 0x0028}, // Set HiDy OPERATION_MODE_CTRL(A) Requested integration time ratio (T2 to T3): 8 & (T1 t0 T2): 16 ++{0x3084, 0x0028}, // Set HiDy OPERATION_MODE_CTRL(B) Requested integration time ratio (T2 to T3): 16 & (T1 t0 T2): 16 ++{0x301E, 0x00C8}, // set datapedestal to 200 to avoid clipping near saturation ++{0x3EDA, 0x0F03}, // Set vln_dac to 0x3 as recommended by Sergey ++{0x3EDE, 0xC007}, ++{0x3ED8, 0x01EF}, // Vrst_low = +1 ++{0x3EE2, 0xA46B}, ++{0x3EE0, 0x067D}, // enable anti eclipse and adjust setting for high conversion gain ++{0x3EDC, 0x0070}, // adjust anti eclipse setting for low conversion gain ++{0x3044, 0x0404}, // disable digital row noise correction and cancels TX during column correction ++{0x3EE6, 0x4303}, // Helps with column noise at low light ++{0x3EE4, 0xD208}, // enable analog row noise correction ++{0x3ED6, 0x00BD}, ++{0x3EE6, 0x8303}, // improves low light FPN ++{0x30E4, 0x6372}, // ADC settings to improve noise performance ++{0x30E2, 0x7253}, ++{0x30E0, 0x5470}, ++{0x30E6, 0xC4CC}, ++{0x30E8, 0x8050}, ++{AR0132_DELAY, 250}, ++{0x3058, 0x003F}, // WR= BLUE_GAIN, 0x003F ++{0x3014, 0}, // Fine_IT_Time(A) ++{0x3002, AR0132_ROI_Y_START}, // WR= Y_ADDR_START_(A) ++{0x3004, AR0132_ROI_X_START}, // WR= X_ADDR_START_(A) ++{0x3006, AR0132_ROI_Y_END}, // WR= Y_ADDR_END_(A) ++{0x3008, AR0132_ROI_X_END}, // WR= X_ADDR_END_(A) ++{0x300A, AR0132_FrameLength_Lines}, // WR= FRAME_LENGTH_LINES_(A) ++{0x3018, 0}, // Fine_IT_Time(B) ++{0x308C, AR0132_ROI_Y_START}, // Y_ADDR_START_(B) ++{0x308A, AR0132_ROI_X_START}, // X_ADDR_START_(B) ++{0x3090, AR0132_ROI_Y_END}, // Y_ADDR_END_(B) ++{0x308E, AR0132_ROI_X_END}, // X_ADDR_END_(B) ++{0x30AA, AR0132_FrameLength_Lines}, // FRAME_LENGTH_LINES_(B) ++{0x300C, AR0132_LineLength_Ticks}, // Line Length ++{0x301A, 0x10D8}, // Disable Streaming and setup parallel ++{0x31D0, 0x0001}, // Set to 12 bits ++{0x3028, 0x0010}, // ROW_SPEED = 16 ++{0x302A, AR0132_PLL_VT_Pix_Clk_Div}, ++{0x302C, AR0132_PLL_VT_Sys_Clk_Div}, ++{0x302E, AR0132_PLL_Pre_Clk_Div}, ++{0x3030, AR0132_PLL_Multiplier}, ++{0x3032, 0x0000}, // SCALING_MODE = 0 ++{0x3040, 0xC000}, // READ_MODE = read_mode_vert_flip | read_mode_horiz_mirror ++{0x3044, 0x0404}, // Dark Control = 1028 ++{0x30A6, 0x0001}, // Y Odd Inc. (A) = 1 ++{0x30A8, 0x0001}, // Y Odd Inc. (B) = 1 ++{0x30B0, AR0132_DigitalTest}, ++{AR0132_DELAY, 100}, ++#ifdef AR0132_EMBEDDED_LINE ++{0x3064, 0x1982}, // Embedded Data on ++#else ++{0x3064, 0x1802}, // Embedded Data off ++#endif ++{0x3100, 0x0084}, // WR= AECTRLREG, ++{0x3190, 0x6BA0}, ++{0x3194, 0x0E74}, ++{0x3196, 0x0ED8}, ++{0x3198, 0x0FA0}, ++{0x319E, 0x5040}, // resetvalue ++{0x31A2, 0x0FA0}, ++//FrontCamera Specific Section ++//Common ++#ifdef AR0132_EMBEDDED_LINE ++{0x3064, 0x1982}, ++#else ++{0x3064, 0x1802}, ++#endif ++{0x30B4, 0x0011}, ++{0x30ba, 0x0008}, ++{0x3180, 0xE000}, ++{0x3182, 0x012C}, ++{0x3190, 0x6BA0}, ++{0x3194, 0x0E74}, ++{0x3196, 0x0ED8}, ++{0x3198, 0x0FA0}, ++{0x319E, 0x5040}, ++{0x31A2, 0x0FA0}, ++//Context A:0 ++{0x3012, 0x0021}, ++{0x3014, 0x0000}, ++{0x30A6, 0x0001}, ++{0x3056, 0x0008}, ++{0x3058, 0x0008}, ++{0x305A, 0x0008}, ++{0x305C, 0x0008}, ++{0x305E, 0x0008}, ++{0x3082, 0x0014}, ++//Context B:0 ++{0x3016, 0x007F}, ++{0x3018, 0x0000}, ++{0x30A8, 0x0001}, ++{0x30BC, 0x0020}, ++{0x30BE, 0x0020}, ++{0x30C0, 0x0020}, ++{0x30C2, 0x0020}, ++{0x30C4, 0x0020}, ++{0x3084, 0x0028}, ++//not covered ++{0x301E, 0x00C8}, ++{0x3044, 0x0404}, ++{0x31D0, 0x0001}, ++{0x30B0, 0x2002}, ++}; diff --git a/drivers/media/i2c/soc_camera/max9286_max9271.c b/drivers/media/i2c/soc_camera/max9286_max9271.c new file mode 100644 -index 0000000..1261e45 +index 0000000..9797d24 --- /dev/null +++ b/drivers/media/i2c/soc_camera/max9286_max9271.c -@@ -0,0 +1,562 @@ +@@ -0,0 +1,567 @@ +/* + * MAXIM max9286-max9271 GMSL driver + * @@ -203,6 +980,24 @@ index 0000000..1261e45 + usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */ +} + ++static void max9286_max9271_sensor_reset(struct i2c_client *client, int addr) ++{ ++ struct max9286_max9271_priv *priv = i2c_get_clientdata(client); ++ ++ if (priv->gpio_resetb < 1 || priv->gpio_resetb > 5) ++ return; ++ ++ /* get out from sensor reset */ ++ client->addr = addr; /* MAX9271-CAMx I2C */ ++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) | ++ (priv->active_low_resetb ? 0 : BIT(priv->gpio_resetb))); /* set GPIOn value to reset */ ++ reg8_write(client, 0x0e, 0x42 | BIT(priv->gpio_resetb)); /* set GPIOn direction output */ ++ usleep_range(2000, 2500); /* wait 2ms */ ++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) | ++ (priv->active_low_resetb ? BIT(priv->gpio_resetb) : 0)); /* set GPIOn value to un-reset */ ++ usleep_range(2000, 2500); /* wait 2ms */ ++} ++ +static void max9286_max9271_postinit(struct i2c_client *client, int addr) +{ + struct max9286_max9271_priv *priv = i2c_get_clientdata(client); @@ -214,10 +1009,6 @@ index 0000000..1261e45 + reg8_write(client, 0x15, 0x9b); /* enable CSI output, VC is set accordingly to Link number, BIT7 magic must be set */ + reg8_write(client, 0x1b, priv->links_mask); /* enable equalizer for CAMs */ + usleep_range(5000, 5500); /* wait 2ms after any change of reverse channel settings */ -+ -+ /* wait for sensor firmware up (f.e. ov490) if we did sensor reset */ -+ if (priv->gpio_resetb >= 1 && priv->gpio_resetb <= 5) -+ mdelay(300); +} + +static int max9286_max9271_reverse_channel_setup(struct i2c_client *client, int idx) @@ -269,6 +1060,8 @@ index 0000000..1261e45 + } + } + ++ max9286_max9271_sensor_reset(client, client->addr); /* sensor reset */ ++ + if (!timeout) { + ret = -ETIMEDOUT; + goto out; @@ -365,17 +1158,6 @@ index 0000000..1261e45 + client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C new */ + maxim_max927x_dump_regs(client); +#endif -+ if (priv->gpio_resetb >= 1 && priv->gpio_resetb <= 5) { -+ /* get out from sensor reset */ -+ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C new */ -+ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) | -+ (priv->active_low_resetb ? 0 : BIT(priv->gpio_resetb))); /* set GPIOn value to reset */ -+ reg8_write(client, 0x0e, 0x42 | BIT(priv->gpio_resetb)); /* set GPIOn direction output */ -+ usleep_range(2000, 2500); /* wait 2ms */ -+ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) | -+ (priv->active_low_resetb ? BIT(priv->gpio_resetb) : 0)); /* set GPIOn value to un-reset */ -+ usleep_range(2000, 2500); /* wait 2ms */ -+ } +} + +static int max9286_max9271_initialize(struct i2c_client *client) @@ -512,10 +1294,10 @@ index 0000000..1261e45 + err = gpio_request_one(pwen, GPIOF_OUT_INIT_HIGH, dev_name(&client->dev)); + if (err) + dev_err(&client->dev, "cannot request PWEN gpio %d: %d\n", pwen, err); -+ else -+ mdelay(250); + } + ++ mdelay(250); ++ + reg8_read(client, 0x1e, &val); /* read max9286 ID */ + if (val != MAX9286_ID) { + prop = of_find_property(np, "reg", NULL); @@ -693,10 +1475,10 @@ index 0000000..1261e45 +MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/soc_camera/max9286_max9271.h b/drivers/media/i2c/soc_camera/max9286_max9271.h new file mode 100644 -index 0000000..87c040b +index 0000000..0016f28a --- /dev/null +++ b/drivers/media/i2c/soc_camera/max9286_max9271.h -@@ -0,0 +1,196 @@ +@@ -0,0 +1,243 @@ +/* + * MAXIM max9286-max9271 GMSL driver include file + * @@ -828,6 +1610,53 @@ index 0000000..87c040b + return ret < 0 ? ret : 0; +} + ++ ++static inline int reg16_read16(struct i2c_client *client, u16 reg, u16 *val) ++{ ++ int ret, retries; ++ u8 buf[2] = {reg >> 8, reg & 0xff}; ++ ++ for (retries = REG8_NUM_RETRIES; retries; retries--) { ++ ret = i2c_master_send(client, buf, 2); ++ if (ret == 2) { ++ ret = i2c_master_recv(client, buf, 2); ++ if (ret == 2) ++ break; ++ } ++ } ++ ++ if (ret < 0) { ++ dev_err(&client->dev, ++ "read fail: chip 0x%x register 0x%x: %d\n", ++ client->addr, reg, ret); ++ } else { ++ *val = ((u16)buf[0] << 8) | buf[1]; ++ } ++ ++ return ret < 0 ? ret : 0; ++} ++ ++static inline int reg16_write16(struct i2c_client *client, u16 reg, u16 val) ++{ ++ int ret, retries; ++ u8 buf[4] = {reg >> 8, reg & 0xff, val >> 8, val & 0xff}; ++ ++ for (retries = REG8_NUM_RETRIES; retries; retries--) { ++ ret = i2c_master_send(client, buf, 4); ++ if (ret == 4) ++ break; ++ } ++ ++ if (ret < 0) { ++ dev_err(&client->dev, ++ "write fail: chip 0x%x register 0x%x: %d\n", ++ client->addr, reg, ret); ++ } ++ ++ return ret < 0 ? ret : 0; ++} ++ ++ +#ifdef MAXIM_DUMP +static void maxim_ovsensor_dump_regs(struct i2c_client *client) +{ @@ -895,10 +1724,10 @@ index 0000000..87c040b +#endif /* _MAX9286_MAX9271_H */ diff --git a/drivers/media/i2c/soc_camera/ov10635.c b/drivers/media/i2c/soc_camera/ov10635.c new file mode 100644 -index 0000000..fd72396 +index 0000000..45169de --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov10635.c -@@ -0,0 +1,751 @@ +@@ -0,0 +1,759 @@ +/* + * OmniVision ov10635 sensor camera driver + * @@ -1344,6 +2173,9 @@ index 0000000..fd72396 + val &= ~0xc0; + ret = reg16_write(client, 0x381c, val); + break; ++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: ++ ret = 0; ++ break; + } + +out: @@ -1504,7 +2336,6 @@ index 0000000..fd72396 + reg8_write(client, 0x5d, OV10635_I2C_ADDR << 1); /* Sensor native I2C address */ + + reg8_write(client, 0x6e, 0xa9); /* GPIO0 - resetb, GPIO1 - fsin */ -+ udelay(100); + } + + if (priv->ti954_addr) { @@ -1516,10 +2347,11 @@ index 0000000..fd72396 + reg8_write(client, 0x5d, OV10635_I2C_ADDR << 1); /* Sensor native I2C address */ + + reg8_write(client, 0x6e, 0xa9); /* GPIO0 - resetb, GPIO1 - fsin */ -+ udelay(100); + } + client->addr = tmp_addr; + ++ udelay(100); ++ + return 0; +} + @@ -1527,6 +2359,7 @@ index 0000000..fd72396 + const struct i2c_device_id *did) +{ + struct ov10635_priv *priv; ++ struct v4l2_ctrl *ctrl; + int ret; + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); @@ -1562,6 +2395,10 @@ index 0000000..fd72396 + V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); ++ ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops, ++ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 9); ++ if (ctrl) ++ ctrl->flags &= ~V4L2_CTRL_FLAG_READ_ONLY; + priv->sd.ctrl_handler = &priv->hdl; + + ret = priv->hdl.error; @@ -2634,10 +3471,10 @@ index 0000000..66cc490 +{0x6F00, 0x03}, +{0x6F00, 0x43}, +/* enable FSIN (FRAMESYNC input) functionality */ -+{0x3832, 0x00}, -+{0x3833, 0x10}, -+{0x3834, 0x00}, -+{0x3835, 0x10}, ++{0x3832, (0x0d+2*0x20+0x15+38) >> 8}, ++{0x3833, (0x0d+2*0x20+0x15+38) & 0xff}, ++{0x3834, OV10635_VTS >> 8}, ++{0x3835, OV10635_VTS & 0xff}, +{0x302E, 0x01}, +}; + @@ -2857,10 +3694,10 @@ index 0000000..4c3515a +#endif diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c new file mode 100644 -index 0000000..0079bb2 +index 0000000..f2bb706 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov106xx.c -@@ -0,0 +1,95 @@ +@@ -0,0 +1,106 @@ +/* + * OmniVision ov10635/ov490-ov10640/ov495-ov2775 sensor camera driver + * @@ -2875,11 +3712,13 @@ index 0000000..0079bb2 +#include "ov10635.c" +#include "ov490_ov10640.c" +#include "ov495_ov2775.c" ++#include "ar0132.c" + +static enum { + ID_OV10635, + ID_OV490_OV10640, + ID_OV495_OV2775, ++ ID_AR0132, +} chip_id; + +static int ov106xx_probe(struct i2c_client *client, @@ -2906,6 +3745,12 @@ index 0000000..0079bb2 + goto out; + } + ++ ret = ar0132_probe(client, did); ++ if (!ret) { ++ chip_id = ID_AR0132; ++ goto out; ++ } ++ + v4l_err(client, "failed to probe @ 0x%02x (%s)\n", + client->addr, client->adapter->name); +out: @@ -2924,6 +3769,9 @@ index 0000000..0079bb2 + case ID_OV495_OV2775: + ov495_remove(client); + break; ++ case ID_AR0132: ++ ar0132_remove(client); ++ break; + }; + + return 0; @@ -2953,15 +3801,15 @@ index 0000000..0079bb2 + +module_i2c_driver(ov106xx_i2c_driver); + -+MODULE_DESCRIPTION("SoC Camera driver for OV10635 or OV490/OV10640 or OV495/OV2775"); ++MODULE_DESCRIPTION("SoC Camera driver for OV10635 or OV490/OV10640 or OV495/OV2775 or AR0132"); +MODULE_AUTHOR("Vladimir Barinov"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.c b/drivers/media/i2c/soc_camera/ov490_ov10640.c new file mode 100644 -index 0000000..308fe1b +index 0000000..15acc51 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c -@@ -0,0 +1,961 @@ +@@ -0,0 +1,1046 @@ +/* + * OmniVision ov490-ov10640 sensor camera driver + * @@ -3021,8 +3869,8 @@ index 0000000..308fe1b + int ti9x3_addr; + int port; + int gpio_resetb; ++ int active_low_resetb; + int gpio_fsin; -+ +}; + +static int force_conf_link; @@ -3055,6 +3903,48 @@ index 0000000..308fe1b + }; +} + ++static void ov490_reset(struct i2c_client *client) ++{ ++ struct ov490_priv *priv = to_ov490(client); ++ int tmp_addr; ++ ++ if (priv->max9286_addr) { ++ if (priv->gpio_resetb < 1 || priv->gpio_resetb > 5) ++ return; ++ ++ tmp_addr = client->addr; ++ /* get out from sensor reset */ ++ client->addr = priv->max9271_addr; /* MAX9271 I2C address */ ++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) | ++ (priv->active_low_resetb ? 0 : BIT(priv->gpio_resetb))); /* set GPIOn value to reset */ ++ usleep_range(2000, 2500); /* wait 2ms */ ++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) | ++ (priv->active_low_resetb ? BIT(priv->gpio_resetb) : 0)); /* set GPIOn value to un-reset */ ++ usleep_range(2000, 2500); /* wait 2ms */ ++ client->addr = tmp_addr; ++ } ++ ++ if (priv->ti964_addr) { ++ client->addr = priv->ti964_addr; /* TI964 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, 0x6e, 0x8a); /* set GPIO1 value to reset */ ++ usleep_range(2000, 2500); /* wait 2ms */ ++ reg8_write(client, 0x6e, 0x9a); /* set GPIO1 value to un-reset */ ++ } ++ ++ if (priv->ti954_addr) { ++ client->addr = priv->ti954_addr; /* TI964 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, 0x6e, 0x8a); /* set GPIO1 value to reset */ ++ usleep_range(2000, 2500); /* wait 2ms */ ++ reg8_write(client, 0x6e, 0x9a); /* set GPIO1 value to un-reset */ ++ } ++} ++ +static int ov490_set_regs(struct i2c_client *client, + const struct ov490_reg *regs, int nr_regs) +{ @@ -3534,6 +4424,9 @@ index 0000000..308fe1b + ret |= reg16_write(client, 0x00C0, 0xc1); +#endif + break; ++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: ++ ret = 0; ++ break; + } + + return ret; @@ -3630,7 +4523,7 @@ index 0000000..308fe1b + struct ov490_priv *priv = to_ov490(client); + u8 val = 0; + u8 pid = 0, ver = 0; -+ int ret = 0; ++ int ret = 0, timeout, retry_timeout = 3; + + if (priv->is_fixed_sensor) { + dev_info(&client->dev, "ov490/ov10640 fixed-sensor res %dx%d\n", priv->max_width, priv->max_height); @@ -3655,6 +4548,36 @@ index 0000000..308fe1b + if (unlikely(force_conf_link)) + goto out; + ++again: ++ /* Check if firmware booted by reading stream-on status */ ++ reg16_write(client, 0xFFFD, 0x80); ++ reg16_write(client, 0xFFFE, 0x29); ++ usleep_range(100, 150); /* wait 100 us */ ++ timeout = 300; ++ for (;;) { ++ reg16_read(client, 0xd000, &val); ++ if (val == 0x0c || --timeout == 0) ++ break; ++ mdelay(1); ++ } ++ ++ if (!timeout) { ++ dev_err(&client->dev, "Timeout firmware boot wait, retrying\n"); ++ /* reset OV10640 using RESETB pin controlled by OV490 GPIO0 */ ++ reg16_write(client, 0xFFFD, 0x80); ++ reg16_write(client, 0xFFFE, 0x80); ++ usleep_range(100, 150); /* wait 100 us */ ++ reg16_write(client, 0x0050, 0x01); ++ reg16_write(client, 0x0054, 0x01); ++ reg16_write(client, 0x0058, 0x00); ++ mdelay(10); ++ reg16_write(client, 0x0058, 0x01); ++ /* reset OV490 using RESETB pin controlled by serializer */ ++ ov490_reset(client); ++ if (retry_timeout--) ++ goto again; ++ } ++ + /* read resolution used by current firmware */ + reg16_write(client, 0xFFFD, 0x80); + reg16_write(client, 0xFFFE, 0x82); @@ -3709,8 +4632,17 @@ index 0000000..308fe1b + + 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)) ++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) { ++ if (of_property_read_u32(rendpoint->parent->parent, "maxim,resetb-gpio", &priv->gpio_resetb)) { ++ priv->gpio_resetb = -1; ++ } else { ++ if (of_property_read_bool(rendpoint->parent->parent, "maxim,resetb-active-high")) ++ priv->active_low_resetb = false; ++ else ++ priv->active_low_resetb = true; ++ } + break; ++ } + + if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) && + !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti964-ti9x3") && @@ -3750,8 +4682,6 @@ index 0000000..308fe1b + reg8_write(client, 0x5d, OV490_I2C_ADDR << 1); /* Sensor native I2C address */ + + reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */ -+ /* TODO: why too long? move logic to workqueue? */ -+ mdelay(350); /* time needed to boot all sensor IPs */ + } + if (priv->ti954_addr) { + client->addr = priv->ti954_addr; /* Deserializer I2C address */ @@ -3762,8 +4692,6 @@ index 0000000..308fe1b + reg8_write(client, 0x5d, OV490_I2C_ADDR << 1); /* Sensor native I2C address */ + + reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */ -+ /* TODO: why too long? move logic to workqueue? */ -+ mdelay(350); /* time needed to boot all sensor IPs */ + } + client->addr = tmp_addr; + @@ -3795,6 +4723,7 @@ index 0000000..308fe1b + const struct i2c_device_id *did) +{ + struct ov490_priv *priv; ++ struct v4l2_ctrl *ctrl; + int ret; + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); @@ -3830,6 +4759,10 @@ index 0000000..308fe1b + V4L2_CID_HFLIP, 0, 1, 1, 1); + v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); ++ ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops, ++ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 9); ++ if (ctrl) ++ ctrl->flags &= ~V4L2_CTRL_FLAG_READ_ONLY; + priv->sd.ctrl_handler = &priv->hdl; + + ret = priv->hdl.error; @@ -3925,7 +4858,7 @@ index 0000000..308fe1b +#endif diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.h b/drivers/media/i2c/soc_camera/ov490_ov10640.h new file mode 100644 -index 0000000..dde81ef +index 0000000..d3290c7 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov490_ov10640.h @@ -0,0 +1,88 @@ @@ -4019,10 +4952,10 @@ index 0000000..dde81ef +}; diff --git a/drivers/media/i2c/soc_camera/ov495_ov2775.c b/drivers/media/i2c/soc_camera/ov495_ov2775.c new file mode 100644 -index 0000000..56891ff +index 0000000..881615e --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov495_ov2775.c -@@ -0,0 +1,650 @@ +@@ -0,0 +1,658 @@ +/* + * OmniVision ov495-ov2775 sensor camera driver + * @@ -4337,6 +5270,9 @@ index 0000000..56891ff + ret |= reg16_write(client, 0x30C0, 0xdc); + ret |= reg16_write(client, 0x3516, 0x01); + break; ++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: ++ ret = 0; ++ break; + } + + return ret; @@ -4545,6 +5481,7 @@ index 0000000..56891ff + const struct i2c_device_id *did) +{ + struct ov495_priv *priv; ++ struct v4l2_ctrl *ctrl; + int ret; + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); @@ -4580,6 +5517,10 @@ index 0000000..56891ff + V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); ++ ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops, ++ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 9); ++ if (ctrl) ++ ctrl->flags &= ~V4L2_CTRL_FLAG_READ_ONLY; + priv->sd.ctrl_handler = &priv->hdl; + + ret = priv->hdl.error; @@ -4704,7 +5645,7 @@ index 0000000..3f53689 +}; diff --git a/drivers/media/i2c/soc_camera/ti954_ti9x3.c b/drivers/media/i2c/soc_camera/ti954_ti9x3.c new file mode 100644 -index 0000000..f94208d +index 0000000..fc7ccda --- /dev/null +++ b/drivers/media/i2c/soc_camera/ti954_ti9x3.c @@ -0,0 +1,417 @@ @@ -4865,7 +5806,7 @@ index 0000000..f94208d + } + reg8_write(client, 0x70, (idx << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */ + reg8_write(client, 0x7c, 0x81); /* BIT(7) - magic to Use RAW10 as 8-bit mode */ -+ reg8_write(client, 0x6e, 0x99); /* Backchannel GPIO0/GPIO1 set high */ ++ reg8_write(client, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */ +} + +static int ti954_ti9x3_initialize(struct i2c_client *client) @@ -5127,7 +6068,7 @@ index 0000000..f94208d +MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/soc_camera/ti964_ti9x3.c b/drivers/media/i2c/soc_camera/ti964_ti9x3.c new file mode 100644 -index 0000000..567def1 +index 0000000..8dd0f99 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ti964_ti9x3.c @@ -0,0 +1,385 @@ @@ -5261,7 +6202,7 @@ index 0000000..567def1 + } + reg8_write(client, 0x70, (idx << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */ + reg8_write(client, 0x7c, 0x81); /* BIT(7) - magic to Use RAW10 as 8-bit mode */ -+ reg8_write(client, 0x6e, 0x99); /* Backchannel GPIO0/GPIO1 set high */ ++ reg8_write(client, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */ +} + +static int ti964_ti9x3_initialize(struct i2c_client *client) @@ -5518,10 +6459,10 @@ index 0000000..567def1 +MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h b/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h new file mode 100644 -index 0000000..0cee5f1 +index 0000000..69d3728 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h -@@ -0,0 +1,108 @@ +@@ -0,0 +1,153 @@ +/* + * TI FPDLinkIII driver include file + * @@ -5629,9 +6570,54 @@ index 0000000..0cee5f1 + + return ret < 0 ? ret : 0; +} ++ ++static inline int reg16_read16(struct i2c_client *client, u16 reg, u16 *val) ++{ ++ int ret, retries; ++ u8 buf[2] = {reg >> 8, reg & 0xff}; ++ ++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) { ++ ret = i2c_master_send(client, buf, 2); ++ if (ret == 2) { ++ ret = i2c_master_recv(client, buf, 2); ++ if (ret == 2) ++ break; ++ } ++ } ++ ++ if (ret < 0) { ++ dev_err(&client->dev, ++ "read fail: chip 0x%x register 0x%x: %d\n", ++ client->addr, reg, ret); ++ } else { ++ *val = ((u16)buf[0] << 8) | buf[1]; ++ } ++ ++ return ret < 0 ? ret : 0; ++} ++ ++static inline int reg16_write16(struct i2c_client *client, u16 reg, u16 val) ++{ ++ int ret, retries; ++ u8 buf[4] = {reg >> 8, reg & 0xff, val >> 8, val & 0xff}; ++ ++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) { ++ ret = i2c_master_send(client, buf, 4); ++ if (ret == 4) ++ break; ++ } ++ ++ if (ret < 0) { ++ dev_err(&client->dev, ++ "write fail: chip 0x%x register 0x%x: %d\n", ++ client->addr, reg, ret); ++ } ++ ++ return ret < 0 ? ret : 0; ++} +#endif /* _TI9X4_H */ diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c -index 5faac64..cf70414 100644 +index 4d95da6..2ef27e8 100644 --- a/drivers/media/platform/soc_camera/rcar_csi2.c +++ b/drivers/media/platform/soc_camera/rcar_csi2.c @@ -37,8 +37,9 @@ @@ -6117,7 +7103,7 @@ index 5faac64..cf70414 100644 return 0; diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c -index 74fb005..f5c2528 100644 +index 74fb005..496a8bd 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -106,6 +106,7 @@ @@ -6158,17 +7144,18 @@ index 74fb005..f5c2528 100644 /* Synchronous probing compatibility */ struct platform_device *csi2_pdev; -@@ -989,6 +995,9 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) +@@ -989,6 +995,10 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601; input_is_yuv = true; break; + case MEDIA_BUS_FMT_SBGGR8_1X8: ++ case MEDIA_BUS_FMT_SBGGR12_1X12: + vnmc |= VNMC_INF_RAW8 | VNMC_BPS; + break; default: break; } -@@ -1021,6 +1030,10 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) +@@ -1021,6 +1031,10 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) dmr = 0; output_is_yuv = true; break; @@ -6179,27 +7166,29 @@ index 74fb005..f5c2528 100644 case V4L2_PIX_FMT_ARGB555: dmr = VNDMR_DTMD_ARGB; break; -@@ -1043,6 +1056,9 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) +@@ -1043,6 +1057,10 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB; break; + case V4L2_PIX_FMT_SBGGR8: ++ case V4L2_PIX_FMT_SBGGR12: + dmr = 0; + break; default: goto e_format; } -@@ -1061,7 +1077,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) +@@ -1061,7 +1079,9 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) else vnmc |= VNMC_DPINE; - if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) + if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) && -+ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) ++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) && ++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12) && is_scaling(cam)) vnmc |= VNMC_SCLE; } -@@ -1211,6 +1228,10 @@ static void rcar_vin_videobuf_queue(struct vb2_buffer *vb) +@@ -1211,6 +1231,10 @@ static void rcar_vin_videobuf_queue(struct vb2_buffer *vb) */ static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv) { @@ -6210,7 +7199,7 @@ index 74fb005..f5c2528 100644 while (priv->state != STOPPED) { /* issue stop if running */ if (priv->state == RUNNING) -@@ -1361,6 +1382,31 @@ static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev) +@@ -1361,6 +1385,31 @@ static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev) return NULL; } @@ -6242,7 +7231,7 @@ index 74fb005..f5c2528 100644 static int rcar_vin_add_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->parent); -@@ -1375,7 +1421,8 @@ static int rcar_vin_add_device(struct soc_camera_device *icd) +@@ -1375,7 +1424,8 @@ static int rcar_vin_add_device(struct soc_camera_device *icd) if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || priv->chip == RCAR_V3M) { struct v4l2_subdev *csi2_sd = find_csi2(priv); @@ -6252,7 +7241,7 @@ index 74fb005..f5c2528 100644 if (csi2_sd) { csi2_sd->grp_id = soc_camera_grp_id(icd); -@@ -1390,6 +1437,18 @@ static int rcar_vin_add_device(struct soc_camera_device *icd) +@@ -1390,6 +1440,18 @@ static int rcar_vin_add_device(struct soc_camera_device *icd) if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) return ret; } @@ -6271,7 +7260,7 @@ index 74fb005..f5c2528 100644 /* * -ENODEV is special: * either csi2_sd == NULL or the CSI-2 driver -@@ -1417,6 +1476,7 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd) +@@ -1417,6 +1479,7 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd) struct rcar_vin_priv *priv = ici->priv; struct vb2_v4l2_buffer *vbuf; struct v4l2_subdev *csi2_sd = find_csi2(priv); @@ -6279,7 +7268,7 @@ index 74fb005..f5c2528 100644 int i; /* disable capture, disable interrupts */ -@@ -1443,6 +1503,8 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd) +@@ -1443,6 +1506,8 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd) if ((csi2_sd) && (priv->csi_sync)) v4l2_subdev_call(csi2_sd, core, s_power, 0); @@ -6288,27 +7277,29 @@ index 74fb005..f5c2528 100644 dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n", icd->devnum); -@@ -1621,13 +1683,17 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd) +@@ -1621,13 +1686,19 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd) if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 || priv->chip == RCAR_V3M) { - if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) + if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) && -+ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) ++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) && ++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12) && is_scaling(cam)) { ret = rcar_vin_uds_set(priv, cam); if (ret < 0) return ret; } - if (is_scaling(cam) || -+ if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_SBGGR8) ++ if ((icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_SBGGR8) || ++ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_SBGGR12)) + iowrite32(ALIGN(cam->out_width / 2, 0x10), + priv->base + VNIS_REG); + else if (is_scaling(cam) || (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV16) || (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV12)) iowrite32(ALIGN(cam->out_width, 0x20), -@@ -1868,6 +1934,14 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt) +@@ -1868,6 +1939,14 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt) .layout = SOC_MBUS_LAYOUT_PACKED, }, { @@ -6323,7 +7314,7 @@ index 74fb005..f5c2528 100644 .fourcc = V4L2_PIX_FMT_RGB565, .name = "RGB565", .bits_per_sample = 16, -@@ -1899,6 +1973,14 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt) +@@ -1899,6 +1978,22 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt) .order = SOC_MBUS_ORDER_LE, .layout = SOC_MBUS_LAYOUT_PACKED, }, @@ -6335,18 +7326,27 @@ index 74fb005..f5c2528 100644 + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, ++ { ++ .fourcc = V4L2_PIX_FMT_SBGGR12, ++ .name = "Bayer 12 BGGR", ++ .bits_per_sample = 8, ++ .packing = SOC_MBUS_PACKING_NONE, ++ .order = SOC_MBUS_ORDER_LE, ++ .layout = SOC_MBUS_LAYOUT_PACKED, ++ }, }; static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, -@@ -2012,6 +2094,7 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, +@@ -2012,6 +2107,8 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, case MEDIA_BUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_YUYV10_2X10: case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_SBGGR8_1X8: ++ case MEDIA_BUS_FMT_SBGGR12_1X12: if (cam->extra_fmt) break; -@@ -2218,12 +2301,14 @@ static int rcar_vin_set_fmt(struct soc_camera_device *icd, +@@ -2218,12 +2315,15 @@ static int rcar_vin_set_fmt(struct soc_camera_device *icd, case V4L2_PIX_FMT_ABGR32: case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_YUYV: @@ -6358,10 +7358,11 @@ index 74fb005..f5c2528 100644 break; case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_SBGGR8: ++ case V4L2_PIX_FMT_SBGGR12: default: can_scale = false; break; -@@ -2316,7 +2401,8 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd, +@@ -2316,7 +2416,8 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd, /* odd number clipping by pixel post clip processing, */ /* it is outputted to a memory per even pixels. */ if ((pixfmt == V4L2_PIX_FMT_NV16) || (pixfmt == V4L2_PIX_FMT_NV12) || @@ -6371,7 +7372,7 @@ index 74fb005..f5c2528 100644 v4l_bound_align_image(&pix->width, 5, priv->max_width, 1, &pix->height, 2, priv->max_height, 0, 0); else -@@ -2486,6 +2572,19 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, +@@ -2486,6 +2587,19 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, } #endif @@ -6391,7 +7392,7 @@ index 74fb005..f5c2528 100644 static struct soc_camera_host_ops rcar_vin_host_ops = { .owner = THIS_MODULE, .add = rcar_vin_add_device, -@@ -2504,6 +2603,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, +@@ -2504,6 +2618,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, .get_selection = rcar_vin_get_selection, .cropcap = rcar_vin_cropcap, #endif @@ -6399,7 +7400,7 @@ index 74fb005..f5c2528 100644 }; #ifdef CONFIG_OF -@@ -2524,7 +2624,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, +@@ -2524,7 +2639,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd, MODULE_DEVICE_TABLE(of, rcar_vin_of_table); #endif @@ -6408,7 +7409,7 @@ index 74fb005..f5c2528 100644 static DECLARE_BITMAP(device_map, MAP_MAX_NUM); static DEFINE_MUTEX(list_lock); -@@ -2714,7 +2814,11 @@ static int rcar_vin_probe(struct platform_device *pdev) +@@ -2714,7 +2829,11 @@ static int rcar_vin_probe(struct platform_device *pdev) const char *str; unsigned int i; struct device_node *epn = NULL, *ren = NULL; @@ -6420,7 +7421,7 @@ index 74fb005..f5c2528 100644 match = of_match_device(of_match_ptr(rcar_vin_of_table), &pdev->dev); -@@ -2741,13 +2845,27 @@ static int rcar_vin_probe(struct platform_device *pdev) +@@ -2741,13 +2860,27 @@ static int rcar_vin_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "node name:%s\n", of_node_full_name(ren->parent)); @@ -6452,7 +7453,7 @@ index 74fb005..f5c2528 100644 } ret = v4l2_of_parse_endpoint(np, &ep); -@@ -2799,6 +2917,7 @@ static int rcar_vin_probe(struct platform_device *pdev) +@@ -2799,6 +2932,7 @@ static int rcar_vin_probe(struct platform_device *pdev) priv->ici.drv_name = dev_name(&pdev->dev); priv->ici.ops = &rcar_vin_host_ops; priv->csi_sync = false; @@ -6460,7 +7461,7 @@ index 74fb005..f5c2528 100644 priv->pdata_flags = pdata_flags; if (!match) { -@@ -2983,7 +3102,25 @@ static int rcar_vin_probe(struct platform_device *pdev) +@@ -2983,7 +3117,25 @@ static int rcar_vin_probe(struct platform_device *pdev) goto cleanup; if (csi_use) { diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch index 661d02c..4acd0f1 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch @@ -18,18 +18,19 @@ Videobox board on R8A7795 ES1.x SoC Videobox board on R8A7795 SoC Eagle board on R8A7797 SoC V3MSK board on R8A7797 SoC -Kingfisher board on V3M SoC +Kingfisher board on R8A7797 SoC Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> --- - arch/arm64/boot/dts/renesas/Makefile | 15 + - arch/arm64/boot/dts/renesas/legacy/Makefile | 7 + + arch/arm64/boot/dts/renesas/Makefile | 16 + + arch/arm64/boot/dts/renesas/legacy/Makefile | 8 + .../renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts | 1717 +++++++++++++++++++ .../renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts | 441 +++++ .../dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts | 1724 +++++++++++++++++++ .../dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts | 465 +++++ .../dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts | 1214 +++++++++++++ .../dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts | 465 +++++ + .../dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts | 20 + .../boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi | 75 + .../arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi | 77 + .../dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts | 22 + @@ -54,9 +55,9 @@ Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts | 294 ++++ arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi | 518 ++++++ arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi | 46 + - arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 1523 +++++++++++++++++ + arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 1520 +++++++++++++++++ arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi | 515 ++++++ - 34 files changed, 17221 insertions(+) + 35 files changed, 17240 insertions(+) create mode 100644 arch/arm64/boot/dts/renesas/legacy/Makefile create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts @@ -64,6 +65,7 @@ Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts + create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts create mode 100644 arch/arm64/boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi create mode 100644 arch/arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts @@ -92,10 +94,10 @@ Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> create mode 100644 arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile -index 32fb4d9..de2770e 100644 +index 32fb4d9..fd17456 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile -@@ -4,5 +4,20 @@ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-salvator-x.dtb r8a7795-es1-h3ulcb.dtb +@@ -4,5 +4,21 @@ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-salvator-x.dtb r8a7795-es1-h3ulcb.dtb dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb r8a7796-m3ulcb.dtb dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-xs.dtb @@ -110,6 +112,7 @@ index 32fb4d9..de2770e 100644 +dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb.dtb r8a7795-es1-h3ulcb-vb.dtb +dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-eagle.dtb +dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk.dtb ++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-kf.dtb + +# ADAS legacy boards +subdir-y := legacy @@ -118,14 +121,15 @@ index 32fb4d9..de2770e 100644 clean-files := *.dtb diff --git a/arch/arm64/boot/dts/renesas/legacy/Makefile b/arch/arm64/boot/dts/renesas/legacy/Makefile new file mode 100644 -index 0000000..f7de935 +index 0000000..7f25079 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/legacy/Makefile -@@ -0,0 +1,7 @@ +@@ -0,0 +1,8 @@ +# Legacy KF board: V0, V1 (V2 is the same as V1), V3 is latest and deployed in default directory +dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-h3ulcb-kf-v0.dtb r8a7795-es1-h3ulcb-kf-v1.dtb +dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-m3ulcb-kf-v0.dtb r8a7796-m3ulcb-kf-v1.dtb +dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-kf-v0.dtb r8a7795-h3ulcb-kf-v1.dtb ++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-kf-v0.dtb + +always := $(dtb-y) +clean-files := *.dtb @@ -220,7 +224,7 @@ index 0000000..cd23797 + regulator-name = "lvds_on"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; -+ gpio = <&gpio1 24 0>; ++ /* gpio = <&gpio1 24 0>; */ + enable-active-high; + regulator-always-on; + }; @@ -2390,7 +2394,7 @@ index 0000000..f640350 + regulator-name = "lvds_on"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; -+ gpio = <&gpio1 24 0>; ++ /* gpio = <&gpio1 24 0>; */ + enable-active-high; + regulator-always-on; + }; @@ -4591,7 +4595,7 @@ index 0000000..7be2370 + regulator-name = "lvds_on"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; -+ gpio = <&gpio1 24 0>; ++ /* gpio = <&gpio1 24 0>; */ + enable-active-high; + regulator-always-on; + }; @@ -6191,6 +6195,32 @@ index 0000000..637c840 + pcie3v3-supply = <&mpcie_3v3>; + pcie1v8-supply = <&mpcie_1v8>; +}; +diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts +new file mode 100644 +index 0000000..cc04429 +--- /dev/null ++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts +@@ -0,0 +1,20 @@ ++/* ++ * Device Tree Source for the V3MSK Kingfisher V0 board on r8a7797 ++ * ++ * Copyright (C) 2017 Renesas Electronics Corp. ++ * Copyright (C) 2017 Cogent Embedded, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include "../r8a7797-v3msk-kf.dts" ++ ++/ { ++ model = "Renesas V3MSK Kingfisher V0 board based on r8a7797"; ++}; ++ ++&i2cswitch4 { ++ reg = <0x74>; ++}; diff --git a/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi b/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi new file mode 100644 index 0000000..2145f5e @@ -12826,7 +12856,7 @@ new file mode 100644 index 0000000..730cd2a --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts -@@ -0,0 +1,36 @@ +@@ -0,0 +1,40 @@ +/* + * Device Tree Source for the M3ULCB Kingfisher board on r8a7796 + * @@ -12863,6 +12893,10 @@ index 0000000..730cd2a +&hsusb { + status = "okay"; +}; ++ ++&xhci0 { ++ status = "disabled"; ++}; diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts new file mode 100644 index 0000000..1ac0041 @@ -14049,7 +14083,7 @@ index 0000000..f71addf + diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts new file mode 100644 -index 0000000..903d73e +index 0000000..9837e17 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts @@ -0,0 +1,541 @@ @@ -15475,7 +15509,7 @@ new file mode 100644 index 0000000..4ead97a --- /dev/null +++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi -@@ -0,0 +1,1523 @@ +@@ -0,0 +1,1520 @@ +/* + * Device Tree Source for the ULCB Kingfisher board + * @@ -15636,7 +15670,7 @@ index 0000000..4ead97a + /delete-node/sound; + + rsnd_ak4613: sound@1 { -+ pinctrl-0 = <&sound_1_pins>; ++ pinctrl-0 = <&sound_pins>; + pinctrl-names = "default"; + compatible = "simple-audio-card"; + @@ -15812,10 +15846,7 @@ index 0000000..4ead97a + function = "ssi"; + }; + -+ sound_1_pins: sound1 { -+ groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data_a"; -+ function = "ssi"; -+ }; ++ /* sound_pins defined in H3 or M3 ulsb file */ + + sound_2_pins: sound2 { + groups = "ssi6_ctrl", "ssi6_data"; diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg index c0f4237..333b917 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg @@ -25,3 +25,4 @@ CONFIG_VIDEO_RENESAS_IMR=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_PROPERTIES=y CONFIG_HID_MULTITOUCH=y +CONFIG_SERIAL_SH_SCI_DMA=y diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg new file mode 100644 index 0000000..ffc54dc --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg @@ -0,0 +1,32 @@ +CONFIG_ARCH_R8A7797=y +CONFIG_CAN=y +CONFIG_CAN_PEAK_USB=y +CONFIG_CAN_BCM=y +CONFIG_CAN_RAW=y +CONFIG_CAN_DEV=y +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_RCAR=y +CONFIG_CANFD_RCAR=y +CONFIG_DUMMY=y +CONFIG_DRM_I2C_ADV7511=y +CONFIG_GPIO_MAX732X=y +CONFIG_GPIO_MAX732X_IRQ=y +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_VIDEO_ADV_DEBUG=y +CONFIG_VIDEO_RCAR_VIN_LEGACY=y +CONFIG_VIDEO_RCAR_CSI2_LEGACY=y +# CONFIG_VIDEO_RCAR_VIN is not set +# CONFIG_VIDEO_RCAR_CSI2 is not set +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_SCALE_CROP=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_SOC_CAMERA_MAX9286_MAX9271=y +CONFIG_SOC_CAMERA_TI964_TI9X3=y +CONFIG_SOC_CAMERA_TI954_TI9X3=y +CONFIG_SOC_CAMERA_OV106XX=y +CONFIG_VIDEO_RENESAS_IMR=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_HID_MULTITOUCH=y +CONFIG_SERIAL_SH_SCI_DMA=y diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend index 7e4738a..43c9e10 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend @@ -1,5 +1,8 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" +COMPATIBLE_MACHINE_eagle = "eagle" +COMPATIBLE_MACHINE_v3msk = "v3msk" + SRC_URI_append = " \ ${@bb.utils.contains('MACHINE_FEATURES', 'h3ulcb-had', ' file://hyperflash.cfg', '', d)} \ ${@base_conditional("SDHI_SEQ", "1", " file://sdhi_seq.cfg", "", d)} \ @@ -61,6 +64,7 @@ SRC_URI_append_h3ulcb = " file://ulcb.cfg" SRC_URI_append_m3ulcb = " file://ulcb.cfg" SRC_URI_append_salvator-x = " file://salvator-x.cfg" SRC_URI_append_eagle = " file://eagle.cfg" +SRC_URI_append_v3msk = " file://v3msk.cfg" KERNEL_DEVICETREE_append_h3ulcb = " \ renesas/r8a7795-es1-h3ulcb-view.dtb \ @@ -73,11 +77,17 @@ KERNEL_DEVICETREE_append_h3ulcb = " \ renesas/r8a7795-h3ulcb-had-beta.dtb \ renesas/r8a7795-h3ulcb-kf.dtb \ renesas/r8a7795-h3ulcb-vb.dtb \ + renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dtb \ + renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dtb \ + renesas/legacy/r8a7795-h3ulcb-kf-v0.dtb \ + renesas/legacy/r8a7795-h3ulcb-kf-v1.dtb \ " KERNEL_DEVICETREE_append_m3ulcb = " \ renesas/r8a7796-m3ulcb-view.dtb \ renesas/r8a7796-m3ulcb-kf.dtb \ + renesas/legacy/r8a7796-m3ulcb-kf-v0.dtb \ + renesas/legacy/r8a7796-m3ulcb-kf-v1.dtb \ " KERNEL_DEVICETREE_append_salvator-x = " \ @@ -89,3 +99,9 @@ KERNEL_DEVICETREE_append_salvator-x = " \ KERNEL_DEVICETREE_append_eagle = " \ renesas/r8a7797-eagle.dtb \ " + +KERNEL_DEVICETREE_append_v3msk = " \ + renesas/r8a7797-v3msk.dtb \ + renesas/r8a7797-v3msk-kf.dtb \ + renesas/legacy/r8a7797-v3msk-kf-v0.dtb \ +" |