From patchwork Mon Dec 16 10:29:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293721 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7CDF613B6 for ; Mon, 16 Dec 2019 10:29:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5AAC52072D for ; Mon, 16 Dec 2019 10:29:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cNQK6Ljv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727435AbfLPK3g (ORCPT ); Mon, 16 Dec 2019 05:29:36 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40682 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727334AbfLPK3g (ORCPT ); Mon, 16 Dec 2019 05:29:36 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8E572B18; Mon, 16 Dec 2019 11:29:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492173; bh=jcFu7Tj97UoeCndERpqPkxyI+zpiatjBJBfIMK0WV6M=; h=From:To:Subject:Date:In-Reply-To:References:From; b=cNQK6Ljv6RkdmhNXmc6prBunoF7jwbElaMq4GhrGQ4WBy13N9WHf5vvyDNpMxF2El p/ffMYe0AeSAeYB/9kh5ukN/Gmnfr1IsnhqnIbVOnmVCSMvml+P9BllP2CUNI7XENK vUsMBGcjcNIahHyzqVb5UTWpeX7bAGJqaYR3NObY= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 01/13] media: i2c: max9286: Add GPIO chip controller Date: Mon, 16 Dec 2019 10:29:18 +0000 Message-Id: <20191216102930.5867-2-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org From: Kieran Bingham Provide a GPIO chip to control the two output lines available on the MAX9286. Signed-off-by: Kieran Bingham --- drivers/media/i2c/max9286.c | 66 +++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index 4761e0b92ba2..df77871e603c 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -59,6 +60,8 @@ #define MAX9286_HVSRC_D0 (2 << 0) #define MAX9286_HVSRC_D14 (1 << 0) #define MAX9286_HVSRC_D18 (0 << 0) +/* Register 0x0f */ +#define MAX9286_0X0F_RESERVED BIT(3) /* Register 0x12 */ #define MAX9286_CSILANECNT(n) (((n) - 1) << 6) #define MAX9286_CSIDBL BIT(5) @@ -147,6 +150,9 @@ struct max9286_priv { struct regulator *regulator; bool poc_enabled; + struct gpio_chip gpio; + u8 gpio_state; + struct i2c_mux_core *mux; unsigned int mux_channel; bool mux_open; @@ -714,6 +720,58 @@ static const struct of_device_id max9286_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, max9286_dt_ids); +static void max9286_gpio_set(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct max9286_priv *priv = gpiochip_get_data(chip); + + if (value) + priv->gpio_state |= BIT(offset); + else + priv->gpio_state &= ~BIT(offset); + + max9286_write(priv, 0x0f, MAX9286_0X0F_RESERVED | priv->gpio_state); +} + +static int max9286_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct max9286_priv *priv = gpiochip_get_data(chip); + + return priv->gpio_state & BIT(offset); +} + +static int max9286_gpio(struct max9286_priv *priv) +{ + struct device *dev = &priv->client->dev; + struct gpio_chip *gpio = &priv->gpio; + int ret; + + static const char * const names[] = { + "GPIO0OUT", + "GPIO1OUT", + }; + + /* Configure the GPIO */ + gpio->label = dev_name(dev); + gpio->parent = dev; + gpio->owner = THIS_MODULE; + gpio->of_node = dev->of_node; + gpio->ngpio = 2; + gpio->set = max9286_gpio_set; + gpio->get = max9286_gpio_get; + gpio->can_sleep = true; + gpio->names = names; + + /* GPIO values default to high */ + priv->gpio_state = BIT(0) | BIT(1); + + ret = devm_gpiochip_add_data(dev, gpio, priv); + if (ret) + dev_err(dev, "Unable to create gpio_chip\n"); + + return ret; +} + static int max9286_init(struct device *dev) { struct max9286_priv *priv; @@ -994,6 +1052,14 @@ static int max9286_probe(struct i2c_client *client) gpiod_set_consumer_name(priv->gpiod_pwdn, "max9286-pwdn"); gpiod_set_value_cansleep(priv->gpiod_pwdn, 1); + /* + * It is possible to set up the power regulator from the GPIO lines, + * so it needs to be set up early. + */ + ret = max9286_gpio(priv); + if (ret) + return ret; + priv->regulator = regulator_get(&client->dev, "poc"); if (IS_ERR(priv->regulator)) { if (PTR_ERR(priv->regulator) != -EPROBE_DEFER) From patchwork Mon Dec 16 10:29:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293723 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 31354186D for ; Mon, 16 Dec 2019 10:29:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0FA242072D for ; Mon, 16 Dec 2019 10:29:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="GvRUyGoG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727467AbfLPK3g (ORCPT ); Mon, 16 Dec 2019 05:29:36 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40692 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727070AbfLPK3g (ORCPT ); Mon, 16 Dec 2019 05:29:36 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DAAC6B1A; Mon, 16 Dec 2019 11:29:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492174; bh=ZIaWTQb5foHsyW3EPce6shFs7PtfFoP2AqMchE4b1sA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=GvRUyGoG4qAmRJ7mDfKvF2LRBfUqR+3S79qW5VzWO7os3Tsj8xXWqhXGIjONLCJzh 8GgiTp8fHG1AEm4lvPn/CMpiNNJcKqAqcHd3k/xgWiZIiDEu08UIcOodHcEsEclQiH 7Vy9mjlZQPPrwt5x0dYeHOj9XyF7yEkzm/i/yIJA= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 02/13] dt-bindings: media: i2c: Add bindings for IMI RDACM20 Date: Mon, 16 Dec 2019 10:29:19 +0000 Message-Id: <20191216102930.5867-3-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org From: Jacopo Mondi The IMI RDACM20 is a Gigabit Multimedia Serial Link (GMSL) camera capable of transmitting video and I2C control messages on a coax cable physical link for automotive applications. Document its device tree binding interface. Signed-off-by: Jacopo Mondi Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- v2: - Provide imi vendor prefix - Fix minor spelling v3: - update binding descriptions v4: - No change v5: - Specify optional third reg address for the MCU --- .../bindings/media/i2c/imi,rdacm20.txt | 66 +++++++++++++++++++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + 2 files changed, 68 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/imi,rdacm20.txt diff --git a/Documentation/devicetree/bindings/media/i2c/imi,rdacm20.txt b/Documentation/devicetree/bindings/media/i2c/imi,rdacm20.txt new file mode 100644 index 000000000000..4731aafed63f --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/imi,rdacm20.txt @@ -0,0 +1,66 @@ +IMI D&D RDACM20 Automotive Camera Platform +------------------------------------------ + +The IMI D&D RDACM20 is a GMSL-compatible camera designed for automotive +applications. It encloses a Maxim Integrated MAX9271 GMSL serializer, an +Omnivision OV10635 camera sensor and an embedded MCU, and connects to a remote +GMSL endpoint through a coaxial cable. + + IMI RDACM20 + --------------- -------------------------------- +| GMSL | <--- Video Stream | <- Video--------\ | +| |< ====== GMSL Link ======== >|MAX9271<- I2C bus-> <-->OV10635 | +| de-serializer | <--- I2C messages ---> | \<-->MCU | + --------------- -------------------------------- + +The RDACM20 transmits video data generated by the embedded camera sensor on the +GMSL serial channel to a remote GMSL de-serializer, as well as it receives and +transmits I2C messages encapsulated in the GMSL bidirectional control channel. + +All I2C traffic received on the GMSL link not directed to the serializer is +propagated on the local I2C bus to the embedded camera sensor and MCU. All +I2C traffic generated on the local I2C bus not directed to the serializer is +propagated to the remote de-serializer encapsulated in the GMSL control channel. + +The RDACM20 DT node should be a direct child of the GMSL Deserializer's I2C bus +corresponding to the GMSL link that the camera is attached to. + +Required Properties: + +- compatible: Shall be "imi,rdacm20". +- reg: I2C device addresses, the first to be assigned to the serializer + the second to be assigned to the camera sensor. An optional third address can + be provided to specify the MCU address if present. + +Connection to the remote GMSL endpoint are modelled using the OF graph bindings +in accordance with the video interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +The device node contains a single "port" child node with a single "endpoint" +sub-device. + +Required endpoint properties: + +- remote-endpoint: phandle to the remote GMSL endpoint sub-node in the remote + node port. + +Example: +------- + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + camera@51 { + compatible = "imi,rdacm20"; + reg = <0x31 0x41 0x51>; + + port { + rdacm20_out0: endpoint { + remote-endpoint = <&max9286_in0>; + }; + }; + + }; + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 6046f4555852..80042764d2c6 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -429,6 +429,8 @@ patternProperties: description: Ingenieurburo Fur Ic-Technologie (I/F/I) "^ilitek,.*": description: ILI Technology Corporation (ILITEK) + "^imi,.*": + description: Integrated Micro-Electronics Inc. "^img,.*": description: Imagination Technologies Ltd. "^incircuit,.*": From patchwork Mon Dec 16 10:29:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293731 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BF824139A for ; Mon, 16 Dec 2019 10:29:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7FD4D2072D for ; Mon, 16 Dec 2019 10:29:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Unl2VSnA" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727474AbfLPK3l (ORCPT ); Mon, 16 Dec 2019 05:29:41 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40704 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727334AbfLPK3l (ORCPT ); Mon, 16 Dec 2019 05:29:41 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 31865B2A; Mon, 16 Dec 2019 11:29:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492174; bh=ErxgSbn3ZJvHQLuai+BAJ5ezAqCfeEehVfo3T3kEZBI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Unl2VSnAWVYNwJLF4DrYc/5UihP9ByLRefkiMYzIO5WuIYdogv1wf9DACam5PgCl+ 8ywr2mQoeTsUbS4Q/nBAtEr6jAdoPE35Ob9yS1isSztCVeuF2JDcFmrEMm4GryZEaL 5tGJSA5yxDe6lw5unoQeHy9+0b9aKDpM5mrvF+kw= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 03/13] media: i2c: Add RDACM20 driver Date: Mon, 16 Dec 2019 10:29:20 +0000 Message-Id: <20191216102930.5867-4-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org The RDACM20 is a GMSL camera supporting 1280x800 resolution images developed by IMI based on an Omnivision 10635 sensor and a Maxim MAX9271 GMSL serializer. The GMSL link carries power, control (I2C) and video data over a single coax cable. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Signed-off-by: Niklas Söderlund Signed-off-by: Kieran Bingham Reviewed-by: Rob Herring --- v2: - Fix MAINTAINERS entry v3: - Use new V4L2_MBUS_CSI2_DPHY bus type - Remove 'always zero' error print - Fix module description v5: - use sleep rather than busy loops for 10 ms delays - Return ov10635_set_regs directly - Use devm_kzalloc instead of kzalloc in probe() - Or in the flags: dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE - Ensure v4l2_ctrl_handler_free() is called - rdacm20_probe converted to use .probe_new and drop i2c device id tables - Remove rdacm20_g_mbus_config --- MAINTAINERS | 10 + drivers/media/i2c/Kconfig | 11 + drivers/media/i2c/Makefile | 1 + drivers/media/i2c/rdacm20-ov10635.h | 953 ++++++++++++++++++++++++++++ drivers/media/i2c/rdacm20.c | 613 ++++++++++++++++++ 5 files changed, 1588 insertions(+) create mode 100644 drivers/media/i2c/rdacm20-ov10635.h create mode 100644 drivers/media/i2c/rdacm20.c diff --git a/MAINTAINERS b/MAINTAINERS index f3ef49efd4e7..05b3a194b9c4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13873,6 +13873,16 @@ S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev F: tools/testing/selftests/rcutorture +RDACM20 Camera Sensor +M: Jacopo Mondi +M: Kieran Bingham +M: Laurent Pinchart +M: Niklas Söderlund +L: linux-media@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/media/i2c/rdacm20.txt +F: drivers/media/i2c/rdacm20* + RDC R-321X SoC M: Florian Fainelli S: Maintained diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 32a4deb90617..8ec4a1915f8c 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -1047,6 +1047,17 @@ config VIDEO_DW9807_VCM endif +config VIDEO_RDACM20 + tristate "IMI RDACM20 camera support" + depends on I2C && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER + select V4L2_FWNODE + help + This driver supports the IMI RDACM20 GMSL camera, used in + ADAS systems. + + This camera should be used in conjunction with a GMSL + deserialiser such as the MAX9286. + comment "Flash devices" if MEDIA_CAMERA_SUPPORT diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 8896cf8bfc4f..c4f47ebe498f 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -118,5 +118,6 @@ obj-$(CONFIG_VIDEO_IMX319) += imx319.o obj-$(CONFIG_VIDEO_IMX355) += imx355.o obj-$(CONFIG_VIDEO_ST_MIPID02) += st-mipid02.o obj-$(CONFIG_VIDEO_MAX9286) += max9286.o +obj-$(CONFIG_VIDEO_RDACM20) += rdacm20.o obj-$(CONFIG_SDR_MAX2175) += max2175.o diff --git a/drivers/media/i2c/rdacm20-ov10635.h b/drivers/media/i2c/rdacm20-ov10635.h new file mode 100644 index 000000000000..3c53a3262ee2 --- /dev/null +++ b/drivers/media/i2c/rdacm20-ov10635.h @@ -0,0 +1,953 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * IMI RDACM20 camera OV10635 sensor register initialization values + * + * Copyright (C) 2017-2018 Jacopo Mondi + * Copyright (C) 2017-2018 Kieran Bingham + * Copyright (C) 2017-2018 Laurent Pinchart + * Copyright (C) 2017-2018 Niklas Söderlund + * Copyright (C) 2016 Renesas Electronics Corporation + * Copyright (C) 2015 Cogent Embedded, Inc. + * + */ + +/* + * Generated by the OmniVision ov10635 sensor camera wizard for + * 1280x800@30/UYVY/BT601/8bit. + */ + +#ifndef __RDACM20_OV10635_H__ +#define __RDACM20_OV10635_H__ + +#define OV10635_SENSOR_WIDTH 1312 +#define OV10635_SENSOR_HEIGHT 814 + +#define OV10635_MAX_WIDTH 1280 +#define OV10635_MAX_HEIGHT 800 + +/* VTS = PCLK / FPS / HTS / 2 (= 88MHz / 1572 / 30 / 2) */ +#define OV10635_HTS 1572 +/* FPS = 29,9998 */ +#define OV10635_VTS 933 + +struct ov10635_reg { + u16 reg; + u8 val; +}; + +static const struct ov10635_reg ov10635_regs_wizard[] = { + { 0x301b, 0xff }, + { 0x301c, 0xff }, + { 0x301a, 0xff }, + { 0x3011, 0x42 }, + { 0x6900, 0x0c }, + { 0x6901, 0x19 }, + { 0x3503, 0x10 }, + { 0x3025, 0x03 }, + { 0x3003, 0x16 }, + { 0x3004, 0x30 }, + { 0x3005, 0x40 }, + { 0x3006, 0x91 }, + { 0x3600, 0x74 }, + { 0x3601, 0x2b }, + { 0x3612, 0x00 }, + { 0x3611, 0x67 }, + { 0x3633, 0xca }, + { 0x3602, 0xaf }, + { 0x3603, 0x04 }, + { 0x3630, 0x28 }, + { 0x3631, 0x16 }, + { 0x3714, 0x10 }, + { 0x371d, 0x01 }, + { 0x4300, 0x3a }, + { 0x3007, 0x01 }, + { 0x3024, 0x03 }, + { 0x3020, 0x0a }, + { 0x3702, 0x0d }, + { 0x3703, 0x20 }, + { 0x3704, 0x15 }, + { 0x3709, 0xa8 }, + { 0x370c, 0xc7 }, + { 0x370d, 0x80 }, + { 0x3712, 0x00 }, + { 0x3713, 0x20 }, + { 0x3715, 0x04 }, + { 0x381d, 0x40 }, + { 0x381c, 0x00 }, + { 0x3822, 0x50 }, + { 0x3824, 0x10 }, + { 0x3815, 0x8c }, + { 0x3804, 0x05 }, + { 0x3805, 0x1f }, + { 0x3800, 0x00 }, + { 0x3801, 0x00 }, + { 0x3806, 0x03 }, + { 0x3807, 0x28 }, + { 0x3802, 0x00 }, + { 0x3803, 0x07 }, + { 0x3808, 0x05 }, + { 0x3809, 0x00 }, + { 0x380a, 0x03 }, + { 0x380b, 0x20 }, + { 0x380c, OV10635_HTS >> 8 }, + { 0x380d, OV10635_HTS & 0xff }, + { 0x380e, OV10635_VTS >> 8 }, + { 0x380f, OV10635_VTS & 0xff }, + { 0x3813, 0x02 }, + { 0x3811, 0x08 }, + { 0x381f, 0x0c }, + { 0x3819, 0x04 }, + { 0x3804, 0x01 }, + { 0x3805, 0x00 }, + { 0x3828, 0x03 }, + { 0x3829, 0x10 }, + { 0x382a, 0x10 }, + { 0x3621, 0x63 }, + { 0x5005, 0x08 }, + { 0x56d5, 0x00 }, + { 0x56d6, 0x80 }, + { 0x56d7, 0x00 }, + { 0x56d8, 0x00 }, + { 0x56d9, 0x00 }, + { 0x56da, 0x80 }, + { 0x56db, 0x00 }, + { 0x56dc, 0x00 }, + { 0x56e8, 0x00 }, + { 0x56e9, 0x7f }, + { 0x56ea, 0x00 }, + { 0x56eb, 0x7f }, + { 0x5100, 0x00 }, + { 0x5101, 0x80 }, + { 0x5102, 0x00 }, + { 0x5103, 0x80 }, + { 0x5104, 0x00 }, + { 0x5105, 0x80 }, + { 0x5106, 0x00 }, + { 0x5107, 0x80 }, + { 0x5108, 0x00 }, + { 0x5109, 0x00 }, + { 0x510a, 0x00 }, + { 0x510b, 0x00 }, + { 0x510c, 0x00 }, + { 0x510d, 0x00 }, + { 0x510e, 0x00 }, + { 0x510f, 0x00 }, + { 0x5110, 0x00 }, + { 0x5111, 0x80 }, + { 0x5112, 0x00 }, + { 0x5113, 0x80 }, + { 0x5114, 0x00 }, + { 0x5115, 0x80 }, + { 0x5116, 0x00 }, + { 0x5117, 0x80 }, + { 0x5118, 0x00 }, + { 0x5119, 0x00 }, + { 0x511a, 0x00 }, + { 0x511b, 0x00 }, + { 0x511c, 0x00 }, + { 0x511d, 0x00 }, + { 0x511e, 0x00 }, + { 0x511f, 0x00 }, + { 0x56d0, 0x00 }, + { 0x5006, 0x04 }, + { 0x5608, 0x05 }, + { 0x52d7, 0x06 }, + { 0x528d, 0x08 }, + { 0x5293, 0x12 }, + { 0x52d3, 0x12 }, + { 0x5288, 0x06 }, + { 0x5289, 0x20 }, + { 0x52c8, 0x06 }, + { 0x52c9, 0x20 }, + { 0x52cd, 0x04 }, + { 0x5381, 0x00 }, + { 0x5382, 0xff }, + { 0x5589, 0x76 }, + { 0x558a, 0x47 }, + { 0x558b, 0xef }, + { 0x558c, 0xc9 }, + { 0x558d, 0x49 }, + { 0x558e, 0x30 }, + { 0x558f, 0x67 }, + { 0x5590, 0x3f }, + { 0x5591, 0xf0 }, + { 0x5592, 0x10 }, + { 0x55a2, 0x6d }, + { 0x55a3, 0x55 }, + { 0x55a4, 0xc3 }, + { 0x55a5, 0xb5 }, + { 0x55a6, 0x43 }, + { 0x55a7, 0x38 }, + { 0x55a8, 0x5f }, + { 0x55a9, 0x4b }, + { 0x55aa, 0xf0 }, + { 0x55ab, 0x10 }, + { 0x5581, 0x52 }, + { 0x5300, 0x01 }, + { 0x5301, 0x00 }, + { 0x5302, 0x00 }, + { 0x5303, 0x0e }, + { 0x5304, 0x00 }, + { 0x5305, 0x0e }, + { 0x5306, 0x00 }, + { 0x5307, 0x36 }, + { 0x5308, 0x00 }, + { 0x5309, 0xd9 }, + { 0x530a, 0x00 }, + { 0x530b, 0x0f }, + { 0x530c, 0x00 }, + { 0x530d, 0x2c }, + { 0x530e, 0x00 }, + { 0x530f, 0x59 }, + { 0x5310, 0x00 }, + { 0x5311, 0x7b }, + { 0x5312, 0x00 }, + { 0x5313, 0x22 }, + { 0x5314, 0x00 }, + { 0x5315, 0xd5 }, + { 0x5316, 0x00 }, + { 0x5317, 0x13 }, + { 0x5318, 0x00 }, + { 0x5319, 0x18 }, + { 0x531a, 0x00 }, + { 0x531b, 0x26 }, + { 0x531c, 0x00 }, + { 0x531d, 0xdc }, + { 0x531e, 0x00 }, + { 0x531f, 0x02 }, + { 0x5320, 0x00 }, + { 0x5321, 0x24 }, + { 0x5322, 0x00 }, + { 0x5323, 0x56 }, + { 0x5324, 0x00 }, + { 0x5325, 0x85 }, + { 0x5326, 0x00 }, + { 0x5327, 0x20 }, + { 0x5609, 0x01 }, + { 0x560a, 0x40 }, + { 0x560b, 0x01 }, + { 0x560c, 0x40 }, + { 0x560d, 0x00 }, + { 0x560e, 0xfa }, + { 0x560f, 0x00 }, + { 0x5610, 0xfa }, + { 0x5611, 0x02 }, + { 0x5612, 0x80 }, + { 0x5613, 0x02 }, + { 0x5614, 0x80 }, + { 0x5615, 0x01 }, + { 0x5616, 0x2c }, + { 0x5617, 0x01 }, + { 0x5618, 0x2c }, + { 0x563b, 0x01 }, + { 0x563c, 0x01 }, + { 0x563d, 0x01 }, + { 0x563e, 0x01 }, + { 0x563f, 0x03 }, + { 0x5640, 0x03 }, + { 0x5641, 0x03 }, + { 0x5642, 0x05 }, + { 0x5643, 0x09 }, + { 0x5644, 0x05 }, + { 0x5645, 0x05 }, + { 0x5646, 0x05 }, + { 0x5647, 0x05 }, + { 0x5651, 0x00 }, + { 0x5652, 0x80 }, + { 0x521a, 0x01 }, + { 0x521b, 0x03 }, + { 0x521c, 0x06 }, + { 0x521d, 0x0a }, + { 0x521e, 0x0e }, + { 0x521f, 0x12 }, + { 0x5220, 0x16 }, + { 0x5223, 0x02 }, + { 0x5225, 0x04 }, + { 0x5227, 0x08 }, + { 0x5229, 0x0c }, + { 0x522b, 0x12 }, + { 0x522d, 0x18 }, + { 0x522f, 0x1e }, + { 0x5241, 0x04 }, + { 0x5242, 0x01 }, + { 0x5243, 0x03 }, + { 0x5244, 0x06 }, + { 0x5245, 0x0a }, + { 0x5246, 0x0e }, + { 0x5247, 0x12 }, + { 0x5248, 0x16 }, + { 0x524a, 0x03 }, + { 0x524c, 0x04 }, + { 0x524e, 0x08 }, + { 0x5250, 0x0c }, + { 0x5252, 0x12 }, + { 0x5254, 0x18 }, + { 0x5256, 0x1e }, + /* fifo_line_length = 2*hts */ + { 0x4606, (2 * OV10635_HTS) >> 8 }, + { 0x4607, (2 * OV10635_HTS) & 0xff }, + /* fifo_hsync_start = 2*(hts - xres) */ + { 0x460a, (2 * (OV10635_HTS - OV10635_MAX_WIDTH)) >> 8 }, + { 0x460b, (2 * (OV10635_HTS - OV10635_MAX_WIDTH)) & 0xff }, + { 0x460c, 0x00 }, + { 0x4620, 0x0e }, + /* BT601: 0x08 is also acceptable as HS/VS mode */ + { 0x4700, 0x04 }, + { 0x4701, 0x00 }, + { 0x4702, 0x01 }, + { 0x4004, 0x04 }, + { 0x4005, 0x18 }, + { 0x4001, 0x06 }, + { 0x4050, 0x22 }, + { 0x4051, 0x24 }, + { 0x4052, 0x02 }, + { 0x4057, 0x9c }, + { 0x405a, 0x00 }, + { 0x4202, 0x02 }, + { 0x3023, 0x10 }, + { 0x0100, 0x01 }, + { 0x0100, 0x01 }, + { 0x6f10, 0x07 }, + { 0x6f11, 0x82 }, + { 0x6f12, 0x04 }, + { 0x6f13, 0x00 }, + { 0xd000, 0x19 }, + { 0xd001, 0xa0 }, + { 0xd002, 0x00 }, + { 0xd003, 0x01 }, + { 0xd004, 0xa9 }, + { 0xd005, 0xad }, + { 0xd006, 0x10 }, + { 0xd007, 0x40 }, + { 0xd008, 0x44 }, + { 0xd009, 0x00 }, + { 0xd00a, 0x68 }, + { 0xd00b, 0x00 }, + { 0xd00c, 0x15 }, + { 0xd00d, 0x00 }, + { 0xd00e, 0x00 }, + { 0xd00f, 0x00 }, + { 0xd040, 0x9c }, + { 0xd041, 0x21 }, + { 0xd042, 0xff }, + { 0xd043, 0xf8 }, + { 0xd044, 0xd4 }, + { 0xd045, 0x01 }, + { 0xd046, 0x48 }, + { 0xd047, 0x00 }, + { 0xd048, 0xd4 }, + { 0xd049, 0x01 }, + { 0xd04a, 0x50 }, + { 0xd04b, 0x04 }, + { 0xd04c, 0x18 }, + { 0xd04d, 0x60 }, + { 0xd04e, 0x00 }, + { 0xd04f, 0x01 }, + { 0xd050, 0xa8 }, + { 0xd051, 0x63 }, + { 0xd052, 0x02 }, + { 0xd053, 0xa4 }, + { 0xd054, 0x85 }, + { 0xd055, 0x43 }, + { 0xd056, 0x00 }, + { 0xd057, 0x00 }, + { 0xd058, 0x18 }, + { 0xd059, 0x60 }, + { 0xd05a, 0x00 }, + { 0xd05b, 0x01 }, + { 0xd05c, 0xa8 }, + { 0xd05d, 0x63 }, + { 0xd05e, 0x03 }, + { 0xd05f, 0xf0 }, + { 0xd060, 0x98 }, + { 0xd061, 0xa3 }, + { 0xd062, 0x00 }, + { 0xd063, 0x00 }, + { 0xd064, 0x8c }, + { 0xd065, 0x6a }, + { 0xd066, 0x00 }, + { 0xd067, 0x6e }, + { 0xd068, 0xe5 }, + { 0xd069, 0x85 }, + { 0xd06a, 0x18 }, + { 0xd06b, 0x00 }, + { 0xd06c, 0x10 }, + { 0xd06d, 0x00 }, + { 0xd06e, 0x00 }, + { 0xd06f, 0x10 }, + { 0xd070, 0x9c }, + { 0xd071, 0x80 }, + { 0xd072, 0x00 }, + { 0xd073, 0x03 }, + { 0xd074, 0x18 }, + { 0xd075, 0x60 }, + { 0xd076, 0x00 }, + { 0xd077, 0x01 }, + { 0xd078, 0xa8 }, + { 0xd079, 0x63 }, + { 0xd07a, 0x07 }, + { 0xd07b, 0x80 }, + { 0xd07c, 0x07 }, + { 0xd07d, 0xff }, + { 0xd07e, 0xf9 }, + { 0xd07f, 0x03 }, + { 0xd080, 0x8c }, + { 0xd081, 0x63 }, + { 0xd082, 0x00 }, + { 0xd083, 0x00 }, + { 0xd084, 0xa5 }, + { 0xd085, 0x6b }, + { 0xd086, 0x00 }, + { 0xd087, 0xff }, + { 0xd088, 0x18 }, + { 0xd089, 0x80 }, + { 0xd08a, 0x00 }, + { 0xd08b, 0x01 }, + { 0xd08c, 0xa8 }, + { 0xd08d, 0x84 }, + { 0xd08e, 0x01 }, + { 0xd08f, 0x04 }, + { 0xd090, 0xe1 }, + { 0xd091, 0x6b }, + { 0xd092, 0x58 }, + { 0xd093, 0x00 }, + { 0xd094, 0x94 }, + { 0xd095, 0x6a }, + { 0xd096, 0x00 }, + { 0xd097, 0x70 }, + { 0xd098, 0xe1 }, + { 0xd099, 0x6b }, + { 0xd09a, 0x20 }, + { 0xd09b, 0x00 }, + { 0xd09c, 0x95 }, + { 0xd09d, 0x6b }, + { 0xd09e, 0x00 }, + { 0xd09f, 0x00 }, + { 0xd0a0, 0xe4 }, + { 0xd0a1, 0x8b }, + { 0xd0a2, 0x18 }, + { 0xd0a3, 0x00 }, + { 0xd0a4, 0x0c }, + { 0xd0a5, 0x00 }, + { 0xd0a6, 0x00 }, + { 0xd0a7, 0x23 }, + { 0xd0a8, 0x15 }, + { 0xd0a9, 0x00 }, + { 0xd0aa, 0x00 }, + { 0xd0ab, 0x00 }, + { 0xd0ac, 0x18 }, + { 0xd0ad, 0x60 }, + { 0xd0ae, 0x80 }, + { 0xd0af, 0x06 }, + { 0xd0b0, 0xa8 }, + { 0xd0b1, 0x83 }, + { 0xd0b2, 0x40 }, + { 0xd0b3, 0x08 }, + { 0xd0b4, 0xa8 }, + { 0xd0b5, 0xe3 }, + { 0xd0b6, 0x38 }, + { 0xd0b7, 0x2a }, + { 0xd0b8, 0xa8 }, + { 0xd0b9, 0xc3 }, + { 0xd0ba, 0x40 }, + { 0xd0bb, 0x09 }, + { 0xd0bc, 0xa8 }, + { 0xd0bd, 0xa3 }, + { 0xd0be, 0x38 }, + { 0xd0bf, 0x29 }, + { 0xd0c0, 0x8c }, + { 0xd0c1, 0x65 }, + { 0xd0c2, 0x00 }, + { 0xd0c3, 0x00 }, + { 0xd0c4, 0xd8 }, + { 0xd0c5, 0x04 }, + { 0xd0c6, 0x18 }, + { 0xd0c7, 0x00 }, + { 0xd0c8, 0x8c }, + { 0xd0c9, 0x67 }, + { 0xd0ca, 0x00 }, + { 0xd0cb, 0x00 }, + { 0xd0cc, 0xd8 }, + { 0xd0cd, 0x06 }, + { 0xd0ce, 0x18 }, + { 0xd0cf, 0x00 }, + { 0xd0d0, 0x18 }, + { 0xd0d1, 0x60 }, + { 0xd0d2, 0x80 }, + { 0xd0d3, 0x06 }, + { 0xd0d4, 0xa8 }, + { 0xd0d5, 0xe3 }, + { 0xd0d6, 0x67 }, + { 0xd0d7, 0x02 }, + { 0xd0d8, 0xa9 }, + { 0xd0d9, 0x03 }, + { 0xd0da, 0x67 }, + { 0xd0db, 0x03 }, + { 0xd0dc, 0xa8 }, + { 0xd0dd, 0xc3 }, + { 0xd0de, 0x3d }, + { 0xd0df, 0x05 }, + { 0xd0e0, 0x8c }, + { 0xd0e1, 0x66 }, + { 0xd0e2, 0x00 }, + { 0xd0e3, 0x00 }, + { 0xd0e4, 0xb8 }, + { 0xd0e5, 0x63 }, + { 0xd0e6, 0x00 }, + { 0xd0e7, 0x18 }, + { 0xd0e8, 0xb8 }, + { 0xd0e9, 0x63 }, + { 0xd0ea, 0x00 }, + { 0xd0eb, 0x98 }, + { 0xd0ec, 0xbc }, + { 0xd0ed, 0x03 }, + { 0xd0ee, 0x00 }, + { 0xd0ef, 0x00 }, + { 0xd0f0, 0x10 }, + { 0xd0f1, 0x00 }, + { 0xd0f2, 0x00 }, + { 0xd0f3, 0x16 }, + { 0xd0f4, 0xb8 }, + { 0xd0f5, 0x83 }, + { 0xd0f6, 0x00 }, + { 0xd0f7, 0x19 }, + { 0xd0f8, 0x8c }, + { 0xd0f9, 0x67 }, + { 0xd0fa, 0x00 }, + { 0xd0fb, 0x00 }, + { 0xd0fc, 0xb8 }, + { 0xd0fd, 0xa4 }, + { 0xd0fe, 0x00 }, + { 0xd0ff, 0x98 }, + { 0xd100, 0xb8 }, + { 0xd101, 0x83 }, + { 0xd102, 0x00 }, + { 0xd103, 0x08 }, + { 0xd104, 0x8c }, + { 0xd105, 0x68 }, + { 0xd106, 0x00 }, + { 0xd107, 0x00 }, + { 0xd108, 0xe0 }, + { 0xd109, 0x63 }, + { 0xd10a, 0x20 }, + { 0xd10b, 0x04 }, + { 0xd10c, 0xe0 }, + { 0xd10d, 0x65 }, + { 0xd10e, 0x18 }, + { 0xd10f, 0x00 }, + { 0xd110, 0xa4 }, + { 0xd111, 0x83 }, + { 0xd112, 0xff }, + { 0xd113, 0xff }, + { 0xd114, 0xb8 }, + { 0xd115, 0x64 }, + { 0xd116, 0x00 }, + { 0xd117, 0x48 }, + { 0xd118, 0xd8 }, + { 0xd119, 0x07 }, + { 0xd11a, 0x18 }, + { 0xd11b, 0x00 }, + { 0xd11c, 0xd8 }, + { 0xd11d, 0x08 }, + { 0xd11e, 0x20 }, + { 0xd11f, 0x00 }, + { 0xd120, 0x9c }, + { 0xd121, 0x60 }, + { 0xd122, 0x00 }, + { 0xd123, 0x00 }, + { 0xd124, 0xd8 }, + { 0xd125, 0x06 }, + { 0xd126, 0x18 }, + { 0xd127, 0x00 }, + { 0xd128, 0x00 }, + { 0xd129, 0x00 }, + { 0xd12a, 0x00 }, + { 0xd12b, 0x08 }, + { 0xd12c, 0x15 }, + { 0xd12d, 0x00 }, + { 0xd12e, 0x00 }, + { 0xd12f, 0x00 }, + { 0xd130, 0x8c }, + { 0xd131, 0x6a }, + { 0xd132, 0x00 }, + { 0xd133, 0x76 }, + { 0xd134, 0xbc }, + { 0xd135, 0x23 }, + { 0xd136, 0x00 }, + { 0xd137, 0x00 }, + { 0xd138, 0x13 }, + { 0xd139, 0xff }, + { 0xd13a, 0xff }, + { 0xd13b, 0xe6 }, + { 0xd13c, 0x18 }, + { 0xd13d, 0x60 }, + { 0xd13e, 0x80 }, + { 0xd13f, 0x06 }, + { 0xd140, 0x03 }, + { 0xd141, 0xff }, + { 0xd142, 0xff }, + { 0xd143, 0xdd }, + { 0xd144, 0xa8 }, + { 0xd145, 0x83 }, + { 0xd146, 0x40 }, + { 0xd147, 0x08 }, + { 0xd148, 0x85 }, + { 0xd149, 0x21 }, + { 0xd14a, 0x00 }, + { 0xd14b, 0x00 }, + { 0xd14c, 0x85 }, + { 0xd14d, 0x41 }, + { 0xd14e, 0x00 }, + { 0xd14f, 0x04 }, + { 0xd150, 0x44 }, + { 0xd151, 0x00 }, + { 0xd152, 0x48 }, + { 0xd153, 0x00 }, + { 0xd154, 0x9c }, + { 0xd155, 0x21 }, + { 0xd156, 0x00 }, + { 0xd157, 0x08 }, + { 0x6f0e, 0x03 }, + { 0x6f0f, 0x00 }, + { 0x460e, 0x08 }, + { 0x460f, 0x01 }, + { 0x4610, 0x00 }, + { 0x4611, 0x01 }, + { 0x4612, 0x00 }, + { 0x4613, 0x01 }, + /* 8 bits */ + { 0x4605, 0x08 }, + /* Swap data bits order [9:0] -> [0:9] */ + { 0x4709, 0x10 }, + { 0x4608, 0x00 }, + { 0x4609, 0x08 }, + { 0x6804, 0x00 }, + { 0x6805, 0x06 }, + { 0x6806, 0x00 }, + { 0x5120, 0x00 }, + { 0x3510, 0x00 }, + { 0x3504, 0x00 }, + { 0x6800, 0x00 }, + { 0x6f0d, 0x01 }, + /* PCLK falling edge */ + { 0x4708, 0x01 }, + { 0x5000, 0xff }, + { 0x5001, 0xbf }, + { 0x5002, 0x7e }, + { 0x503d, 0x00 }, + { 0xc450, 0x01 }, + { 0xc452, 0x04 }, + { 0xc453, 0x00 }, + { 0xc454, 0x00 }, + { 0xc455, 0x01 }, + { 0xc456, 0x01 }, + { 0xc457, 0x00 }, + { 0xc458, 0x00 }, + { 0xc459, 0x00 }, + { 0xc45b, 0x00 }, + { 0xc45c, 0x01 }, + { 0xc45d, 0x00 }, + { 0xc45e, 0x00 }, + { 0xc45f, 0x00 }, + { 0xc460, 0x00 }, + { 0xc461, 0x01 }, + { 0xc462, 0x01 }, + { 0xc464, 0x03 }, + { 0xc465, 0x00 }, + { 0xc466, 0x8a }, + { 0xc467, 0x00 }, + { 0xc468, 0x86 }, + { 0xc469, 0x00 }, + { 0xc46a, 0x40 }, + { 0xc46b, 0x50 }, + { 0xc46c, 0x30 }, + { 0xc46d, 0x28 }, + { 0xc46e, 0x60 }, + { 0xc46f, 0x40 }, + { 0xc47c, 0x01 }, + { 0xc47d, 0x38 }, + { 0xc47e, 0x00 }, + { 0xc47f, 0x00 }, + { 0xc480, 0x00 }, + { 0xc481, 0xff }, + { 0xc482, 0x00 }, + { 0xc483, 0x40 }, + { 0xc484, 0x00 }, + { 0xc485, 0x18 }, + { 0xc486, 0x00 }, + { 0xc487, 0x18 }, + { 0xc488, (OV10635_VTS - 8) * 16 >> 8}, + { 0xc489, (OV10635_VTS - 8) * 16 & 0xff}, + { 0xc48a, (OV10635_VTS - 8) * 16 >> 8}, + { 0xc48b, (OV10635_VTS - 8) * 16 & 0xff}, + { 0xc48c, 0x00 }, + { 0xc48d, 0x04 }, + { 0xc48e, 0x00 }, + { 0xc48f, 0x04 }, + { 0xc490, 0x03 }, + { 0xc492, 0x20 }, + { 0xc493, 0x08 }, + { 0xc498, 0x02 }, + { 0xc499, 0x00 }, + { 0xc49a, 0x02 }, + { 0xc49b, 0x00 }, + { 0xc49c, 0x02 }, + { 0xc49d, 0x00 }, + { 0xc49e, 0x02 }, + { 0xc49f, 0x60 }, + { 0xc4a0, 0x03 }, + { 0xc4a1, 0x00 }, + { 0xc4a2, 0x04 }, + { 0xc4a3, 0x00 }, + { 0xc4a4, 0x00 }, + { 0xc4a5, 0x10 }, + { 0xc4a6, 0x00 }, + { 0xc4a7, 0x40 }, + { 0xc4a8, 0x00 }, + { 0xc4a9, 0x80 }, + { 0xc4aa, 0x0d }, + { 0xc4ab, 0x00 }, + { 0xc4ac, 0x0f }, + { 0xc4ad, 0xc0 }, + { 0xc4b4, 0x01 }, + { 0xc4b5, 0x01 }, + { 0xc4b6, 0x00 }, + { 0xc4b7, 0x01 }, + { 0xc4b8, 0x00 }, + { 0xc4b9, 0x01 }, + { 0xc4ba, 0x01 }, + { 0xc4bb, 0x00 }, + { 0xc4bc, 0x01 }, + { 0xc4bd, 0x60 }, + { 0xc4be, 0x02 }, + { 0xc4bf, 0x33 }, + { 0xc4c8, 0x03 }, + { 0xc4c9, 0xd0 }, + { 0xc4ca, 0x0e }, + { 0xc4cb, 0x00 }, + { 0xc4cc, 0x0e }, + { 0xc4cd, 0x51 }, + { 0xc4ce, 0x0e }, + { 0xc4cf, 0x51 }, + { 0xc4d0, 0x04 }, + { 0xc4d1, 0x80 }, + { 0xc4e0, 0x04 }, + { 0xc4e1, 0x02 }, + { 0xc4e2, 0x01 }, + { 0xc4e4, 0x10 }, + { 0xc4e5, 0x20 }, + { 0xc4e6, 0x30 }, + { 0xc4e7, 0x40 }, + { 0xc4e8, 0x50 }, + { 0xc4e9, 0x60 }, + { 0xc4ea, 0x70 }, + { 0xc4eb, 0x80 }, + { 0xc4ec, 0x90 }, + { 0xc4ed, 0xa0 }, + { 0xc4ee, 0xb0 }, + { 0xc4ef, 0xc0 }, + { 0xc4f0, 0xd0 }, + { 0xc4f1, 0xe0 }, + { 0xc4f2, 0xf0 }, + { 0xc4f3, 0x80 }, + { 0xc4f4, 0x00 }, + { 0xc4f5, 0x20 }, + { 0xc4f6, 0x02 }, + { 0xc4f7, 0x00 }, + { 0xc4f8, 0x00 }, + { 0xc4f9, 0x00 }, + { 0xc4fa, 0x00 }, + { 0xc4fb, 0x01 }, + { 0xc4fc, 0x01 }, + { 0xc4fd, 0x00 }, + { 0xc4fe, 0x04 }, + { 0xc4ff, 0x02 }, + { 0xc500, 0x48 }, + { 0xc501, 0x74 }, + { 0xc502, 0x58 }, + { 0xc503, 0x80 }, + { 0xc504, 0x05 }, + { 0xc505, 0x80 }, + { 0xc506, 0x03 }, + { 0xc507, 0x80 }, + { 0xc508, 0x01 }, + { 0xc509, 0xc0 }, + { 0xc50a, 0x01 }, + { 0xc50b, 0xa0 }, + { 0xc50c, 0x01 }, + { 0xc50d, 0x2c }, + { 0xc50e, 0x01 }, + { 0xc50f, 0x0a }, + { 0xc510, 0x00 }, + { 0xc511, 0x00 }, + { 0xc512, 0xe5 }, + { 0xc513, 0x14 }, + { 0xc514, 0x04 }, + { 0xc515, 0x00 }, + { 0xc518, OV10635_VTS >> 8}, + { 0xc519, OV10635_VTS & 0xff}, + { 0xc51a, OV10635_HTS >> 8}, + { 0xc51b, OV10635_HTS & 0xff}, + { 0xc2e0, 0x00 }, + { 0xc2e1, 0x51 }, + { 0xc2e2, 0x00 }, + { 0xc2e3, 0xd6 }, + { 0xc2e4, 0x01 }, + { 0xc2e5, 0x5e }, + { 0xc2e9, 0x01 }, + { 0xc2ea, 0x7a }, + { 0xc2eb, 0x90 }, + { 0xc2ed, 0x00 }, + { 0xc2ee, 0x7a }, + { 0xc2ef, 0x64 }, + { 0xc308, 0x00 }, + { 0xc309, 0x00 }, + { 0xc30a, 0x00 }, + { 0xc30c, 0x00 }, + { 0xc30d, 0x01 }, + { 0xc30e, 0x00 }, + { 0xc30f, 0x00 }, + { 0xc310, 0x01 }, + { 0xc311, 0x60 }, + { 0xc312, 0xff }, + { 0xc313, 0x08 }, + { 0xc314, 0x01 }, + { 0xc315, 0x00 }, + { 0xc316, 0xff }, + { 0xc317, 0x0b }, + { 0xc318, 0x00 }, + { 0xc319, 0x0c }, + { 0xc31a, 0x00 }, + { 0xc31b, 0xe0 }, + { 0xc31c, 0x00 }, + { 0xc31d, 0x14 }, + { 0xc31e, 0x00 }, + { 0xc31f, 0xc5 }, + { 0xc320, 0xff }, + { 0xc321, 0x4b }, + { 0xc322, 0xff }, + { 0xc323, 0xf0 }, + { 0xc324, 0xff }, + { 0xc325, 0xe8 }, + { 0xc326, 0x00 }, + { 0xc327, 0x46 }, + { 0xc328, 0xff }, + { 0xc329, 0xd2 }, + { 0xc32a, 0xff }, + { 0xc32b, 0xe4 }, + { 0xc32c, 0xff }, + { 0xc32d, 0xbb }, + { 0xc32e, 0x00 }, + { 0xc32f, 0x61 }, + { 0xc330, 0xff }, + { 0xc331, 0xf9 }, + { 0xc332, 0x00 }, + { 0xc333, 0xd9 }, + { 0xc334, 0x00 }, + { 0xc335, 0x2e }, + { 0xc336, 0x00 }, + { 0xc337, 0xb1 }, + { 0xc338, 0xff }, + { 0xc339, 0x64 }, + { 0xc33a, 0xff }, + { 0xc33b, 0xeb }, + { 0xc33c, 0xff }, + { 0xc33d, 0xe8 }, + { 0xc33e, 0x00 }, + { 0xc33f, 0x48 }, + { 0xc340, 0xff }, + { 0xc341, 0xd0 }, + { 0xc342, 0xff }, + { 0xc343, 0xed }, + { 0xc344, 0xff }, + { 0xc345, 0xad }, + { 0xc346, 0x00 }, + { 0xc347, 0x66 }, + { 0xc348, 0x01 }, + { 0xc349, 0x00 }, + { 0x6700, 0x04 }, + { 0x6701, 0x7b }, + { 0x6702, 0xfd }, + { 0x6703, 0xf9 }, + { 0x6704, 0x3d }, + { 0x6705, 0x71 }, + { 0x6706, 0x78 }, + { 0x6708, 0x05 }, + { 0x6f06, 0x6f }, + { 0x6f07, 0x00 }, + { 0x6f0a, 0x6f }, + { 0x6f0b, 0x00 }, + { 0x6f00, 0x03 }, + { 0xc34c, 0x01 }, + { 0xc34d, 0x00 }, + { 0xc34e, 0x46 }, + { 0xc34f, 0x55 }, + { 0xc350, 0x00 }, + { 0xc351, 0x40 }, + { 0xc352, 0x00 }, + { 0xc353, 0xff }, + { 0xc354, 0x04 }, + { 0xc355, 0x08 }, + { 0xc356, 0x01 }, + { 0xc357, 0xef }, + { 0xc358, 0x30 }, + { 0xc359, 0x01 }, + { 0xc35a, 0x64 }, + { 0xc35b, 0x46 }, + { 0xc35c, 0x00 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, + { 0xc261, 0x01 }, + { 0x301b, 0xf0 }, + { 0x301c, 0xf0 }, + { 0x301a, 0xf0 }, + { 0x6f00, 0xc3 }, + { 0xc46a, 0x30 }, + { 0xc46d, 0x20 }, + { 0xc464, 0x84 }, + { 0xc465, 0x00 }, + { 0x6f00, 0x03 }, + { 0x6f00, 0x43 }, + { 0x381c, 0x00 }, + { 0x381d, 0x40 }, + { 0xc454, 0x01 }, + { 0x6f00, 0xc3 }, + { 0xc454, 0x00 }, + { 0xc4b1, 0x02 }, + { 0xc4b2, 0x01 }, + { 0xc4b3, 0x03 }, + { 0x6f00, 0x03 }, + { 0x6f00, 0x43 }, + /* enable FSIN (FRAMESYNC input) functionality */ + { 0x3832, (0x0d + 2 * 0x20 + 0x15 + 38) >> 8 }, + { 0x3833, (0x0d + 2 * 0x20 + 0x15 + 38) & 0xff }, + { 0x3834, OV10635_VTS >> 8 }, + { 0x3835, OV10635_VTS & 0xff }, + { 0x302e, 0x01 }, +}; + +#endif /* __RDACM20_OV10635_H__ */ diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c new file mode 100644 index 000000000000..c21a6cbe6ded --- /dev/null +++ b/drivers/media/i2c/rdacm20.c @@ -0,0 +1,613 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * IMI RDACM20 GMSL Camera Driver + * + * Copyright (C) 2017-2018 Jacopo Mondi + * Copyright (C) 2017-2018 Kieran Bingham + * Copyright (C) 2017-2018 Laurent Pinchart + * Copyright (C) 2017-2018 Niklas Söderlund + * Copyright (C) 2016 Renesas Electronics Corporation + * Copyright (C) 2015 Cogent Embedded, Inc. + */ + +/* + * The camera is mode of an Omnivision OV10635 sensor connected to a Maxim + * MAX9271 GMSL serializer. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "rdacm20-ov10635.h" + +#define RDACM20_SENSOR_HARD_RESET + +#define MAX9271_I2C_ADDRESS 0x40 + +/* Register 0x04 */ +#define MAX9271_SEREN BIT(7) +#define MAX9271_CLINKEN BIT(6) +#define MAX9271_PRBSEN BIT(5) +#define MAX9271_SLEEP BIT(4) +#define MAX9271_INTTYPE_I2C (0 << 2) +#define MAX9271_INTTYPE_UART (1 << 2) +#define MAX9271_INTTYPE_NONE (2 << 2) +#define MAX9271_REVCCEN BIT(1) +#define MAX9271_FWDCCEN BIT(0) +/* Register 0x07 */ +#define MAX9271_DBL BIT(7) +#define MAX9271_DRS BIT(6) +#define MAX9271_BWS BIT(5) +#define MAX9271_ES BIT(4) +#define MAX9271_HVEN BIT(2) +#define MAX9271_EDC_1BIT_PARITY (0 << 0) +#define MAX9271_EDC_6BIT_CRC (1 << 0) +#define MAX9271_EDC_6BIT_HAMMING (2 << 0) +/* Register 0x08 */ +#define MAX9271_INVVS BIT(7) +#define MAX9271_INVHS BIT(6) +#define MAX9271_REV_LOGAIN BIT(3) +#define MAX9271_REV_HIVTH BIT(0) +/* Register 0x09 */ +#define MAX9271_ID 0x09 +/* Register 0x0d */ +#define MAX9271_I2CLOCACK BIT(7) +#define MAX9271_I2CSLVSH_1046NS_469NS (3 << 5) +#define MAX9271_I2CSLVSH_938NS_352NS (2 << 5) +#define MAX9271_I2CSLVSH_469NS_234NS (1 << 5) +#define MAX9271_I2CSLVSH_352NS_117NS (0 << 5) +#define MAX9271_I2CMSTBT_837KBPS (7 << 2) +#define MAX9271_I2CMSTBT_533KBPS (6 << 2) +#define MAX9271_I2CMSTBT_339KBPS (5 << 2) +#define MAX9271_I2CMSTBT_173KBPS (4 << 2) +#define MAX9271_I2CMSTBT_105KBPS (3 << 2) +#define MAX9271_I2CMSTBT_84KBPS (2 << 2) +#define MAX9271_I2CMSTBT_28KBPS (1 << 2) +#define MAX9271_I2CMSTBT_8KBPS (0 << 2) +#define MAX9271_I2CSLVTO_NONE (3 << 0) +#define MAX9271_I2CSLVTO_1024US (2 << 0) +#define MAX9271_I2CSLVTO_256US (1 << 0) +#define MAX9271_I2CSLVTO_64US (0 << 0) +/* Register 0x0f */ +#define MAX9271_GPIO5OUT BIT(5) +#define MAX9271_GPIO4OUT BIT(4) +#define MAX9271_GPIO3OUT BIT(3) +#define MAX9271_GPIO2OUT BIT(2) +#define MAX9271_GPIO1OUT BIT(1) +#define MAX9271_SETGPO BIT(0) +/* Register 0x15 */ +#define MAX9271_PCLKDET BIT(0) + +#define MAXIM_I2C_I2C_SPEED_400KHZ MAX9271_I2CMSTBT_339KBPS +#define MAXIM_I2C_I2C_SPEED_100KHZ MAX9271_I2CMSTBT_105KBPS +#define MAXIM_I2C_SPEED MAXIM_I2C_I2C_SPEED_100KHZ + +#define OV10635_I2C_ADDRESS 0x30 + +#define OV10635_SOFTWARE_RESET 0x0103 +#define OV10635_PID 0x300a +#define OV10635_VER 0x300b +#define OV10635_SC_CMMN_SCCB_ID 0x300c +#define OV10635_SC_CMMN_SCCB_ID_SELECT BIT(0) +#define OV10635_VERSION 0xa635 + +#define OV10635_WIDTH 1280 +#define OV10635_HEIGHT 800 +#define OV10635_FORMAT MEDIA_BUS_FMT_UYVY8_2X8 +/* #define OV10635_FORMAT MEDIA_BUS_FMT_UYVY10_2X10 */ + +struct rdacm20_device { + struct i2c_client *client; + struct i2c_client *sensor; + struct v4l2_subdev sd; + struct media_pad pad; + struct v4l2_ctrl_handler ctrls; +}; + +static inline struct rdacm20_device *sd_to_rdacm20(struct v4l2_subdev *sd) +{ + return container_of(sd, struct rdacm20_device, sd); +} + +static inline struct rdacm20_device *i2c_to_rdacm20(struct i2c_client *client) +{ + return sd_to_rdacm20(i2c_get_clientdata(client)); +} + +static int max9271_read(struct rdacm20_device *dev, u8 reg) +{ + int ret; + + dev_dbg(&dev->client->dev, "%s(0x%02x)\n", __func__, reg); + + ret = i2c_smbus_read_byte_data(dev->client, reg); + if (ret < 0) + dev_dbg(&dev->client->dev, + "%s: register 0x%02x read failed (%d)\n", + __func__, reg, ret); + + return ret; +} + +static int max9271_write(struct rdacm20_device *dev, u8 reg, u8 val) +{ + int ret; + + dev_dbg(&dev->client->dev, "%s(0x%02x, 0x%02x)\n", __func__, reg, val); + + ret = i2c_smbus_write_byte_data(dev->client, reg, val); + if (ret < 0) + dev_err(&dev->client->dev, + "%s: register 0x%02x write failed (%d)\n", + __func__, reg, ret); + + return ret; +} + +static int ov10635_read16(struct rdacm20_device *dev, u16 reg) +{ + u8 buf[2] = { reg >> 8, reg & 0xff }; + int ret; + + ret = i2c_master_send(dev->sensor, buf, 2); + if (ret == 2) + ret = i2c_master_recv(dev->sensor, buf, 2); + + if (ret < 0) { + dev_dbg(&dev->client->dev, + "%s: register 0x%04x read failed (%d)\n", + __func__, reg, ret); + return ret; + } + + return (buf[0] << 8) | buf[1]; +} + +static int __ov10635_write(struct rdacm20_device *dev, u16 reg, u8 val) +{ + u8 buf[3] = { reg >> 8, reg & 0xff, val }; + int ret; + + dev_dbg(&dev->client->dev, "%s(0x%04x, 0x%02x)\n", __func__, reg, val); + + ret = i2c_master_send(dev->sensor, buf, 3); + return ret < 0 ? ret : 0; +} + +static int ov10635_write(struct rdacm20_device *dev, u16 reg, u8 val) +{ + int ret; + + ret = __ov10635_write(dev, reg, val); + if (ret < 0) + dev_err(&dev->client->dev, + "%s: register 0x%04x write failed (%d)\n", + __func__, reg, ret); + + return ret; +} + +static int ov10635_set_regs(struct rdacm20_device *dev, + const struct ov10635_reg *regs, + unsigned int nr_regs) +{ + unsigned int i; + int ret; + + for (i = 0; i < nr_regs; i++) { + ret = __ov10635_write(dev, regs[i].reg, regs[i].val); + if (ret) { + dev_err(&dev->client->dev, + "%s: register %u (0x%04x) write failed (%d)\n", + __func__, i, regs[i].reg, ret); + return ret; + } + } + + return 0; +} + +/* + * rdacm20_pclk_detect() - Detect valid pixel clock from image sensor + * + * Wait up to 10ms for a valid pixel clock. + * + * Returns 0 for success, < 0 for pixel clock not properly detected + */ +static int rdacm20_pclk_detect(struct rdacm20_device *dev) +{ + unsigned int i; + int ret; + + for (i = 0; i < 100; i++) { + ret = max9271_read(dev, 0x15); + if (ret < 0) + return ret; + + if (ret & MAX9271_PCLKDET) + return 0; + + usleep_range(50, 100); + } + + dev_err(&dev->client->dev, "Unable to detect valid pixel clock\n"); + return -EIO; +} + +static int rdacm20_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct rdacm20_device *dev = sd_to_rdacm20(sd); + int ret; + + if (enable) { + ret = rdacm20_pclk_detect(dev); + if (ret) + return ret; + + /* Enable the serial link. */ + max9271_write(dev, 0x04, MAX9271_SEREN | MAX9271_REVCCEN | + MAX9271_FWDCCEN); + } else { + /* Disable the serial link. */ + max9271_write(dev, 0x04, MAX9271_CLINKEN | MAX9271_REVCCEN | + MAX9271_FWDCCEN); + } + + return 0; +} + +static int rdacm20_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 = OV10635_FORMAT; + + return 0; +} + +static int rdacm20_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *mf = &format->format; + + if (format->pad) + return -EINVAL; + + mf->width = OV10635_WIDTH; + mf->height = OV10635_HEIGHT; + mf->code = OV10635_FORMAT; + mf->colorspace = V4L2_COLORSPACE_RAW; + mf->field = V4L2_FIELD_NONE; + mf->ycbcr_enc = V4L2_YCBCR_ENC_601; + mf->quantization = V4L2_QUANTIZATION_FULL_RANGE; + mf->xfer_func = V4L2_XFER_FUNC_NONE; + + return 0; +} + +static struct v4l2_subdev_video_ops rdacm20_video_ops = { + .s_stream = rdacm20_s_stream, +}; + +static const struct v4l2_subdev_pad_ops rdacm20_subdev_pad_ops = { + .enum_mbus_code = rdacm20_enum_mbus_code, + .get_fmt = rdacm20_get_fmt, + .set_fmt = rdacm20_get_fmt, +}; + +static struct v4l2_subdev_ops rdacm20_subdev_ops = { + .video = &rdacm20_video_ops, + .pad = &rdacm20_subdev_pad_ops, +}; + +static int max9271_configure_i2c(struct rdacm20_device *dev) +{ + /* + * Configure the I2C bus: + * + * - Enable high thresholds on the reverse channel + * - Disable artificial ACK and set I2C speed + */ + max9271_write(dev, 0x08, MAX9271_REV_HIVTH); + usleep_range(5000, 8000); + + max9271_write(dev, 0x0d, MAX9271_I2CSLVSH_469NS_234NS | + MAX9271_I2CSLVTO_1024US | MAXIM_I2C_SPEED); + usleep_range(5000, 8000); + + return 0; +} + +static int max9271_configure_gmsl_link(struct rdacm20_device *dev) +{ + /* + * Disable the serial link and enable the configuration link to allow + * the control channel to operate in a low-speed mode in the absence of + * the serial link clock. + */ + max9271_write(dev, 0x04, MAX9271_CLINKEN | MAX9271_REVCCEN | + MAX9271_FWDCCEN); + + /* + * The serializer temporarily disables the reverse control channel for + * 350µs after starting/stopping the forward serial link, but the + * deserializer synchronization time isn't clearly documented. + * + * According to the serializer datasheet we should wait 3ms, while + * according to the deserializer datasheet we should wait 5ms. + * + * Short delays here appear to show bit-errors in the writes following. + * Therefore a conservative delay seems best here. + */ + usleep_range(5000, 8000); + + /* + * Configure the GMSL link: + * + * - Double input mode, high data rate, 24-bit mode + * - Latch input data on PCLKIN rising edge + * - Enable HS/VS encoding + * - 1-bit parity error detection + */ + max9271_write(dev, 0x07, MAX9271_DBL | MAX9271_HVEN | + MAX9271_EDC_1BIT_PARITY); + usleep_range(5000, 8000); + + return 0; +} + +static int max9271_verify_id(struct rdacm20_device *dev) +{ + int ret; + + ret = max9271_read(dev, 0x1e); + if (ret < 0) { + dev_err(&dev->client->dev, "MAX9271 ID read failed (%d)\n", + ret); + return ret; + } + + if (ret != MAX9271_ID) { + dev_err(&dev->client->dev, "MAX9271 ID mismatch (0x%02x)\n", + ret); + return -ENXIO; + } + + return 0; +} + +static int max9271_configure_address(struct rdacm20_device *dev, u8 addr) +{ + int ret; + + /* Change the MAX9271 I2C address. */ + ret = max9271_write(dev, 0x00, addr << 1); + if (ret < 0) { + dev_err(&dev->client->dev, + "MAX9271 I2C address change failed (%d)\n", ret); + return ret; + } + dev->client->addr = addr; + usleep_range(3500, 5000); + + return 0; +} + +static int rdacm20_initialize(struct rdacm20_device *dev) +{ + u32 addrs[2]; + int ret; + + ret = of_property_read_u32_array(dev->client->dev.of_node, "reg", + addrs, ARRAY_SIZE(addrs)); + if (ret < 0) { + dev_err(&dev->client->dev, "Invalid DT reg property\n"); + return -EINVAL; + } + + /* + * FIXME: The MAX9271 boots at a default address that we will change to + * the address specified in DT. Set the client address back to the + * default for initial communication. + */ + dev->client->addr = MAX9271_I2C_ADDRESS; + + /* Verify communication with the MAX9271. */ + i2c_smbus_read_byte(dev->client); /* ping to wake-up */ + + /* + * Ensure that we have a good link configuration before attempting to + * identify the device. + */ + max9271_configure_i2c(dev); + max9271_configure_gmsl_link(dev); + + ret = max9271_verify_id(dev); + if (ret < 0) + return ret; + + ret = max9271_configure_address(dev, addrs[0]); + if (ret < 0) + return ret; + + /* Reset and verify communication with the OV10635. */ +#ifdef RDACM20_SENSOR_HARD_RESET + /* Cycle the OV10635 reset signal connected to the MAX9271 GPIO1. */ + max9271_write(dev, 0x0f, 0xff & ~(MAX9271_GPIO1OUT | MAX9271_SETGPO)); + usleep_range(10000, 20000); + max9271_write(dev, 0x0f, 0xff & ~MAX9271_SETGPO); + usleep_range(10000, 20000); +#else + /* Perform a software reset. */ + ret = ov10635_write(dev, OV10635_SOFTWARE_RESET, 1); + if (ret < 0) { + dev_err(&dev->client->dev, "OV10635 reset failed (%d)\n", ret); + return -ENXIO; + } + + udelay(100); +#endif + + ret = ov10635_read16(dev, OV10635_PID); + if (ret < 0) { + dev_err(&dev->client->dev, "OV10635 ID read failed (%d)\n", + ret); + return -ENXIO; + } + + if (ret != OV10635_VERSION) { + dev_err(&dev->client->dev, "OV10635 ID mismatch (0x%04x)\n", + ret); + return -ENXIO; + } + + dev_info(&dev->client->dev, "Identified MAX9271 + OV10635 device\n"); + + /* Change the sensor I2C address. */ + ret = ov10635_write(dev, OV10635_SC_CMMN_SCCB_ID, + (addrs[1] << 1) | OV10635_SC_CMMN_SCCB_ID_SELECT); + if (ret < 0) { + dev_err(&dev->client->dev, + "OV10635 I2C address change failed (%d)\n", ret); + return ret; + } + dev->sensor->addr = addrs[1]; + usleep_range(3500, 5000); + + /* Program the 0V10635 initial configuration. */ + return ov10635_set_regs(dev, ov10635_regs_wizard, + ARRAY_SIZE(ov10635_regs_wizard)); +} + +static int rdacm20_probe(struct i2c_client *client) +{ + struct rdacm20_device *dev; + struct fwnode_handle *ep; + int ret; + + dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + dev->client = client; + + /* Create the dummy I2C client for the sensor. */ + dev->sensor = i2c_new_dummy(client->adapter, OV10635_I2C_ADDRESS); + if (!dev->sensor) { + ret = -ENXIO; + goto error; + } + + /* Initialize the hardware. */ + ret = rdacm20_initialize(dev); + if (ret < 0) + goto error; + + /* Initialize and register the subdevice. */ + v4l2_i2c_subdev_init(&dev->sd, client, &rdacm20_subdev_ops); + dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + + v4l2_ctrl_handler_init(&dev->ctrls, 1); + /* + * FIXME: Compute the real pixel rate. The 50 MP/s value comes from the + * hardcoded frequency in the BSP CSI-2 receiver driver. + */ + v4l2_ctrl_new_std(&dev->ctrls, NULL, V4L2_CID_PIXEL_RATE, 50000000, + 50000000, 1, 50000000); + dev->sd.ctrl_handler = &dev->ctrls; + + ret = dev->ctrls.error; + if (ret) + goto error_free_ctrls; + + dev->pad.flags = MEDIA_PAD_FL_SOURCE; + dev->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR; + ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); + if (ret < 0) + goto error_free_ctrls; + + ep = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL); + if (!ep) { + dev_err(&client->dev, + "Unable to get endpoint in node %pOF\n", + client->dev.of_node); + ret = -ENOENT; + goto error_free_ctrls; + } + dev->sd.fwnode = ep; + + ret = v4l2_async_register_subdev(&dev->sd); + if (ret) + goto error_put_node; + + return 0; + +error_put_node: + fwnode_handle_put(ep); +error_free_ctrls: + v4l2_ctrl_handler_free(&dev->ctrls); +error: + media_entity_cleanup(&dev->sd.entity); + if (dev->sensor) + i2c_unregister_device(dev->sensor); + + dev_err(&client->dev, "probe failed\n"); + + return ret; +} + +static int rdacm20_remove(struct i2c_client *client) +{ + struct rdacm20_device *dev = i2c_to_rdacm20(client); + + fwnode_handle_put(dev->sd.fwnode); + v4l2_async_unregister_subdev(&dev->sd); + v4l2_ctrl_handler_free(&dev->ctrls); + media_entity_cleanup(&dev->sd.entity); + i2c_unregister_device(dev->sensor); + + return 0; +} + +static void rdacm20_shutdown(struct i2c_client *client) +{ + struct rdacm20_device *dev = i2c_to_rdacm20(client); + + /* make sure stream off during shutdown (reset/reboot) */ + rdacm20_s_stream(&dev->sd, 0); +} + +static const struct of_device_id rdacm20_of_ids[] = { + { .compatible = "imi,rdacm20", }, + { } +}; +MODULE_DEVICE_TABLE(of, rdacm20_of_ids); + +static struct i2c_driver rdacm20_i2c_driver = { + .driver = { + .name = "rdacm20", + .of_match_table = rdacm20_of_ids, + }, + .probe_new = rdacm20_probe, + .remove = rdacm20_remove, + .shutdown = rdacm20_shutdown, +}; + +module_i2c_driver(rdacm20_i2c_driver); + +MODULE_DESCRIPTION("GMSL Camera driver for RDACM20"); +MODULE_AUTHOR("Vladimir Barinov"); +MODULE_LICENSE("GPL"); From patchwork Mon Dec 16 10:29:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293727 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5ED1B139A for ; Mon, 16 Dec 2019 10:29:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 32B7A20725 for ; Mon, 16 Dec 2019 10:29:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="G960wV45" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727436AbfLPK3i (ORCPT ); Mon, 16 Dec 2019 05:29:38 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40692 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727070AbfLPK3h (ORCPT ); Mon, 16 Dec 2019 05:29:37 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 908A21170; Mon, 16 Dec 2019 11:29:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492174; bh=bLgoGWpMfLhIxX+u92B25Ll8zAnWSzgu0IFdujBe/cc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=G960wV450pFXkqIAKOc19BFZ+wtETEvoh5zP7vmsWpTEGSiF3nlFv/fiAnMCC5kri 2aeDE9u68WtZfTyq8HBO6rdtO/grpzCeEw+SQLEmBNeGPAIzSw4AdHNwml0xyPHmWf B0IqL7dySbPXLNh3GvWXEPunexgm7jm0scwll2PY= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 04/13] arm64: dts: renesas: eagle: enable VIN Date: Mon, 16 Dec 2019 10:29:21 +0000 Message-Id: <20191216102930.5867-5-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org From: Niklas Söderlund Enable VIN0-VIN3 on the Eagle platform. Signed-off-by: Niklas Söderlund [Kieran: Rebase to linux-media/master] Signed-off-by: Kieran Bingham --- arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts index 2afb91ec9c8d..2be89ed879a5 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts +++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts @@ -206,3 +206,19 @@ status = "okay"; }; + +&vin0 { + status = "okay"; +}; + +&vin1 { + status = "okay"; +}; + +&vin2 { + status = "okay"; +}; + +&vin3 { + status = "okay"; +}; From patchwork Mon Dec 16 10:29:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293729 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 67C38138C for ; Mon, 16 Dec 2019 10:29:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 462E92072D for ; Mon, 16 Dec 2019 10:29:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CRcP1LmS" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727470AbfLPK3k (ORCPT ); Mon, 16 Dec 2019 05:29:40 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40692 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727070AbfLPK3j (ORCPT ); Mon, 16 Dec 2019 05:29:39 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DCBBD130D; Mon, 16 Dec 2019 11:29:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492175; bh=SDhpg95pNYwvTDG8mWp7nEbGSj6l4DgwHKU7WgYNMFc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=CRcP1LmSoPLRCJSII2TUCiM3IvETSrZ4An9JtZt3rD3xW15lgh9YZgBfknLY5SF7W 2K3WePNvTQSXNMb0qEMZlokP/25BYK4P5pCMpo/W5HpMfcTrehfPjpQRYPek+Xm4te kI/e5NOQWDRmUZwVhiUUrYkRH5Qr5lXZRNeS9t10= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 05/13] arm64: dts: renesas: eagle: Provide MAX9286 GMSL deserialiser Date: Mon, 16 Dec 2019 10:29:22 +0000 Message-Id: <20191216102930.5867-6-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org From: Kieran Bingham Provide the wiring for the MAX9286 populated on the Eagle-V3M board which has 4 FAKRA connectors. No cameras are connected, and the I2C muxes are disabled by default. Connected cameras should be defined in a device-tree overlay or included after these definitions. Signed-off-by: Kieran Bingham --- v2 - Rebase to mainline, and fix DTB merge issues. v3: - Fix up gmsl-serialiszer i2c bus unit address v6: - Use new i2c-mux subnode - Make use of the GPIO controller exposed by the max9286 to expose a hog on the line we need to hold low for camera power. Produces this: gpiochip7 - 2 lines: line 0: "GPIO0OUT" "CSI0_CAMVDD_EN" output active-high [used] line 1: "GPIO1OUT" unused output active-high - Remove the powerdown hog, and utilise an optional enable-gpio line instead. --- .../arm64/boot/dts/renesas/r8a77970-eagle.dts | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts index 2be89ed879a5..86caf98e9eb0 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts +++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts @@ -6,6 +6,8 @@ * Copyright (C) 2017 Cogent Embedded, Inc. */ +#include + /dts-v1/; #include "r8a77970.dtsi" @@ -189,6 +191,11 @@ function = "i2c0"; }; + i2c3_pins: i2c3 { + groups = "i2c3_a"; + function = "i2c3"; + }; + scif0_pins: scif0 { groups = "scif0_data"; function = "scif0"; @@ -200,6 +207,134 @@ status = "okay"; }; +&csi40 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + csi40_in: endpoint { + clock-lanes = <0>; + data-lanes = <1 2 3 4>; + remote-endpoint = <&max9286_out0>; + }; + }; + }; +}; + +&i2c3 { + pinctrl-0 = <&i2c3_pins>; + pinctrl-names = "default"; + + status = "okay"; + clock-frequency = <400000>; + + gmsl: gmsl-deserializer@48 { + gpio-controller; + #gpio-cells = <2>; + + compatible = "maxim,max9286"; + reg = <0x48>; + + #address-cells = <1>; + #size-cells = <0>; + + /* eagle-pca9654-max9286-pwdn */ + enable-gpios = <&io_expander 0 GPIO_ACTIVE_HIGH>; + + /* + * Workaround: Hog the CAMVDD line high as we can't establish a + * regulator-fixed on the gpio_chip exposed by &gmsl due to + * circular-dependency issues. + */ + camvdd_en { + gpio-hog; + gpios = <0 0>; + output-low; + line-name = "CSI0_CAMVDD_EN"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + max9286_in0: endpoint { + }; + }; + + port@1 { + reg = <1>; + max9286_in1: endpoint { + }; + }; + + port@2 { + reg = <2>; + max9286_in2: endpoint { + }; + }; + + port@3 { + reg = <3>; + max9286_in3: endpoint { + }; + }; + + port@4 { + reg = <4>; + max9286_out0: endpoint { + clock-lanes = <0>; + data-lanes = <1 2 3 4>; + remote-endpoint = <&csi40_in>; + }; + }; + }; + + i2c-mux { + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + status = "disabled"; + }; + + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + status = "disabled"; + }; + + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + status = "disabled"; + }; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + status = "disabled"; + }; + }; + }; +}; + &scif0 { pinctrl-0 = <&scif0_pins>; pinctrl-names = "default"; From patchwork Mon Dec 16 10:29:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293733 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E9C8E13B6 for ; Mon, 16 Dec 2019 10:29:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C864C207FF for ; Mon, 16 Dec 2019 10:29:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="HE25dDeg" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727334AbfLPK3l (ORCPT ); Mon, 16 Dec 2019 05:29:41 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40692 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727070AbfLPK3l (ORCPT ); Mon, 16 Dec 2019 05:29:41 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 350221337; Mon, 16 Dec 2019 11:29:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492175; bh=AwMIOcVPhFepZBzd6Cs+5I+A4VMcBFPGk6l5fjeiHvo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=HE25dDegrSi4641MKH6obzYKWAVELQ59k83zSt40yYs3NNv6qRndFwy8CAs5l08ow UaFESj2WoA0kQDERdPHnbE4lCQzCtFQMjrcxJI3ramKpWaA3GOOFsy7/3iUTNjYngk S13OyTE39lW3MTLGT37HBcf2syP3aorW/pklIK+I= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 06/13] arm64: dts: renesas: eagle: Provide Eagle FAKRA dynamic overlay Date: Mon, 16 Dec 2019 10:29:23 +0000 Message-Id: <20191216102930.5867-7-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org From: Kieran Bingham This overlay currently supports either the RDACM20, or RDACM21 cameras and can be included directly at the end of the Eagle-V3M dtb. Ideally this would be an externally provided (and loaded) device tree overlay (dto). Signed-off-by: Kieran Bingham --- v2: - Fix up SPDX header v6: - Use new i2c-mux subnodes - Remove incorrect enable-gpio line --- arch/arm64/boot/dts/renesas/eagle-fakra.dtsi | 128 +++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 arch/arm64/boot/dts/renesas/eagle-fakra.dtsi diff --git a/arch/arm64/boot/dts/renesas/eagle-fakra.dtsi b/arch/arm64/boot/dts/renesas/eagle-fakra.dtsi new file mode 100644 index 000000000000..95acc535e230 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/eagle-fakra.dtsi @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Device Tree Source (overlay) for the Eagle V3M FAKRA connectors + * + * Copyright (C) 2017 Ideas on Board + * + * This overlay allows you to define cameras connected to the FAKRA connectors + * on the Eagle-V3M (or compatible) board. + * + * Enable the cameras by specifying the camera compatible on the appropriate + * line. Comment out the defines to disconnect the camera from the DTB. + * + * The following cameras are currently supported: + * "imi,rdacm20" + * "imi,rdacm21" + */ + +#include + +#define EAGLE_CAMERA0 "imi,rdacm20" +#define EAGLE_CAMERA1 "imi,rdacm20" +#define EAGLE_CAMERA2 "imi,rdacm20" +#define EAGLE_CAMERA3 "imi,rdacm20" + +/* Define the endpoint links */ +#ifdef EAGLE_CAMERA0 +&max9286_in0 { + remote-endpoint = <&fakra_con0>; +}; +#endif + +#ifdef EAGLE_CAMERA1 +&max9286_in1 { + remote-endpoint = <&fakra_con1>; +}; +#endif + +#ifdef EAGLE_CAMERA2 +&max9286_in2 { + remote-endpoint = <&fakra_con2>; +}; +#endif + +#ifdef EAGLE_CAMERA3 +&max9286_in3 { + remote-endpoint = <&fakra_con3>; +}; +#endif + +/* Cameras are 'attached' to the GMSL I2C busses */ +&gmsl { + +#if defined(EAGLE_CAMERA0) || defined(EAGLE_CAMERA1) || \ + defined(EAGLE_CAMERA2) || defined(EAGLE_CAMERA3) + status = "okay"; + +#endif + + i2c-mux { +#ifdef EAGLE_CAMERA0 + i2c@0 { + status = "okay"; + + camera@51 { + compatible = EAGLE_CAMERA0; + reg = <0x51 0x61>; + + port { + fakra_con0: endpoint { + remote-endpoint = <&max9286_in0>; + }; + }; + }; + }; +#endif + +#ifdef EAGLE_CAMERA1 + i2c@1 { + status = "okay"; + + camera@52 { + compatible = EAGLE_CAMERA1; + reg = <0x52 0x62>; + + port { + fakra_con1: endpoint { + remote-endpoint = <&max9286_in1>; + }; + }; + }; + }; +#endif + +#ifdef EAGLE_CAMERA2 + i2c@2 { + status = "okay"; + + camera@53 { + compatible = EAGLE_CAMERA2; + reg = <0x53 0x63>; + + port { + fakra_con2: endpoint { + remote-endpoint = <&max9286_in2>; + }; + }; + }; + }; +#endif + +#ifdef EAGLE_CAMERA3 + i2c@3 { + status = "okay"; + + camera@54 { + compatible = EAGLE_CAMERA3; + reg = <0x54 0x64>; + + port { + fakra_con3: endpoint { + remote-endpoint = <&max9286_in3>; + }; + }; + }; + }; +#endif + }; +}; From patchwork Mon Dec 16 10:29:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293739 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E8B1713B6 for ; Mon, 16 Dec 2019 10:29:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BC1E62072D for ; Mon, 16 Dec 2019 10:29:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="I3/BgKvb" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727513AbfLPK3n (ORCPT ); Mon, 16 Dec 2019 05:29:43 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40704 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727476AbfLPK3n (ORCPT ); Mon, 16 Dec 2019 05:29:43 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7D83EA34; Mon, 16 Dec 2019 11:29:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492175; bh=Ren/XIru5Y5hQ2L1tNYvyr2r6P0B7j38rkD7G9d9XSI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=I3/BgKvbXs+h4RRDSqEcguyKYhHPinn9cwWtKTwRbyyQ28644RYXXWV6xUug34pQA 5ez8if5RmfU9DWWHDDeno0T8KAQe5au+gBMi5oGprvR1QUKYLWQMZzexhtXzca9lw7 O921j7P9uP/82Wzx1czgTEYaX35paZklTLLk/Zmw= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 07/13] arm64: dts: renesas: salvator-x: Add MAX9286 expansion board Date: Mon, 16 Dec 2019 10:29:24 +0000 Message-Id: <20191216102930.5867-8-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org From: Laurent Pinchart Add a .dtsi fragment to describe the MAX9286-based expansion board for the Renesas Salvator-X board. The MAX9286 expansion board has eight RDACM20 cameras connected to it. They can be individually controlled by enabling or disabling the macro defines. Signed-off-by: Laurent Pinchart Signed-off-by: Kieran Bingham --- v2: - Use SPDX headers - Remove link from ADV748x TXA (HDMI) - Use 0x31-0x38, and 0x41-0x48 for the 8 cameras. 0x30 and 0x40 are the base addresses for the OV10635 and MAX9271 (0x50 for the MCU) - Provide RDACM20 MCU I2C address reservations. (0x51-0x58) v3: - Fix gmsl-serializer@ i2c node addressing v6: - Make i2c-mux child node and update to be conformant to new bindings. --- .../boot/dts/renesas/salvator-x-max9286.dtsi | 394 ++++++++++++++++++ 1 file changed, 394 insertions(+) create mode 100644 arch/arm64/boot/dts/renesas/salvator-x-max9286.dtsi diff --git a/arch/arm64/boot/dts/renesas/salvator-x-max9286.dtsi b/arch/arm64/boot/dts/renesas/salvator-x-max9286.dtsi new file mode 100644 index 000000000000..19697f5a3c85 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/salvator-x-max9286.dtsi @@ -0,0 +1,394 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Device Tree Source for the Salvator-X MAX9286 expansion board + * + * Copyright (C) 2017 Ideas on Board + */ + +#include + +/* + * MAX9286 A + */ +#define MAXIM_CAMERA0 "imi,rdacm20" +#define MAXIM_CAMERA1 "imi,rdacm20" +#define MAXIM_CAMERA2 "imi,rdacm20" +#define MAXIM_CAMERA3 "imi,rdacm20" + +/* + * MAX9286 B + */ +#define MAXIM_CAMERA4 "imi,rdacm20" +#define MAXIM_CAMERA5 "imi,rdacm20" +#define MAXIM_CAMERA6 "imi,rdacm20" +#define MAXIM_CAMERA7 "imi,rdacm20" + +/ { +/* + * Powered MCU IMI cameras need delay between power-on and R-Car access + * to avoid I2C bus conflicts since the R-Car I2C does not support I2C + * multi-master. The I2C bus conflict would result in R-Car I2C IP stall. + */ +#define IMI_MCU_V0_DELAY 8000000 /* delay for powered MCU firmware v0 */ +#define IMI_MCU_V1_DELAY 3000000 /* delay for powered MCU firmware v1 */ +#define IMI_MCU_NO_DELAY 0 /* delay for unpowered MCU */ +#define IMI_MCU_DELAY IMI_MCU_V0_DELAY + + poc_12v: regulator-vcc-poc-12v { + compatible = "regulator-fixed"; + + regulator-name = "Camera PoC 12V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + startup-delay-us = <(250000 + IMI_MCU_DELAY)>; + + gpio = <&gpio6 30 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&vin0 { + status = "okay"; +}; + +&vin1 { + status = "okay"; +}; + +&vin2 { + status = "okay"; +}; + +&vin3 { + status = "okay"; +}; + +&vin4 { + status = "okay"; +}; + +&vin5 { + status = "okay"; +}; + +&vin6 { + status = "okay"; +}; + +&vin7 { + status = "okay"; +}; + +/* Disconnect the csi40 endpoint from the ADV748x TXA (HDMI) */ +&adv7482_txa { + /delete-property/ remote-endpoint; + status = "disabled"; +}; + +&csi40 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + csi40_in: endpoint { + clock-lanes = <0>; + data-lanes = <1 2 3 4>; + remote-endpoint = <&max9286_out0>; + }; + }; + }; +}; + +&csi41 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + csi41_in: endpoint { + clock-lanes = <0>; + data-lanes = <1 2 3 4>; + remote-endpoint = <&max9286_out1>; + }; + }; + }; +}; + +&i2c4 { + gmsl-deserializer@4c { + compatible = "maxim,max9286"; + reg = <0x4c>; + poc-supply = <&poc_12v>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + max9286_in0: endpoint { +#ifdef MAXIM_CAMERA0 + remote-endpoint = <&rdacm20_out0>; +#endif + }; + }; + + port@1 { + reg = <1>; + max9286_in1: endpoint { +#ifdef MAXIM_CAMERA1 + remote-endpoint = <&rdacm20_out1>; +#endif + }; + }; + + port@2 { + reg = <2>; + max9286_in2: endpoint { +#ifdef MAXIM_CAMERA2 + remote-endpoint = <&rdacm20_out2>; +#endif + }; + }; + + port@3 { + reg = <3>; + max9286_in3: endpoint { +#ifdef MAXIM_CAMERA3 + remote-endpoint = <&rdacm20_out3>; +#endif + }; + }; + + port@4 { + reg = <4>; + max9286_out0: endpoint { + clock-lanes = <0>; + data-lanes = <1 2 3 4>; + remote-endpoint = <&csi40_in>; + }; + }; + }; + + i2c-mux { + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + +#ifdef MAXIM_CAMERA0 + camera@31 { + compatible = MAXIM_CAMERA0; + reg = <0x31 0x41 0x51>; + + port { + rdacm20_out0: endpoint { + remote-endpoint = <&max9286_in0>; + }; + }; + + }; +#endif + }; + + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + +#ifdef MAXIM_CAMERA1 + camera@32 { + compatible = MAXIM_CAMERA1; + reg = <0x32 0x42 0x52>; + port { + rdacm20_out1: endpoint { + remote-endpoint = <&max9286_in1>; + }; + }; + }; +#endif + }; + + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + +#ifdef MAXIM_CAMERA2 + camera@33 { + compatible = MAXIM_CAMERA2; + reg = <0x33 0x43 0x53>; + port { + rdacm20_out2: endpoint { + remote-endpoint = <&max9286_in2>; + }; + }; + }; +#endif + }; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + +#ifdef MAXIM_CAMERA3 + camera@34 { + compatible = MAXIM_CAMERA3; + reg = <0x34 0x44 0x54>; + port { + rdacm20_out3: endpoint { + remote-endpoint = <&max9286_in3>; + }; + }; + }; +#endif + }; + }; + }; + + gmsl-deserializer@6c { + compatible = "maxim,max9286"; + reg = <0x6c>; + poc-supply = <&poc_12v>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + max9286_in4: endpoint { +#ifdef MAXIM_CAMERA4 + remote-endpoint = <&rdacm20_out4>; +#endif + }; + }; + + port@1 { + reg = <1>; + max9286_in5: endpoint { +#ifdef MAXIM_CAMERA5 + remote-endpoint = <&rdacm20_out5>; +#endif + }; + }; + + port@2 { + reg = <2>; + max9286_in6: endpoint { +#ifdef MAXIM_CAMERA6 + remote-endpoint = <&rdacm20_out6>; +#endif + }; + }; + + port@3 { + reg = <3>; + max9286_in7: endpoint { +#ifdef MAXIM_CAMERA7 + remote-endpoint = <&rdacm20_out7>; +#endif + }; + }; + + port@4 { + reg = <4>; + max9286_out1: endpoint { + clock-lanes = <0>; + data-lanes = <1 2 3 4>; + remote-endpoint = <&csi41_in>; + }; + }; + }; + + i2c-mux { + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + +#ifdef MAXIM_CAMERA4 + camera@35 { + compatible = MAXIM_CAMERA4; + reg = <0x35 0x45 0x55>; + port { + rdacm20_out4: endpoint { + remote-endpoint = <&max9286_in4>; + }; + }; + }; +#endif + }; + + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + +#ifdef MAXIM_CAMERA5 + camera@36 { + compatible = MAXIM_CAMERA5; + reg = <0x36 0x46 0x56>; + port { + rdacm20_out5: endpoint { + remote-endpoint = <&max9286_in5>; + }; + }; + }; +#endif + }; + + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + +#ifdef MAXIM_CAMERA6 + camera@37 { + compatible = MAXIM_CAMERA6; + reg = <0x37 0x47 0x57>; + port { + rdacm20_out6: endpoint { + remote-endpoint = <&max9286_in6>; + }; + }; + }; +#endif + }; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + +#ifdef MAXIM_CAMERA7 + camera@38 { + compatible = MAXIM_CAMERA7; + reg = <0x38 0x48 0x58>; + port { + rdacm20_out7: endpoint { + remote-endpoint = <&max9286_in7>; + }; + }; + }; +#endif + }; + }; + }; +}; From patchwork Mon Dec 16 10:29:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293735 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 94C95138C for ; Mon, 16 Dec 2019 10:29:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 728742072D for ; Mon, 16 Dec 2019 10:29:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="W/mh/YhD" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727480AbfLPK3m (ORCPT ); Mon, 16 Dec 2019 05:29:42 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40692 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727070AbfLPK3m (ORCPT ); Mon, 16 Dec 2019 05:29:42 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C5C5013C5; Mon, 16 Dec 2019 11:29:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492176; bh=rM/j77zhSu88EFwvOBiyxCtGkc5hP29MGQS+20BGe+o=; h=From:To:Subject:Date:In-Reply-To:References:From; b=W/mh/YhD0bX4eI6QbCTbAxbdDYoE1Xp5lHNYBV3raGYt6A2XCL93ovfl9g88k1UuB kWNScQ0NWyIPSzBBy70mkOhLdV4AHAGWyJd7zox1WFAzlZ/6pSFs0gCkydwvhaQzvC sPSbjPWsuxKTv+S3eoJbDghvhjBehkkDhoWjRd5Y= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 08/13] arm64: dts: renesas: eagle: Include Eagle FAKRA overlay Date: Mon, 16 Dec 2019 10:29:25 +0000 Message-Id: <20191216102930.5867-9-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org From: Kieran Bingham Apply the eagle-fakra overlay to enable GMSL camera support on the Eagle-V3M platform. Signed-off-by: Kieran Bingham --- arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts index 86caf98e9eb0..deab881eb2d9 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts +++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts @@ -357,3 +357,6 @@ &vin3 { status = "okay"; }; + +/* FAKRA Overlay */ +#include "eagle-fakra.dtsi" From patchwork Mon Dec 16 10:29:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293737 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5D084138C for ; Mon, 16 Dec 2019 10:29:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3AD762072D for ; Mon, 16 Dec 2019 10:29:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="pKln3/96" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727512AbfLPK3n (ORCPT ); Mon, 16 Dec 2019 05:29:43 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40692 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727070AbfLPK3m (ORCPT ); Mon, 16 Dec 2019 05:29:42 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 245051446; Mon, 16 Dec 2019 11:29:36 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492176; bh=PqCIRiuoRxfir1JLxW5cg/mfITNtQQ6T2YBYYiR7P/Q=; h=From:To:Subject:Date:In-Reply-To:References:From; b=pKln3/96+ZqHuBbXmbfTA+NgnHVfotTpTLheRoWyv/NhjQHDSOZtSFowVDAH/I9wb ahglm85r+MRtepxpCeDi0YgJ1oR0QiW4lP9eva8y3VZhZWKjYdigEMcC4yJLx+O0m8 QPCnJnlgGgVObe6/yutitUQDTktpd74WI+bQg9Q4= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 09/13] arm64: dts: renesas: r8a7795-es1-salvator-x: Include MAX9286 8 Camera expansion board Date: Mon, 16 Dec 2019 10:29:26 +0000 Message-Id: <20191216102930.5867-10-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Include the overlay for the dual MAX9286 expansion board, providing 8 FAKRA camera connectors. Signed-off-by: Kieran Bingham --- arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts index c72968623e94..a845a988cb06 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts @@ -155,3 +155,6 @@ status = "okay"; }; + +/* Include the max9286 expansion board "overlay" */ +#include "salvator-x-max9286.dtsi" From patchwork Mon Dec 16 10:29:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293743 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D633413B6 for ; Mon, 16 Dec 2019 10:29:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B30992072D for ; Mon, 16 Dec 2019 10:29:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="LPuz/jGy" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727514AbfLPK3p (ORCPT ); Mon, 16 Dec 2019 05:29:45 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40692 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727070AbfLPK3p (ORCPT ); Mon, 16 Dec 2019 05:29:45 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7D84CB18; Mon, 16 Dec 2019 11:29:36 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492176; bh=4RpJ3bE4pj4Pu0tFqVNEkjDIl1PHOcfrVMJv8bj2eKs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=LPuz/jGyB8bJf7gGEb5dcIkwojUN9Ayvdm/inrHtl4enzcp0zpKr0lcpVn8PMshve ULUoy3VT71MVmFLADGBOYafGZZbOpvBksfi0pCPlylqN6IzX5MMSyxRh+4dd+9EGuV c0xn38u3rHduwG4YoUGLZKXvxnYRDZluvi7CvVWY= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 10/13] media: i2c: max9286: Introduce a debugfs layer Date: Mon, 16 Dec 2019 10:29:27 +0000 Message-Id: <20191216102930.5867-11-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org The MAX9286 provides several read-only status registers for observing the system state of the device. Provide error statistics and link status through debugfs files. These files will be free-form and should not be considered as part of any userspace API Signed-off-by: Kieran Bingham --- Please consider this a starting point for adding useful debug. I don't necessarily expect this code to make it to the final driver, but it could be very useful to process and expose this information internally in the driver. Alternatively - we could move this all to max9286_debugfs.c or such. Watch out for a lot of the error counters which reset to 0 when read. We should handle those by adding the value to a local store on every read. v2: - Cleanup debugfs in error path of probe() v6: - Fix a bogus (h << 0) check --- drivers/media/i2c/max9286.c | 127 ++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index df77871e603c..6e1dfc518e03 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -10,6 +10,7 @@ * Copyright (C) 2015 Cogent Embedded, Inc. */ +#include #include #include #include @@ -148,6 +149,7 @@ struct max9286_priv { struct v4l2_subdev sd; struct media_pad pads[MAX9286_N_PADS]; struct regulator *regulator; + struct dentry *dbgroot; bool poc_enabled; struct gpio_chip gpio; @@ -225,6 +227,124 @@ static int max9286_write(struct max9286_priv *priv, u8 reg, u8 val) return ret; } +/* ----------------------------------------------------------------------------- + * DebugFS + */ + +#define DEBUGFS_RO_ATTR(name) \ +static int name##_open(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, name, inode->i_private); \ +} \ +static const struct file_operations name##_fops = { \ + .owner = THIS_MODULE, \ + .open = name##_open, \ + .llseek = seq_lseek, \ + .read = seq_read, \ + .release = single_release, \ +} + +static int max9286_config_video_detect(struct max9286_priv *priv, + struct seq_file *s) +{ + int reg_49 = max9286_read(priv, 0x49); + unsigned int i; + + if (reg_49 < 0) + return reg_49; + + seq_puts(s, " : 0 1 2 3\n"); + seq_puts(s, "Configuration Link:"); + for (i = 0; i < 4; i++) { + int link = (reg_49 & BIT(i + 4)); + + seq_printf(s, " %3s", link ? " O " : "xxx"); + } + seq_puts(s, "\n"); + + seq_puts(s, "Video Link :"); + for (i = 0; i < 4; i++) { + int link = (reg_49 & BIT(i)); + + seq_printf(s, " %3s", link ? " O " : "xxx"); + } + seq_puts(s, "\n"); + + return 0; +} + +static int max9286_vs_period(struct max9286_priv *priv, struct seq_file *s) +{ + int l, m, h; + unsigned int frame_length; + + l = max9286_read(priv, 0x5b); + m = max9286_read(priv, 0x5c); + h = max9286_read(priv, 0x5d); + + if (l < 0 || m < 0 || h < 0) + return -ENODEV; + + frame_length = (h << 16) + (m << 8) + l; + + seq_printf(s, "Calculated VS Period (pxclk) : %u\n", frame_length); + + return 0; +} + +static int max9286_master_link(struct max9286_priv *priv, struct seq_file *s) +{ + int reg_71 = max9286_read(priv, 0x71); + unsigned int link = (reg_71 >> 4) & 0x03; + + if (reg_71 < 0) + return reg_71; + + seq_printf(s, "Master link selected : %u\n", link); + + return 0; +} + +static int max9286_debugfs_info(struct seq_file *s, void *p) +{ + struct max9286_priv *priv = s->private; + + max9286_config_video_detect(priv, s); + max9286_vs_period(priv, s); + max9286_master_link(priv, s); + + return 0; +} + +DEBUGFS_RO_ATTR(max9286_debugfs_info); + +static int max9286_debugfs_init(struct max9286_priv *priv) +{ + char name[32]; + + snprintf(name, sizeof(name), "max9286-%s", + dev_name(&priv->client->dev)); + + priv->dbgroot = debugfs_create_dir(name, NULL); + if (!priv->dbgroot) + return -ENOMEM; + + /* + * dentry pointers are discarded, and remove_recursive is used to + * cleanup the tree. DEBUGFS_RO_ATTR defines the file operations with + * the _fops extension to the function name. + */ + debugfs_create_file("info", 0444, priv->dbgroot, priv, + &max9286_debugfs_info_fops); + + return 0; +} + +static void max9286_debugfs_remove(struct max9286_priv *priv) +{ + debugfs_remove_recursive(priv->dbgroot); +} + /* ----------------------------------------------------------------------------- * I2C Multiplexer */ @@ -1094,6 +1214,9 @@ static int max9286_probe(struct i2c_client *client) */ max9286_configure_i2c(priv, false); + /* Add any userspace support before we return early. */ + max9286_debugfs_init(priv); + ret = max9286_init(&client->dev); if (ret < 0) goto err_regulator; @@ -1104,6 +1227,7 @@ static int max9286_probe(struct i2c_client *client) regulator_put(priv->regulator); max9286_i2c_mux_close(priv); max9286_configure_i2c(priv, false); + max9286_debugfs_remove(priv); err_free: max9286_cleanup_dt(priv); kfree(priv); @@ -1115,6 +1239,9 @@ static int max9286_remove(struct i2c_client *client) { struct max9286_priv *priv = i2c_get_clientdata(client); + /* Remove all Debugfs / sysfs entries */ + max9286_debugfs_remove(priv); + i2c_mux_del_adapters(priv->mux); fwnode_handle_put(priv->sd.fwnode); From patchwork Mon Dec 16 10:29:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293741 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3E533138C for ; Mon, 16 Dec 2019 10:29:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1C1B12072D for ; Mon, 16 Dec 2019 10:29:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Prs9UIgm" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727395AbfLPK3o (ORCPT ); Mon, 16 Dec 2019 05:29:44 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40704 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727476AbfLPK3o (ORCPT ); Mon, 16 Dec 2019 05:29:44 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C8B5EB1A; Mon, 16 Dec 2019 11:29:36 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492176; bh=iVKHkanYUVKEN78LNrq66HLl46bCSrAtpvh3rdpeH8U=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Prs9UIgm0diNFH6oyy2ZCsvR82kgEAKFC8UfvoZM4UWqYvLExgASyUeRa5lqpW5D/ m563TM0BYPwHk5RrQx1zlFD9mNQ9ROb+YJa3mhyn4HiiN3pX4BNdBAqtNTcgX6nZem fy1vrPL6zoZL4IMz8XsaqI3473MpTqiAyidxl8Os= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 11/13] [DNI:DEBUG] media: i2c: max9286: Add max9286_check_config_link() Date: Mon, 16 Dec 2019 10:29:28 +0000 Message-Id: <20191216102930.5867-12-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org From: Kieran Bingham Add extra debug status output. Signed-off-by: Kieran Bingham --- drivers/media/i2c/max9286.c | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index 6e1dfc518e03..057258a3c645 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -502,6 +502,51 @@ static const struct v4l2_async_notifier_operations max9286_notify_ops = { .unbind = max9286_notify_unbind, }; +/* + * max9286_check_config_link() - Detect and wait for configuration links + * + * Determine if the configuration channel is up and settled for a link. + * + * Returns 0 for success, -EIO for errors. + */ +static int max9286_check_config_link(struct max9286_priv *priv, + unsigned int source_mask) +{ + unsigned int i; + int ret; + const unsigned int max_loops = 1000; + + source_mask &= 0xf; + source_mask <<= 4; + + /* + * Make sure requested configuration links are detected. + */ + for (i = 0; i < max_loops; i++) { + ret = max9286_read(priv, 0x49); + if (ret < 0) + return -EIO; + + if ((ret & source_mask) == source_mask) + break; + + usleep_range(350, 500); + } + + if (i == max_loops) { + dev_err(&priv->client->dev, + "Unable to detect configuration links: 0x%02x expected 0x%02x\n", + ret, source_mask); + return -EIO; + } + + dev_err(&priv->client->dev, + "Successfully detected configuration links after %u loops: 0x%02x\n", + i, ret); + + return 0; +} + /* * max9286_check_video_links() - Make sure video links are detected and locked * @@ -831,6 +876,11 @@ static int max9286_setup(struct max9286_priv *priv) */ usleep_range(2000, 5000); + /* + * Check to see if the expected configuration links are up. + */ + max9286_check_config_link(priv, priv->source_mask); + return 0; } From patchwork Mon Dec 16 10:29:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293745 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 310B2138C for ; Mon, 16 Dec 2019 10:29:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0EC4B2072D for ; Mon, 16 Dec 2019 10:29:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="AcrfBZFP" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727516AbfLPK3p (ORCPT ); Mon, 16 Dec 2019 05:29:45 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40704 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727476AbfLPK3p (ORCPT ); Mon, 16 Dec 2019 05:29:45 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1C76F13CB; Mon, 16 Dec 2019 11:29:37 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492177; bh=+t6mDqnzHaaK1agWF9IfwPifCVytBgh+BqoIKAH1MAU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=AcrfBZFPjEFilOM4kcYqKZGPTaXvb6BPGEH0kBMQ/0NNFipLXUigG3MnMYN4CZfbH ZXuhkqL/rBFzh68np7nZ1yzROHZcKgeYjuzJS1vDGJcl184DrWlmg2slDboeLprh8G FC458AXDPZFSHIySyvh65OgecgxEQawO5WVs0rRQ= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 12/13] media: i2c: max9286: [Workaround] Hard delay while waiting to enable the V3M cameras Date: Mon, 16 Dec 2019 10:29:29 +0000 Message-Id: <20191216102930.5867-13-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org From: Kieran Bingham The camera's power regulator is connected to a GPIO on the max9286. Unfortunately this causes us a circular dependency on the regulator needing the gpio_chip before the max9286 has probed. Until we can get the regulator framework to create the regulator device on demand (at the time of regulator_get(), the gpio_chip is available) we need to force the gpio line with a gpio-hog, and handle the delay required with a manual sleep. This is specific to the Eagle-V3M. Signed-off-by: Kieran Bingham --- drivers/media/i2c/max9286.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index 057258a3c645..090b6c0f81e9 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -964,6 +964,20 @@ static int max9286_init(struct device *dev) return ret; } + /* + * Regulator Workaround: + * + * We must sleep at least 8 seconds to let the cameras power and + * complete their bootstrapping process. This should be handled by the + * call to regulator_enable, but alas on V3M we end up in a circular + * dependency due to the regulator being connected to our own gpio_chip + * + * This sleep is a temporary work-around and should be removed, which + * ensures enough time has passed from the gpio_chip enabling a + * gpio-hog before we enable any reverse channels within max9286_setup. + */ + usleep_range(8000000, 9000000); + priv->poc_enabled = true; ret = max9286_setup(priv); From patchwork Mon Dec 16 10:29:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11293747 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 52015138C for ; Mon, 16 Dec 2019 10:29:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 309C32072D for ; Mon, 16 Dec 2019 10:29:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="L3Q4S1N3" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727452AbfLPK3q (ORCPT ); Mon, 16 Dec 2019 05:29:46 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:40692 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727070AbfLPK3q (ORCPT ); Mon, 16 Dec 2019 05:29:46 -0500 Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 65722144B; Mon, 16 Dec 2019 11:29:37 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1576492177; bh=uCh1T2Yfv/ZM/HR/y4pLSjxonu+4j+vpiwmLYsdw3k8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=L3Q4S1N3tqsoZeNiLcpFZfiAMF0wdxY9Kdh56fizijPmo/6irw5H6SWgpqsznMhse moAyTixS18wTnDRp/CXQkSoFpY980Qz/H3hnZOuoTrfHf6GeKXmV9EVp6hsSCzs8f+ VlKISx10WNW1zbKI72d6RP9ram6yg2tsGRjLIZUs= From: Kieran Bingham To: Jacopo Mondi , linux-renesas-soc@vger.kernel.org Subject: [RFC PATCH v6 13/13] media: i2c: max9286: [Workaround] 'device is bound' Date: Mon, 16 Dec 2019 10:29:30 +0000 Message-Id: <20191216102930.5867-14-kieran.bingham+renesas@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> References: <20191211124459.20508-1-kieran.bingham+renesas@ideasonboard.com> <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com> MIME-Version: 1.0 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org From: Kieran Bingham This introduces a local workaround to support multiple MAX9286 devices on the same I2C bus. Not for upstream consumption due to device_is_bound being an in kernel symbol, and requires the module to be a built-in only. Not-signed-off-by: Kieran Bingham --- drivers/media/i2c/max9286.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index 090b6c0f81e9..07d4489183f4 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -942,7 +942,7 @@ static int max9286_gpio(struct max9286_priv *priv) return ret; } -static int max9286_init(struct device *dev) +static int max9286_init(struct device *dev, void *data) { struct max9286_priv *priv; struct i2c_client *client; @@ -1056,6 +1056,25 @@ static int max9286_init(struct device *dev) return ret; } +static int max9286_is_bound(struct device *dev, void *data) +{ + struct device *this = data; + int ret; + + if (dev == this) + return 0; + + /* Skip non-max9286 devices. */ + if (!dev->of_node || !of_match_node(max9286_dt_ids, dev->of_node)) + return 0; + + ret = device_is_bound(dev); + if (!ret) + return -EPROBE_DEFER; + + return 0; +} + static void max9286_cleanup_dt(struct max9286_priv *priv) { struct max9286_source *source; @@ -1281,10 +1300,21 @@ static int max9286_probe(struct i2c_client *client) /* Add any userspace support before we return early. */ max9286_debugfs_init(priv); - ret = max9286_init(&client->dev); + ret = device_for_each_child(client->dev.parent, &client->dev, + max9286_is_bound); + if (ret) + return 0; + + dev_dbg(&client->dev, + "All max9286 probed: start initialization sequence\n"); + ret = device_for_each_child(client->dev.parent, NULL, + max9286_init); if (ret < 0) goto err_regulator; + /* Leave the mux channels disabled until they are selected. */ + max9286_i2c_mux_close(priv); + return 0; err_regulator: